diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2014-01-27 08:51:44 -0500 |
|---|---|---|
| committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-01-29 12:11:55 -0500 |
| commit | 77f01bdfa5e55dc19d3eb747181d2730a9bb3ca8 (patch) | |
| tree | 9f85c79d2af02145774799b31b0862dfcce5b844 | |
| parent | 1c300a40772dae829b91dad634999a6a522c0829 (diff) | |
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>
| -rw-r--r-- | arch/x86/include/asm/kvm_para.h | 11 | ||||
| -rw-r--r-- | arch/x86/kernel/kvm.c | 5 |
2 files changed, 11 insertions, 5 deletions
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index 1679cc799b26..c7678e43465b 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h | |||
| @@ -85,13 +85,9 @@ static inline long kvm_hypercall4(unsigned int nr, unsigned long p1, | |||
| 85 | return ret; | 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 | #ifdef CONFIG_KVM_GUEST | 88 | #ifdef CONFIG_KVM_GUEST |
| 94 | bool kvm_para_available(void); | 89 | bool kvm_para_available(void); |
| 90 | unsigned int kvm_arch_para_features(void); | ||
| 95 | void __init kvm_guest_init(void); | 91 | void __init kvm_guest_init(void); |
| 96 | void kvm_async_pf_task_wait(u32 token); | 92 | void kvm_async_pf_task_wait(u32 token); |
| 97 | void kvm_async_pf_task_wake(u32 token); | 93 | void kvm_async_pf_task_wake(u32 token); |
| @@ -116,6 +112,11 @@ static inline bool kvm_para_available(void) | |||
| 116 | return 0; | 112 | return 0; |
| 117 | } | 113 | } |
| 118 | 114 | ||
| 115 | static inline unsigned int kvm_arch_para_features(void) | ||
| 116 | { | ||
| 117 | return 0; | ||
| 118 | } | ||
| 119 | |||
| 119 | static inline u32 kvm_read_and_reset_pf_reason(void) | 120 | static inline u32 kvm_read_and_reset_pf_reason(void) |
| 120 | { | 121 | { |
| 121 | return 0; | 122 | return 0; |
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 0823003770fc..f81cadebcc0e 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c | |||
| @@ -527,6 +527,11 @@ bool kvm_para_available(void) | |||
| 527 | } | 527 | } |
| 528 | EXPORT_SYMBOL_GPL(kvm_para_available); | 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 | static uint32_t __init kvm_detect(void) | 535 | static uint32_t __init kvm_detect(void) |
| 531 | { | 536 | { |
| 532 | return kvm_cpuid_base(); | 537 | return kvm_cpuid_base(); |
