diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2014-01-23 19:27:24 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-02-03 17:33:55 +0100 |
commit | 234cc64796557eea829544e4ff72ee99b6149187 (patch) | |
tree | 47f69a505738738bc070902ebc036e9bad241a58 /target-i386 | |
parent | 977c7b6d8909464eb3a510829f534451d0adb227 (diff) | |
download | hqemu-234cc64796557eea829544e4ff72ee99b6149187.zip hqemu-234cc64796557eea829544e4ff72ee99b6149187.tar.gz |
KVM: fix coexistence of KVM and Hyper-V leaves
kvm_arch_init_vcpu's initialization of the KVM leaves at 0x40000100
is broken, because KVM_CPUID_FEATURES is left at 0x40000001. Move
it to 0x40000101 if Hyper-V is enabled.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'target-i386')
-rw-r--r-- | target-i386/kvm.c | 47 |
1 files changed, 25 insertions, 22 deletions
diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 0a21c30..5738911 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -455,6 +455,7 @@ int kvm_arch_init_vcpu(CPUState *cs) uint32_t unused; struct kvm_cpuid_entry2 *c; uint32_t signature[3]; + int kvm_base = KVM_CPUID_SIGNATURE; int r; memset(&cpuid_data, 0, sizeof(cpuid_data)); @@ -462,26 +463,22 @@ int kvm_arch_init_vcpu(CPUState *cs) cpuid_i = 0; /* Paravirtualization CPUIDs */ - c = &cpuid_data.entries[cpuid_i++]; - c->function = KVM_CPUID_SIGNATURE; - if (!hyperv_enabled(cpu)) { - memcpy(signature, "KVMKVMKVM\0\0\0", 12); - c->eax = 0; - } else { + if (hyperv_enabled(cpu)) { + c = &cpuid_data.entries[cpuid_i++]; + c->function = HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS; memcpy(signature, "Microsoft Hv", 12); c->eax = HYPERV_CPUID_MIN; - } - c->ebx = signature[0]; - c->ecx = signature[1]; - c->edx = signature[2]; - - c = &cpuid_data.entries[cpuid_i++]; - c->function = KVM_CPUID_FEATURES; - c->eax = env->features[FEAT_KVM]; + c->ebx = signature[0]; + c->ecx = signature[1]; + c->edx = signature[2]; - if (hyperv_enabled(cpu)) { + c = &cpuid_data.entries[cpuid_i++]; + c->function = HYPERV_CPUID_INTERFACE; memcpy(signature, "Hv#1\0\0\0\0\0\0\0\0", 12); c->eax = signature[0]; + c->ebx = 0; + c->ecx = 0; + c->edx = 0; c = &cpuid_data.entries[cpuid_i++]; c->function = HYPERV_CPUID_VERSION; @@ -513,15 +510,21 @@ int kvm_arch_init_vcpu(CPUState *cs) c->eax = 0x40; c->ebx = 0x40; - c = &cpuid_data.entries[cpuid_i++]; - c->function = KVM_CPUID_SIGNATURE_NEXT; - memcpy(signature, "KVMKVMKVM\0\0\0", 12); - c->eax = 0; - c->ebx = signature[0]; - c->ecx = signature[1]; - c->edx = signature[2]; + kvm_base = KVM_CPUID_SIGNATURE_NEXT; } + memcpy(signature, "KVMKVMKVM\0\0\0", 12); + c = &cpuid_data.entries[cpuid_i++]; + c->function = KVM_CPUID_SIGNATURE | kvm_base; + c->eax = 0; + c->ebx = signature[0]; + c->ecx = signature[1]; + c->edx = signature[2]; + + c = &cpuid_data.entries[cpuid_i++]; + c->function = KVM_CPUID_FEATURES | kvm_base; + c->eax = env->features[FEAT_KVM]; + has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF); has_msr_pv_eoi_en = c->eax & (1 << KVM_FEATURE_PV_EOI); |