aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBorislav Petkov <bp@suse.de>2013-09-22 10:44:50 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2013-10-30 13:54:39 -0400
commit9c15bb1d0a8411f9bb3395d21d5309bde7da0c1c (patch)
tree33f00dcd75d1ef4f97e037f1c97acb2365131de4
parent5bb3398dd2df2c26261b2156c98cf4c95b3f91fe (diff)
kvm: Add KVM_GET_EMULATED_CPUID
Add a kvm ioctl which states which system functionality kvm emulates. The format used is that of CPUID and we return the corresponding CPUID bits set for which we do emulate functionality. Make sure ->padding is being passed on clean from userspace so that we can use it for something in the future, after the ioctl gets cast in stone. s/kvm_dev_ioctl_get_supported_cpuid/kvm_dev_ioctl_get_cpuid/ while at it. Signed-off-by: Borislav Petkov <bp@suse.de> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--Documentation/virtual/kvm/api.txt77
-rw-r--r--arch/x86/include/uapi/asm/kvm.h6
-rw-r--r--arch/x86/kvm/cpuid.c57
-rw-r--r--arch/x86/kvm/cpuid.h5
-rw-r--r--arch/x86/kvm/x86.c9
-rw-r--r--include/uapi/linux/kvm.h2
6 files changed, 139 insertions, 17 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index a89a5ee0b940..488964414f04 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1122,9 +1122,9 @@ struct kvm_cpuid2 {
1122 struct kvm_cpuid_entry2 entries[0]; 1122 struct kvm_cpuid_entry2 entries[0];
1123}; 1123};
1124 1124
1125#define KVM_CPUID_FLAG_SIGNIFCANT_INDEX 1 1125#define KVM_CPUID_FLAG_SIGNIFCANT_INDEX BIT(0)
1126#define KVM_CPUID_FLAG_STATEFUL_FUNC 2 1126#define KVM_CPUID_FLAG_STATEFUL_FUNC BIT(1)
1127#define KVM_CPUID_FLAG_STATE_READ_NEXT 4 1127#define KVM_CPUID_FLAG_STATE_READ_NEXT BIT(2)
1128 1128
1129struct kvm_cpuid_entry2 { 1129struct kvm_cpuid_entry2 {
1130 __u32 function; 1130 __u32 function;
@@ -2684,6 +2684,77 @@ and usually define the validity of a groups of registers. (e.g. one bit
2684}; 2684};
2685 2685
2686 2686
26874.81 KVM_GET_EMULATED_CPUID
2688
2689Capability: KVM_CAP_EXT_EMUL_CPUID
2690Architectures: x86
2691Type: system ioctl
2692Parameters: struct kvm_cpuid2 (in/out)
2693Returns: 0 on success, -1 on error
2694
2695struct kvm_cpuid2 {
2696 __u32 nent;
2697 __u32 flags;
2698 struct kvm_cpuid_entry2 entries[0];
2699};
2700
2701The member 'flags' is used for passing flags from userspace.
2702
2703#define KVM_CPUID_FLAG_SIGNIFCANT_INDEX BIT(0)
2704#define KVM_CPUID_FLAG_STATEFUL_FUNC BIT(1)
2705#define KVM_CPUID_FLAG_STATE_READ_NEXT BIT(2)
2706
2707struct kvm_cpuid_entry2 {
2708 __u32 function;
2709 __u32 index;
2710 __u32 flags;
2711 __u32 eax;
2712 __u32 ebx;
2713 __u32 ecx;
2714 __u32 edx;
2715 __u32 padding[3];
2716};
2717
2718This ioctl returns x86 cpuid features which are emulated by
2719kvm.Userspace can use the information returned by this ioctl to query
2720which features are emulated by kvm instead of being present natively.
2721
2722Userspace invokes KVM_GET_EMULATED_CPUID by passing a kvm_cpuid2
2723structure with the 'nent' field indicating the number of entries in
2724the variable-size array 'entries'. If the number of entries is too low
2725to describe the cpu capabilities, an error (E2BIG) is returned. If the
2726number is too high, the 'nent' field is adjusted and an error (ENOMEM)
2727is returned. If the number is just right, the 'nent' field is adjusted
2728to the number of valid entries in the 'entries' array, which is then
2729filled.
2730
2731The entries returned are the set CPUID bits of the respective features
2732which kvm emulates, as returned by the CPUID instruction, with unknown
2733or unsupported feature bits cleared.
2734
2735Features like x2apic, for example, may not be present in the host cpu
2736but are exposed by kvm in KVM_GET_SUPPORTED_CPUID because they can be
2737emulated efficiently and thus not included here.
2738
2739The fields in each entry are defined as follows:
2740
2741 function: the eax value used to obtain the entry
2742 index: the ecx value used to obtain the entry (for entries that are
2743 affected by ecx)
2744 flags: an OR of zero or more of the following:
2745 KVM_CPUID_FLAG_SIGNIFCANT_INDEX:
2746 if the index field is valid
2747 KVM_CPUID_FLAG_STATEFUL_FUNC:
2748 if cpuid for this function returns different values for successive
2749 invocations; there will be several entries with the same function,
2750 all with this flag set
2751 KVM_CPUID_FLAG_STATE_READ_NEXT:
2752 for KVM_CPUID_FLAG_STATEFUL_FUNC entries, set if this entry is
2753 the first entry to be read by a cpu
2754 eax, ebx, ecx, edx: the values returned by the cpuid instruction for
2755 this function/index combination
2756
2757
26876. Capabilities that can be enabled 27586. Capabilities that can be enabled
2688----------------------------------- 2759-----------------------------------
2689 2760
diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h
index 5d9a3033b3d7..d3a87780c70b 100644
--- a/arch/x86/include/uapi/asm/kvm.h
+++ b/arch/x86/include/uapi/asm/kvm.h
@@ -211,9 +211,9 @@ struct kvm_cpuid_entry2 {
211 __u32 padding[3]; 211 __u32 padding[3];
212}; 212};
213 213
214#define KVM_CPUID_FLAG_SIGNIFCANT_INDEX 1 214#define KVM_CPUID_FLAG_SIGNIFCANT_INDEX BIT(0)
215#define KVM_CPUID_FLAG_STATEFUL_FUNC 2 215#define KVM_CPUID_FLAG_STATEFUL_FUNC BIT(1)
216#define KVM_CPUID_FLAG_STATE_READ_NEXT 4 216#define KVM_CPUID_FLAG_STATE_READ_NEXT BIT(2)
217 217
218/* for KVM_SET_CPUID2 */ 218/* for KVM_SET_CPUID2 */
219struct kvm_cpuid2 { 219struct kvm_cpuid2 {
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 0a1e3b8b964d..78a4439bfdc5 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -219,8 +219,14 @@ static bool supported_xcr0_bit(unsigned bit)
219 219
220#define F(x) bit(X86_FEATURE_##x) 220#define F(x) bit(X86_FEATURE_##x)
221 221
222static int do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, 222static int __do_cpuid_ent_emulated(struct kvm_cpuid_entry2 *entry,
223 u32 index, int *nent, int maxnent) 223 u32 func, u32 index, int *nent, int maxnent)
224{
225 return 0;
226}
227
228static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
229 u32 index, int *nent, int maxnent)
224{ 230{
225 int r; 231 int r;
226 unsigned f_nx = is_efer_nx() ? F(NX) : 0; 232 unsigned f_nx = is_efer_nx() ? F(NX) : 0;
@@ -515,6 +521,15 @@ out:
515 return r; 521 return r;
516} 522}
517 523
524static int do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 func,
525 u32 idx, int *nent, int maxnent, unsigned int type)
526{
527 if (type == KVM_GET_EMULATED_CPUID)
528 return __do_cpuid_ent_emulated(entry, func, idx, nent, maxnent);
529
530 return __do_cpuid_ent(entry, func, idx, nent, maxnent);
531}
532
518#undef F 533#undef F
519 534
520struct kvm_cpuid_param { 535struct kvm_cpuid_param {
@@ -529,8 +544,34 @@ static bool is_centaur_cpu(const struct kvm_cpuid_param *param)
529 return boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR; 544 return boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR;
530} 545}
531 546
532int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, 547static bool sanity_check_entries(struct kvm_cpuid_entry2 __user *entries,
533 struct kvm_cpuid_entry2 __user *entries) 548 __u32 num_entries, unsigned int ioctl_type)
549{
550 int i;
551
552 if (ioctl_type != KVM_GET_EMULATED_CPUID)
553 return false;
554
555 /*
556 * We want to make sure that ->padding is being passed clean from
557 * userspace in case we want to use it for something in the future.
558 *
559 * Sadly, this wasn't enforced for KVM_GET_SUPPORTED_CPUID and so we
560 * have to give ourselves satisfied only with the emulated side. /me
561 * sheds a tear.
562 */
563 for (i = 0; i < num_entries; i++) {
564 if (entries[i].padding[0] ||
565 entries[i].padding[1] ||
566 entries[i].padding[2])
567 return true;
568 }
569 return false;
570}
571
572int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 *cpuid,
573 struct kvm_cpuid_entry2 __user *entries,
574 unsigned int type)
534{ 575{
535 struct kvm_cpuid_entry2 *cpuid_entries; 576 struct kvm_cpuid_entry2 *cpuid_entries;
536 int limit, nent = 0, r = -E2BIG, i; 577 int limit, nent = 0, r = -E2BIG, i;
@@ -547,6 +588,10 @@ int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
547 goto out; 588 goto out;
548 if (cpuid->nent > KVM_MAX_CPUID_ENTRIES) 589 if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
549 cpuid->nent = KVM_MAX_CPUID_ENTRIES; 590 cpuid->nent = KVM_MAX_CPUID_ENTRIES;
591
592 if (sanity_check_entries(entries, cpuid->nent, type))
593 return -EINVAL;
594
550 r = -ENOMEM; 595 r = -ENOMEM;
551 cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry2) * cpuid->nent); 596 cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry2) * cpuid->nent);
552 if (!cpuid_entries) 597 if (!cpuid_entries)
@@ -560,7 +605,7 @@ int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
560 continue; 605 continue;
561 606
562 r = do_cpuid_ent(&cpuid_entries[nent], ent->func, ent->idx, 607 r = do_cpuid_ent(&cpuid_entries[nent], ent->func, ent->idx,
563 &nent, cpuid->nent); 608 &nent, cpuid->nent, type);
564 609
565 if (r) 610 if (r)
566 goto out_free; 611 goto out_free;
@@ -571,7 +616,7 @@ int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
571 limit = cpuid_entries[nent - 1].eax; 616 limit = cpuid_entries[nent - 1].eax;
572 for (func = ent->func + 1; func <= limit && nent < cpuid->nent && r == 0; ++func) 617 for (func = ent->func + 1; func <= limit && nent < cpuid->nent && r == 0; ++func)
573 r = do_cpuid_ent(&cpuid_entries[nent], func, ent->idx, 618 r = do_cpuid_ent(&cpuid_entries[nent], func, ent->idx,
574 &nent, cpuid->nent); 619 &nent, cpuid->nent, type);
575 620
576 if (r) 621 if (r)
577 goto out_free; 622 goto out_free;
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
index b7fd07984888..f1e4895174b2 100644
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
@@ -6,8 +6,9 @@
6void kvm_update_cpuid(struct kvm_vcpu *vcpu); 6void kvm_update_cpuid(struct kvm_vcpu *vcpu);
7struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu, 7struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
8 u32 function, u32 index); 8 u32 function, u32 index);
9int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, 9int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 *cpuid,
10 struct kvm_cpuid_entry2 __user *entries); 10 struct kvm_cpuid_entry2 __user *entries,
11 unsigned int type);
11int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, 12int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
12 struct kvm_cpuid *cpuid, 13 struct kvm_cpuid *cpuid,
13 struct kvm_cpuid_entry __user *entries); 14 struct kvm_cpuid_entry __user *entries);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index edf2a07df3a3..3d1e3ee8b39e 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2564,6 +2564,7 @@ int kvm_dev_ioctl_check_extension(long ext)
2564 case KVM_CAP_MMU_SHADOW_CACHE_CONTROL: 2564 case KVM_CAP_MMU_SHADOW_CACHE_CONTROL:
2565 case KVM_CAP_SET_TSS_ADDR: 2565 case KVM_CAP_SET_TSS_ADDR:
2566 case KVM_CAP_EXT_CPUID: 2566 case KVM_CAP_EXT_CPUID:
2567 case KVM_CAP_EXT_EMUL_CPUID:
2567 case KVM_CAP_CLOCKSOURCE: 2568 case KVM_CAP_CLOCKSOURCE:
2568 case KVM_CAP_PIT: 2569 case KVM_CAP_PIT:
2569 case KVM_CAP_NOP_IO_DELAY: 2570 case KVM_CAP_NOP_IO_DELAY:
@@ -2673,15 +2674,17 @@ long kvm_arch_dev_ioctl(struct file *filp,
2673 r = 0; 2674 r = 0;
2674 break; 2675 break;
2675 } 2676 }
2676 case KVM_GET_SUPPORTED_CPUID: { 2677 case KVM_GET_SUPPORTED_CPUID:
2678 case KVM_GET_EMULATED_CPUID: {
2677 struct kvm_cpuid2 __user *cpuid_arg = argp; 2679 struct kvm_cpuid2 __user *cpuid_arg = argp;
2678 struct kvm_cpuid2 cpuid; 2680 struct kvm_cpuid2 cpuid;
2679 2681
2680 r = -EFAULT; 2682 r = -EFAULT;
2681 if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid)) 2683 if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid))
2682 goto out; 2684 goto out;
2683 r = kvm_dev_ioctl_get_supported_cpuid(&cpuid, 2685
2684 cpuid_arg->entries); 2686 r = kvm_dev_ioctl_get_cpuid(&cpuid, cpuid_arg->entries,
2687 ioctl);
2685 if (r) 2688 if (r)
2686 goto out; 2689 goto out;
2687 2690
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index e32e776f20c0..32c60b98ddf8 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -541,6 +541,7 @@ struct kvm_ppc_smmu_info {
541#define KVM_TRACE_ENABLE __KVM_DEPRECATED_MAIN_W_0x06 541#define KVM_TRACE_ENABLE __KVM_DEPRECATED_MAIN_W_0x06
542#define KVM_TRACE_PAUSE __KVM_DEPRECATED_MAIN_0x07 542#define KVM_TRACE_PAUSE __KVM_DEPRECATED_MAIN_0x07
543#define KVM_TRACE_DISABLE __KVM_DEPRECATED_MAIN_0x08 543#define KVM_TRACE_DISABLE __KVM_DEPRECATED_MAIN_0x08
544#define KVM_GET_EMULATED_CPUID _IOWR(KVMIO, 0x09, struct kvm_cpuid2)
544 545
545/* 546/*
546 * Extension capability list. 547 * Extension capability list.
@@ -668,6 +669,7 @@ struct kvm_ppc_smmu_info {
668#define KVM_CAP_IRQ_XICS 92 669#define KVM_CAP_IRQ_XICS 92
669#define KVM_CAP_ARM_EL1_32BIT 93 670#define KVM_CAP_ARM_EL1_32BIT 93
670#define KVM_CAP_SPAPR_MULTITCE 94 671#define KVM_CAP_SPAPR_MULTITCE 94
672#define KVM_CAP_EXT_EMUL_CPUID 95
671 673
672#ifdef KVM_CAP_IRQ_ROUTING 674#ifdef KVM_CAP_IRQ_ROUTING
673 675