aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2014-12-04 15:11:11 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2014-12-05 13:57:17 +0100
commit404e0a19e155e2303a081109f3ae5e625ac8030a (patch)
treec7ac01f970f148c126b5c17cc2137924b3d7728f /arch
parentKVM: cpuid: set CPUID(EAX=0xd,ECX=1).EBX correctly (diff)
downloadlinux-dev-404e0a19e155e2303a081109f3ae5e625ac8030a.tar.xz
linux-dev-404e0a19e155e2303a081109f3ae5e625ac8030a.zip
KVM: cpuid: mask more bits in leaf 0xd and subleaves
- EAX=0Dh, ECX=1: output registers EBX/ECX/EDX are reserved. - EAX=0Dh, ECX>1: output register ECX bit 0 is clear for all the CPUID leaves we support, because variable "supported" comes from XCR0 and not XSS. Bits above 0 are reserved, so ECX is overall zero. Output register EDX is reserved. Source: Intel Architecture Instruction Set Extensions Programming Reference, ref. number 319433-022 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')
-rw-r--r--arch/x86/kvm/cpuid.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 2f7bc2de9915..644bfe828ce1 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -482,8 +482,14 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
entry[i].ebx =
xstate_required_size(supported,
true);
- } else if (entry[i].eax == 0 || !(supported & mask))
- continue;
+ } else {
+ if (entry[i].eax == 0 || !(supported & mask))
+ continue;
+ if (WARN_ON_ONCE(entry[i].ecx & 1))
+ continue;
+ }
+ entry[i].ecx = 0;
+ entry[i].edx = 0;
entry[i].flags |=
KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
++*nent;