[RFC PATCH] kvm: Enable -cpu option to hide KVM

Alex Williamson
2014-06-01T16:25:24Z

The latest Nvidia driver (337.88) specifically checks for KVM as the
hypervisor and reports Code 43 for the driver in a Windows guest when
found. Removing or changing the KVM signature is sufficient to allow
the driver to load. This patch adds an option to easily allow the KVM
hypervisor signature to be hidden using '-cpu no-kvm'.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
---
target-i386/cpu-qom.h | 1 +
target-i386/cpu.c | 1 +
target-i386/kvm.c | 28 +++++++++++++++-------------
3 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index e9b3d57..99bb059 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -87,6 +87,7 @@ typedef struct X86CPU {
bool hyperv_time;
bool check_cpuid;
bool enforce_cpuid;
+ bool no_kvm;

/* if true the CPUID code directly forward host cache leaves to the guest */
bool cache_info_passthrough;
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 042a48d..8e6ce9c 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2792,6 +2792,7 @@ static Property x86_cpu_properties[] = {
DEFINE_PROP_BOOL("hv-time", X86CPU, hyperv_time, false),
DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, false),
DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
+ DEFINE_PROP_BOOL("no-kvm", X86CPU, no_kvm, false),
DEFINE_PROP_END_OF_LIST()
};

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 0d894ef..920898e 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -528,23 +528,25 @@ int kvm_arch_init_vcpu(CPUState *cs)
has_msr_hv_hypercall = true;
}

- 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];
+ if (!cpu->no_kvm) {
+ 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];
+ 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);

- has_msr_kvm_steal_time = c->eax & (1 << KVM_FEATURE_STEAL_TIME);
+ has_msr_kvm_steal_time = c->eax & (1 << KVM_FEATURE_STEAL_TIME);
+ }

cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);