Skip to content

Commit 546d714

Browse files
committed
KVM: introduce new vendor op for KVM_GET_DEVICE_ATTR
Allow vendor modules to provide their own attributes on /dev/kvm. To avoid proliferation of vendor ops, implement KVM_HAS_DEVICE_ATTR and KVM_GET_DEVICE_ATTR in terms of the same function. You're not supposed to use KVM_GET_DEVICE_ATTR to do complicated computations, especially on /dev/kvm. Reviewed-by: Michael Roth <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]> Reviewed-by: Isaku Yamahata <[email protected]> Message-ID: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 8d2aec3 commit 546d714

File tree

3 files changed

+26
-14
lines changed

3 files changed

+26
-14
lines changed

arch/x86/include/asm/kvm-x86-ops.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ KVM_X86_OP(enter_smm)
121121
KVM_X86_OP(leave_smm)
122122
KVM_X86_OP(enable_smi_window)
123123
#endif
124+
KVM_X86_OP_OPTIONAL(dev_get_attr)
124125
KVM_X86_OP_OPTIONAL(mem_enc_ioctl)
125126
KVM_X86_OP_OPTIONAL(mem_enc_register_region)
126127
KVM_X86_OP_OPTIONAL(mem_enc_unregister_region)

arch/x86/include/asm/kvm_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1778,6 +1778,7 @@ struct kvm_x86_ops {
17781778
void (*enable_smi_window)(struct kvm_vcpu *vcpu);
17791779
#endif
17801780

1781+
int (*dev_get_attr)(u32 group, u64 attr, u64 *val);
17811782
int (*mem_enc_ioctl)(struct kvm *kvm, void __user *argp);
17821783
int (*mem_enc_register_region)(struct kvm *kvm, struct kvm_enc_region *argp);
17831784
int (*mem_enc_unregister_region)(struct kvm *kvm, struct kvm_enc_region *argp);

arch/x86/kvm/x86.c

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4842,34 +4842,44 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
48424842
return r;
48434843
}
48444844

4845-
static int kvm_x86_dev_get_attr(struct kvm_device_attr *attr)
4845+
static int __kvm_x86_dev_get_attr(struct kvm_device_attr *attr, u64 *val)
48464846
{
4847-
u64 __user *uaddr = u64_to_user_ptr(attr->addr);
4848-
4849-
if (attr->group)
4847+
if (attr->group) {
4848+
if (kvm_x86_ops.dev_get_attr)
4849+
return static_call(kvm_x86_dev_get_attr)(attr->group, attr->attr, val);
48504850
return -ENXIO;
4851+
}
48514852

48524853
switch (attr->attr) {
48534854
case KVM_X86_XCOMP_GUEST_SUPP:
4854-
if (put_user(kvm_caps.supported_xcr0, uaddr))
4855-
return -EFAULT;
4855+
*val = kvm_caps.supported_xcr0;
48564856
return 0;
48574857
default:
48584858
return -ENXIO;
48594859
}
48604860
}
48614861

4862+
static int kvm_x86_dev_get_attr(struct kvm_device_attr *attr)
4863+
{
4864+
u64 __user *uaddr = u64_to_user_ptr(attr->addr);
4865+
int r;
4866+
u64 val;
4867+
4868+
r = __kvm_x86_dev_get_attr(attr, &val);
4869+
if (r < 0)
4870+
return r;
4871+
4872+
if (put_user(val, uaddr))
4873+
return -EFAULT;
4874+
4875+
return 0;
4876+
}
4877+
48624878
static int kvm_x86_dev_has_attr(struct kvm_device_attr *attr)
48634879
{
4864-
if (attr->group)
4865-
return -ENXIO;
4880+
u64 val;
48664881

4867-
switch (attr->attr) {
4868-
case KVM_X86_XCOMP_GUEST_SUPP:
4869-
return 0;
4870-
default:
4871-
return -ENXIO;
4872-
}
4882+
return __kvm_x86_dev_get_attr(attr, &val);
48734883
}
48744884

48754885
long kvm_arch_dev_ioctl(struct file *filp,

0 commit comments

Comments
 (0)