qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] i386/kvm: Add CPU property to expose VMware CPUID signature


From: Liran Alon
Subject: [PATCH] i386/kvm: Add CPU property to expose VMware CPUID signature
Date: Tue, 10 Mar 2020 02:40:17 +0200

Some guests are only familiar with VMware PV interface. Therefore, in
order for these guests to run properly on KVM, we need to be able to
expose VMware main CPUID leaf. i.e. leaf 0x40000000.

E.g. Without exposing this VMware CPUID leaf, some guests will fail to boot.
For example, because of guest attempt to calibrate TSC.

Signed-off-by: Liran Alon <address@hidden>
---
 target/i386/cpu.c |  1 +
 target/i386/cpu.h |  1 +
 target/i386/kvm.c | 35 +++++++++++++++++++++++++++++------
 3 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 92fafa265914..694766d45a9b 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -7127,6 +7127,7 @@ static Property x86_cpu_properties[] = {
     DEFINE_PROP_BOOL("l3-cache", X86CPU, enable_l3_cache, true),
     DEFINE_PROP_BOOL("kvm-no-smi-migration", X86CPU, kvm_no_smi_migration,
                      false),
+    DEFINE_PROP_BOOL("vmware-cpuid", X86CPU, expose_vmware, false),
     DEFINE_PROP_BOOL("vmware-cpuid-freq", X86CPU, vmware_cpuid_freq, true),
     DEFINE_PROP_BOOL("tcg-cpuid", X86CPU, expose_tcg, true),
     DEFINE_PROP_BOOL("x-migrate-smi-count", X86CPU, migrate_smi_count,
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 9c7cd7cde107..bca626963e25 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1647,6 +1647,7 @@ struct X86CPU {
      */
     bool force_features;
     bool expose_kvm;
+    bool expose_vmware;
     bool expose_tcg;
     bool migratable;
     bool migrate_smi_count;
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 00917196dffb..2656258b96b3 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -1187,6 +1187,15 @@ static int hyperv_handle_properties(CPUState *cs,
     if (!hyperv_enabled(cpu))
         return 0;
 
+    /*
+     * VMware & Hyper-V conflicts in CPUID leafs.
+     * Therefore, they cannot exists together.
+     */
+    if (cpu->expose_vmware) {
+        error_report("vmware-cpuid not compatible with hyperv options");
+        return -ENOTSUP;
+    }
+
     if (hyperv_feat_enabled(cpu, HYPERV_FEAT_EVMCS) ||
         cpu->hyperv_passthrough) {
         uint16_t evmcs_version;
@@ -1508,6 +1517,18 @@ int kvm_arch_init_vcpu(CPUState *cs)
         has_msr_hv_hypercall = true;
     }
 
+    if (cpu->expose_vmware) {
+        c = &cpuid_data.entries[cpuid_i++];
+        c->function = KVM_CPUID_SIGNATURE;
+        memcpy(signature, "VMwareVMware", 12);
+        c->eax = KVM_CPUID_SIGNATURE;
+        c->ebx = signature[0];
+        c->ecx = signature[1];
+        c->edx = signature[2];
+
+        kvm_base = KVM_CPUID_SIGNATURE_NEXT;
+    }
+
     if (cpu->expose_kvm) {
         memcpy(signature, "KVMKVMKVM\0\0\0", 12);
         c = &cpuid_data.entries[cpuid_i++];
@@ -1791,11 +1812,13 @@ int kvm_arch_init_vcpu(CPUState *cs)
         }
     }
 
-    if (cpu->vmware_cpuid_freq
-        /* Guests depend on 0x40000000 to detect this feature, so only expose
-         * it if KVM exposes leaf 0x40000000. (Conflicts with Hyper-V) */
-        && cpu->expose_kvm
-        && kvm_base == KVM_CPUID_SIGNATURE
+    if (cpu->vmware_cpuid_freq &&
+        (cpu->expose_vmware ||
+         /*
+          * Guests depend on 0x40000000 to detect this feature, so only expose
+          * it if KVM exposes leaf 0x40000000. (Conflicts with Hyper-V)
+          */
+          (cpu->expose_kvm && kvm_base == KVM_CPUID_SIGNATURE))
         /* TSC clock must be stable and known for this feature. */
         && tsc_is_stable_and_known(env)) {
 
@@ -1805,7 +1828,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
         c->ebx = env->apic_bus_freq / 1000; /* Hz to KHz */
         c->ecx = c->edx = 0;
 
-        c = cpuid_find_entry(&cpuid_data.cpuid, kvm_base, 0);
+        c = cpuid_find_entry(&cpuid_data.cpuid, KVM_CPUID_SIGNATURE, 0);
         c->eax = MAX(c->eax, KVM_CPUID_SIGNATURE | 0x10);
     }
 
-- 
2.20.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]