aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/cpuid.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kvm/cpuid.c')
-rw-r--r--arch/x86/kvm/cpuid.c57
1 files changed, 43 insertions, 14 deletions
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 976e3a57f9ea..8a80737ee6e6 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -23,7 +23,7 @@
23#include "mmu.h" 23#include "mmu.h"
24#include "trace.h" 24#include "trace.h"
25 25
26static u32 xstate_required_size(u64 xstate_bv) 26static u32 xstate_required_size(u64 xstate_bv, bool compacted)
27{ 27{
28 int feature_bit = 0; 28 int feature_bit = 0;
29 u32 ret = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET; 29 u32 ret = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET;
@@ -31,9 +31,10 @@ static u32 xstate_required_size(u64 xstate_bv)
31 xstate_bv &= XSTATE_EXTEND_MASK; 31 xstate_bv &= XSTATE_EXTEND_MASK;
32 while (xstate_bv) { 32 while (xstate_bv) {
33 if (xstate_bv & 0x1) { 33 if (xstate_bv & 0x1) {
34 u32 eax, ebx, ecx, edx; 34 u32 eax, ebx, ecx, edx, offset;
35 cpuid_count(0xD, feature_bit, &eax, &ebx, &ecx, &edx); 35 cpuid_count(0xD, feature_bit, &eax, &ebx, &ecx, &edx);
36 ret = max(ret, eax + ebx); 36 offset = compacted ? ret : ebx;
37 ret = max(ret, offset + eax);
37 } 38 }
38 39
39 xstate_bv >>= 1; 40 xstate_bv >>= 1;
@@ -53,6 +54,8 @@ u64 kvm_supported_xcr0(void)
53 return xcr0; 54 return xcr0;
54} 55}
55 56
57#define F(x) bit(X86_FEATURE_##x)
58
56int kvm_update_cpuid(struct kvm_vcpu *vcpu) 59int kvm_update_cpuid(struct kvm_vcpu *vcpu)
57{ 60{
58 struct kvm_cpuid_entry2 *best; 61 struct kvm_cpuid_entry2 *best;
@@ -64,13 +67,13 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu)
64 67
65 /* Update OSXSAVE bit */ 68 /* Update OSXSAVE bit */
66 if (cpu_has_xsave && best->function == 0x1) { 69 if (cpu_has_xsave && best->function == 0x1) {
67 best->ecx &= ~(bit(X86_FEATURE_OSXSAVE)); 70 best->ecx &= ~F(OSXSAVE);
68 if (kvm_read_cr4_bits(vcpu, X86_CR4_OSXSAVE)) 71 if (kvm_read_cr4_bits(vcpu, X86_CR4_OSXSAVE))
69 best->ecx |= bit(X86_FEATURE_OSXSAVE); 72 best->ecx |= F(OSXSAVE);
70 } 73 }
71 74
72 if (apic) { 75 if (apic) {
73 if (best->ecx & bit(X86_FEATURE_TSC_DEADLINE_TIMER)) 76 if (best->ecx & F(TSC_DEADLINE_TIMER))
74 apic->lapic_timer.timer_mode_mask = 3 << 17; 77 apic->lapic_timer.timer_mode_mask = 3 << 17;
75 else 78 else
76 apic->lapic_timer.timer_mode_mask = 1 << 17; 79 apic->lapic_timer.timer_mode_mask = 1 << 17;
@@ -85,9 +88,13 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu)
85 (best->eax | ((u64)best->edx << 32)) & 88 (best->eax | ((u64)best->edx << 32)) &
86 kvm_supported_xcr0(); 89 kvm_supported_xcr0();
87 vcpu->arch.guest_xstate_size = best->ebx = 90 vcpu->arch.guest_xstate_size = best->ebx =
88 xstate_required_size(vcpu->arch.xcr0); 91 xstate_required_size(vcpu->arch.xcr0, false);
89 } 92 }
90 93
94 best = kvm_find_cpuid_entry(vcpu, 0xD, 1);
95 if (best && (best->eax & (F(XSAVES) | F(XSAVEC))))
96 best->ebx = xstate_required_size(vcpu->arch.xcr0, true);
97
91 /* 98 /*
92 * The existing code assumes virtual address is 48-bit in the canonical 99 * The existing code assumes virtual address is 48-bit in the canonical
93 * address checks; exit if it is ever changed. 100 * address checks; exit if it is ever changed.
@@ -122,8 +129,8 @@ static void cpuid_fix_nx_cap(struct kvm_vcpu *vcpu)
122 break; 129 break;
123 } 130 }
124 } 131 }
125 if (entry && (entry->edx & bit(X86_FEATURE_NX)) && !is_efer_nx()) { 132 if (entry && (entry->edx & F(NX)) && !is_efer_nx()) {
126 entry->edx &= ~bit(X86_FEATURE_NX); 133 entry->edx &= ~F(NX);
127 printk(KERN_INFO "kvm: guest NX capability removed\n"); 134 printk(KERN_INFO "kvm: guest NX capability removed\n");
128 } 135 }
129} 136}
@@ -227,8 +234,6 @@ static void do_cpuid_1_ent(struct kvm_cpuid_entry2 *entry, u32 function,
227 entry->flags = 0; 234 entry->flags = 0;
228} 235}
229 236
230#define F(x) bit(X86_FEATURE_##x)
231
232static int __do_cpuid_ent_emulated(struct kvm_cpuid_entry2 *entry, 237static int __do_cpuid_ent_emulated(struct kvm_cpuid_entry2 *entry,
233 u32 func, u32 index, int *nent, int maxnent) 238 u32 func, u32 index, int *nent, int maxnent)
234{ 239{
@@ -267,6 +272,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
267 unsigned f_rdtscp = kvm_x86_ops->rdtscp_supported() ? F(RDTSCP) : 0; 272 unsigned f_rdtscp = kvm_x86_ops->rdtscp_supported() ? F(RDTSCP) : 0;
268 unsigned f_invpcid = kvm_x86_ops->invpcid_supported() ? F(INVPCID) : 0; 273 unsigned f_invpcid = kvm_x86_ops->invpcid_supported() ? F(INVPCID) : 0;
269 unsigned f_mpx = kvm_x86_ops->mpx_supported() ? F(MPX) : 0; 274 unsigned f_mpx = kvm_x86_ops->mpx_supported() ? F(MPX) : 0;
275 unsigned f_xsaves = kvm_x86_ops->xsaves_supported() ? F(XSAVES) : 0;
270 276
271 /* cpuid 1.edx */ 277 /* cpuid 1.edx */
272 const u32 kvm_supported_word0_x86_features = 278 const u32 kvm_supported_word0_x86_features =
@@ -317,7 +323,12 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
317 const u32 kvm_supported_word9_x86_features = 323 const u32 kvm_supported_word9_x86_features =
318 F(FSGSBASE) | F(BMI1) | F(HLE) | F(AVX2) | F(SMEP) | 324 F(FSGSBASE) | F(BMI1) | F(HLE) | F(AVX2) | F(SMEP) |
319 F(BMI2) | F(ERMS) | f_invpcid | F(RTM) | f_mpx | F(RDSEED) | 325 F(BMI2) | F(ERMS) | f_invpcid | F(RTM) | f_mpx | F(RDSEED) |
320 F(ADX) | F(SMAP); 326 F(ADX) | F(SMAP) | F(AVX512F) | F(AVX512PF) | F(AVX512ER) |
327 F(AVX512CD);
328
329 /* cpuid 0xD.1.eax */
330 const u32 kvm_supported_word10_x86_features =
331 F(XSAVEOPT) | F(XSAVEC) | F(XGETBV1) | f_xsaves;
321 332
322 /* all calls to cpuid_count() should be made on the same cpu */ 333 /* all calls to cpuid_count() should be made on the same cpu */
323 get_cpu(); 334 get_cpu();
@@ -453,16 +464,34 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
453 u64 supported = kvm_supported_xcr0(); 464 u64 supported = kvm_supported_xcr0();
454 465
455 entry->eax &= supported; 466 entry->eax &= supported;
467 entry->ebx = xstate_required_size(supported, false);
468 entry->ecx = entry->ebx;
456 entry->edx &= supported >> 32; 469 entry->edx &= supported >> 32;
457 entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX; 470 entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
471 if (!supported)
472 break;
473
458 for (idx = 1, i = 1; idx < 64; ++idx) { 474 for (idx = 1, i = 1; idx < 64; ++idx) {
459 u64 mask = ((u64)1 << idx); 475 u64 mask = ((u64)1 << idx);
460 if (*nent >= maxnent) 476 if (*nent >= maxnent)
461 goto out; 477 goto out;
462 478
463 do_cpuid_1_ent(&entry[i], function, idx); 479 do_cpuid_1_ent(&entry[i], function, idx);
464 if (entry[i].eax == 0 || !(supported & mask)) 480 if (idx == 1) {
465 continue; 481 entry[i].eax &= kvm_supported_word10_x86_features;
482 entry[i].ebx = 0;
483 if (entry[i].eax & (F(XSAVES)|F(XSAVEC)))
484 entry[i].ebx =
485 xstate_required_size(supported,
486 true);
487 } else {
488 if (entry[i].eax == 0 || !(supported & mask))
489 continue;
490 if (WARN_ON_ONCE(entry[i].ecx & 1))
491 continue;
492 }
493 entry[i].ecx = 0;
494 entry[i].edx = 0;
466 entry[i].flags |= 495 entry[i].flags |=
467 KVM_CPUID_FLAG_SIGNIFCANT_INDEX; 496 KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
468 ++*nent; 497 ++*nent;