diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2013-10-02 10:06:14 -0400 |
---|---|---|
committer | Gleb Natapov <gleb@redhat.com> | 2013-10-03 05:29:04 -0400 |
commit | 647e23bb333ff196e7be8ae08c842d855fb850f6 (patch) | |
tree | a71cae213807d51e30ad5e942281dfdfd55db99f /arch/x86/kvm | |
parent | 29242cb5c63b1f8e12e8055ba1a6c3e0004fa86d (diff) |
KVM: x86: mask unsupported XSAVE entries from leaf 0Dh index 0
XSAVE entries that KVM does not support are reported by
KVM_GET_SUPPORTED_CPUID for leaf 0Dh index 0 if the host supports them;
they should be left out unless there is also hypervisor support for them.
Sub-leafs are correctly handled in supported_xcr0_bit, fix index 0
to match.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r-- | arch/x86/kvm/cpuid.c | 4 | ||||
-rw-r--r-- | arch/x86/kvm/x86.h | 1 |
2 files changed, 4 insertions, 1 deletions
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index b110fe6c03d4..a03a9faf81b0 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c | |||
@@ -182,7 +182,7 @@ static bool supported_xcr0_bit(unsigned bit) | |||
182 | { | 182 | { |
183 | u64 mask = ((u64)1 << bit); | 183 | u64 mask = ((u64)1 << bit); |
184 | 184 | ||
185 | return mask & (XSTATE_FP | XSTATE_SSE | XSTATE_YMM) & host_xcr0; | 185 | return mask & KVM_SUPPORTED_XCR0 & host_xcr0; |
186 | } | 186 | } |
187 | 187 | ||
188 | #define F(x) bit(X86_FEATURE_##x) | 188 | #define F(x) bit(X86_FEATURE_##x) |
@@ -383,6 +383,8 @@ static int do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, | |||
383 | case 0xd: { | 383 | case 0xd: { |
384 | int idx, i; | 384 | int idx, i; |
385 | 385 | ||
386 | entry->eax &= host_xcr0 & KVM_SUPPORTED_XCR0; | ||
387 | entry->edx &= (host_xcr0 & KVM_SUPPORTED_XCR0) >> 32; | ||
386 | entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX; | 388 | entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX; |
387 | for (idx = 1, i = 1; idx < 64; ++idx) { | 389 | for (idx = 1, i = 1; idx < 64; ++idx) { |
388 | if (*nent >= maxnent) | 390 | if (*nent >= maxnent) |
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index e224f7a671b6..587fb9ede436 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h | |||
@@ -122,6 +122,7 @@ int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt, | |||
122 | gva_t addr, void *val, unsigned int bytes, | 122 | gva_t addr, void *val, unsigned int bytes, |
123 | struct x86_exception *exception); | 123 | struct x86_exception *exception); |
124 | 124 | ||
125 | #define KVM_SUPPORTED_XCR0 (XSTATE_FP | XSTATE_SSE | XSTATE_YMM) | ||
125 | extern u64 host_xcr0; | 126 | extern u64 host_xcr0; |
126 | 127 | ||
127 | extern struct static_key kvm_no_apic_vcpu; | 128 | extern struct static_key kvm_no_apic_vcpu; |