Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86, kvm: correctly access the KVM_CPUID_FEATURES leaf at 0x40000101

When Hyper-V hypervisor leaves are present, KVM must relocate
its own leaves at 0x40000100, because Windows does not look for
Hyper-V leaves at indices other than 0x40000000. In this case,
the KVM features are at 0x40000101, but the old code would always
look at 0x40000001.

Fix by using kvm_cpuid_base(). This also requires making the
function non-inline, since kvm_cpuid_base() is static.

Fixes: 1085ba7f552d84aa8ac0ae903fa8d0cc2ff9f79d
Cc: stable@vger.kernel.org
Cc: mtosatti@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

+11 -5
+6 -5
arch/x86/include/asm/kvm_para.h
··· 85 85 return ret; 86 86 } 87 87 88 - static inline unsigned int kvm_arch_para_features(void) 89 - { 90 - return cpuid_eax(KVM_CPUID_FEATURES); 91 - } 92 - 93 88 #ifdef CONFIG_KVM_GUEST 94 89 bool kvm_para_available(void); 90 + unsigned int kvm_arch_para_features(void); 95 91 void __init kvm_guest_init(void); 96 92 void kvm_async_pf_task_wait(u32 token); 97 93 void kvm_async_pf_task_wake(u32 token); ··· 108 112 #define kvm_async_pf_task_wake(T) do {} while(0) 109 113 110 114 static inline bool kvm_para_available(void) 115 + { 116 + return 0; 117 + } 118 + 119 + static inline unsigned int kvm_arch_para_features(void) 111 120 { 112 121 return 0; 113 122 }
+5
arch/x86/kernel/kvm.c
··· 527 527 } 528 528 EXPORT_SYMBOL_GPL(kvm_para_available); 529 529 530 + unsigned int kvm_arch_para_features(void) 531 + { 532 + return cpuid_eax(kvm_cpuid_base() | KVM_CPUID_FEATURES); 533 + } 534 + 530 535 static uint32_t __init kvm_detect(void) 531 536 { 532 537 return kvm_cpuid_base();