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>
This commit is contained in:
parent
977c7b6d89
commit
234cc64796
@ -455,6 +455,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
|
|||||||
uint32_t unused;
|
uint32_t unused;
|
||||||
struct kvm_cpuid_entry2 *c;
|
struct kvm_cpuid_entry2 *c;
|
||||||
uint32_t signature[3];
|
uint32_t signature[3];
|
||||||
|
int kvm_base = KVM_CPUID_SIGNATURE;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
memset(&cpuid_data, 0, sizeof(cpuid_data));
|
memset(&cpuid_data, 0, sizeof(cpuid_data));
|
||||||
@ -462,26 +463,22 @@ int kvm_arch_init_vcpu(CPUState *cs)
|
|||||||
cpuid_i = 0;
|
cpuid_i = 0;
|
||||||
|
|
||||||
/* Paravirtualization CPUIDs */
|
/* Paravirtualization CPUIDs */
|
||||||
c = &cpuid_data.entries[cpuid_i++];
|
if (hyperv_enabled(cpu)) {
|
||||||
c->function = KVM_CPUID_SIGNATURE;
|
c = &cpuid_data.entries[cpuid_i++];
|
||||||
if (!hyperv_enabled(cpu)) {
|
c->function = HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS;
|
||||||
memcpy(signature, "KVMKVMKVM\0\0\0", 12);
|
|
||||||
c->eax = 0;
|
|
||||||
} else {
|
|
||||||
memcpy(signature, "Microsoft Hv", 12);
|
memcpy(signature, "Microsoft Hv", 12);
|
||||||
c->eax = HYPERV_CPUID_MIN;
|
c->eax = HYPERV_CPUID_MIN;
|
||||||
}
|
c->ebx = signature[0];
|
||||||
c->ebx = signature[0];
|
c->ecx = signature[1];
|
||||||
c->ecx = signature[1];
|
c->edx = signature[2];
|
||||||
c->edx = signature[2];
|
|
||||||
|
|
||||||
c = &cpuid_data.entries[cpuid_i++];
|
c = &cpuid_data.entries[cpuid_i++];
|
||||||
c->function = KVM_CPUID_FEATURES;
|
c->function = HYPERV_CPUID_INTERFACE;
|
||||||
c->eax = env->features[FEAT_KVM];
|
|
||||||
|
|
||||||
if (hyperv_enabled(cpu)) {
|
|
||||||
memcpy(signature, "Hv#1\0\0\0\0\0\0\0\0", 12);
|
memcpy(signature, "Hv#1\0\0\0\0\0\0\0\0", 12);
|
||||||
c->eax = signature[0];
|
c->eax = signature[0];
|
||||||
|
c->ebx = 0;
|
||||||
|
c->ecx = 0;
|
||||||
|
c->edx = 0;
|
||||||
|
|
||||||
c = &cpuid_data.entries[cpuid_i++];
|
c = &cpuid_data.entries[cpuid_i++];
|
||||||
c->function = HYPERV_CPUID_VERSION;
|
c->function = HYPERV_CPUID_VERSION;
|
||||||
@ -513,15 +510,21 @@ int kvm_arch_init_vcpu(CPUState *cs)
|
|||||||
c->eax = 0x40;
|
c->eax = 0x40;
|
||||||
c->ebx = 0x40;
|
c->ebx = 0x40;
|
||||||
|
|
||||||
c = &cpuid_data.entries[cpuid_i++];
|
kvm_base = KVM_CPUID_SIGNATURE_NEXT;
|
||||||
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];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF);
|
||||||
|
|
||||||
has_msr_pv_eoi_en = c->eax & (1 << KVM_FEATURE_PV_EOI);
|
has_msr_pv_eoi_en = c->eax & (1 << KVM_FEATURE_PV_EOI);
|
||||||
|
Loading…
Reference in New Issue
Block a user