aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/cpuid.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2014-12-03 08:38:01 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2014-12-05 07:57:17 -0500
commit412a3c411e6df54179f300e8d8d6247327865a2d (patch)
treee8577d48dd317052835aaddeac35a94eb2bf45b4 /arch/x86/kvm/cpuid.c
parent55412b2eda2b783ef37316eb06ba91fa63ae049d (diff)
KVM: cpuid: set CPUID(EAX=0xd,ECX=1).EBX correctly
This is the size of the XSAVES area. This starts providing guest support for XSAVES (with no support yet for supervisor states, i.e. XSS == 0 always in guests for now). Wanpeng Li suggested testing XSAVEC as well as XSAVES, since in practice no real processor exists that only has one of them, and there is no other way for userspace programs to compute the area of the XSAVEC save area. CPUID(EAX=0xd,ECX=1).EBX provides an upper bound. Suggested-by: Radim Krčmář <rkrcmar@redhat.com> Reviewed-by: Radim Krčmář <rkrcmar@redhat.com> Tested-by: Wanpeng Li <wanpeng.li@linux.intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm/cpuid.c')
-rw-r--r--arch/x86/kvm/cpuid.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index e24df01ab118..2f7bc2de9915 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;
@@ -87,9 +88,13 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu)
87 (best->eax | ((u64)best->edx << 32)) & 88 (best->eax | ((u64)best->edx << 32)) &
88 kvm_supported_xcr0(); 89 kvm_supported_xcr0();
89 vcpu->arch.guest_xstate_size = best->ebx = 90 vcpu->arch.guest_xstate_size = best->ebx =
90 xstate_required_size(vcpu->arch.xcr0); 91 xstate_required_size(vcpu->arch.xcr0, false);
91 } 92 }
92 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
93 /* 98 /*
94 * 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
95 * address checks; exit if it is ever changed. 100 * address checks; exit if it is ever changed.
@@ -470,9 +475,14 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
470 goto out; 475 goto out;
471 476
472 do_cpuid_1_ent(&entry[i], function, idx); 477 do_cpuid_1_ent(&entry[i], function, idx);
473 if (idx == 1) 478 if (idx == 1) {
474 entry[i].eax &= kvm_supported_word10_x86_features; 479 entry[i].eax &= kvm_supported_word10_x86_features;
475 else if (entry[i].eax == 0 || !(supported & mask)) 480 entry[i].ebx = 0;
481 if (entry[i].eax & (F(XSAVES)|F(XSAVEC)))
482 entry[i].ebx =
483 xstate_required_size(supported,
484 true);
485 } else if (entry[i].eax == 0 || !(supported & mask))
476 continue; 486 continue;
477 entry[i].flags |= 487 entry[i].flags |=
478 KVM_CPUID_FLAG_SIGNIFCANT_INDEX; 488 KVM_CPUID_FLAG_SIGNIFCANT_INDEX;