diff options
author | Shannon Zhao <shannon.zhao@linaro.org> | 2016-01-11 13:56:17 +0100 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2016-02-29 19:34:21 +0100 |
commit | f577f6c2a6a5ccabe98061f256a1e2ff468d5e93 (patch) | |
tree | 278bd52115efb03e8d23ab4f80969a9bd1d6dab3 | |
parent | arm64: KVM: Add a new feature bit for PMUv3 (diff) | |
download | linux-f577f6c2a6a5ccabe98061f256a1e2ff468d5e93.tar.xz linux-f577f6c2a6a5ccabe98061f256a1e2ff468d5e93.zip |
arm64: KVM: Introduce per-vcpu kvm device controls
In some cases it needs to get/set attributes specific to a vcpu and so
needs something else than ONE_REG.
Let's copy the KVM_DEVICE approach, and define the respective ioctls
for the vcpu file descriptor.
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Acked-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
-rw-r--r-- | Documentation/virtual/kvm/api.txt | 10 | ||||
-rw-r--r-- | Documentation/virtual/kvm/devices/vcpu.txt | 8 | ||||
-rw-r--r-- | arch/arm/kvm/arm.c | 55 | ||||
-rw-r--r-- | arch/arm64/kvm/reset.c | 1 | ||||
-rw-r--r-- | include/uapi/linux/kvm.h | 1 |
5 files changed, 71 insertions, 4 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 9684f8dc6bb2..cb2ef0bcdcb5 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -2507,8 +2507,9 @@ struct kvm_create_device { 4.80 KVM_SET_DEVICE_ATTR/KVM_GET_DEVICE_ATTR -Capability: KVM_CAP_DEVICE_CTRL, KVM_CAP_VM_ATTRIBUTES for vm device -Type: device ioctl, vm ioctl +Capability: KVM_CAP_DEVICE_CTRL, KVM_CAP_VM_ATTRIBUTES for vm device, + KVM_CAP_VCPU_ATTRIBUTES for vcpu device +Type: device ioctl, vm ioctl, vcpu ioctl Parameters: struct kvm_device_attr Returns: 0 on success, -1 on error Errors: @@ -2533,8 +2534,9 @@ struct kvm_device_attr { 4.81 KVM_HAS_DEVICE_ATTR -Capability: KVM_CAP_DEVICE_CTRL, KVM_CAP_VM_ATTRIBUTES for vm device -Type: device ioctl, vm ioctl +Capability: KVM_CAP_DEVICE_CTRL, KVM_CAP_VM_ATTRIBUTES for vm device, + KVM_CAP_VCPU_ATTRIBUTES for vcpu device +Type: device ioctl, vm ioctl, vcpu ioctl Parameters: struct kvm_device_attr Returns: 0 on success, -1 on error Errors: diff --git a/Documentation/virtual/kvm/devices/vcpu.txt b/Documentation/virtual/kvm/devices/vcpu.txt new file mode 100644 index 000000000000..3cc59c5e44ce --- /dev/null +++ b/Documentation/virtual/kvm/devices/vcpu.txt @@ -0,0 +1,8 @@ +Generic vcpu interface +==================================== + +The virtual cpu "device" also accepts the ioctls KVM_SET_DEVICE_ATTR, +KVM_GET_DEVICE_ATTR, and KVM_HAS_DEVICE_ATTR. The interface uses the same struct +kvm_device_attr as other devices, but targets VCPU-wide settings and controls. + +The groups and attributes per virtual cpu, if any, are architecture specific. diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 9d133df2da53..166232356291 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -828,11 +828,51 @@ static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu, return 0; } +static int kvm_arm_vcpu_set_attr(struct kvm_vcpu *vcpu, + struct kvm_device_attr *attr) +{ + int ret = -ENXIO; + + switch (attr->group) { + default: + break; + } + + return ret; +} + +static int kvm_arm_vcpu_get_attr(struct kvm_vcpu *vcpu, + struct kvm_device_attr *attr) +{ + int ret = -ENXIO; + + switch (attr->group) { + default: + break; + } + + return ret; +} + +static int kvm_arm_vcpu_has_attr(struct kvm_vcpu *vcpu, + struct kvm_device_attr *attr) +{ + int ret = -ENXIO; + + switch (attr->group) { + default: + break; + } + + return ret; +} + long kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { struct kvm_vcpu *vcpu = filp->private_data; void __user *argp = (void __user *)arg; + struct kvm_device_attr attr; switch (ioctl) { case KVM_ARM_VCPU_INIT: { @@ -875,6 +915,21 @@ long kvm_arch_vcpu_ioctl(struct file *filp, return -E2BIG; return kvm_arm_copy_reg_indices(vcpu, user_list->reg); } + case KVM_SET_DEVICE_ATTR: { + if (copy_from_user(&attr, argp, sizeof(attr))) + return -EFAULT; + return kvm_arm_vcpu_set_attr(vcpu, &attr); + } + case KVM_GET_DEVICE_ATTR: { + if (copy_from_user(&attr, argp, sizeof(attr))) + return -EFAULT; + return kvm_arm_vcpu_get_attr(vcpu, &attr); + } + case KVM_HAS_DEVICE_ATTR: { + if (copy_from_user(&attr, argp, sizeof(attr))) + return -EFAULT; + return kvm_arm_vcpu_has_attr(vcpu, &attr); + } default: return -EINVAL; } diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c index cf4f28a7a514..9677bf069bcc 100644 --- a/arch/arm64/kvm/reset.c +++ b/arch/arm64/kvm/reset.c @@ -81,6 +81,7 @@ int kvm_arch_dev_ioctl_check_extension(long ext) r = kvm_arm_support_pmu_v3(); break; case KVM_CAP_SET_GUEST_DEBUG: + case KVM_CAP_VCPU_ATTRIBUTES: r = 1; break; default: diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index dc16d3084d4a..50f44a229212 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -851,6 +851,7 @@ struct kvm_ppc_smmu_info { #define KVM_CAP_HYPERV_SYNIC 123 #define KVM_CAP_S390_RI 124 #define KVM_CAP_ARM_PMU_V3 125 +#define KVM_CAP_VCPU_ATTRIBUTES 126 #ifdef KVM_CAP_IRQ_ROUTING |