@@ -376,6 +376,11 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
#define PC_COMPAT_2_8 \
HW_COMPAT_2_8 \
{\
+ .driver = TYPE_X86_CPU,\
+ .property = "tcg-cpuid",\
+ .value = "off",\
+ },\
+ {\
.driver = "kvmclock",\
.property = "x-mach-use-reliable-get-clock",\
.value = "off",\
@@ -2626,6 +2626,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
X86CPU *cpu = x86_env_get_cpu(env);
CPUState *cs = CPU(cpu);
uint32_t pkg_offset;
+ uint32_t signature[3];
/* test if maximum index reached */
switch (index & 0xF0000000) {
@@ -2638,6 +2639,16 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
index = env->cpuid_level;
}
break;
+ case 0x40000000:
+ /* Not sure what we should do here. Intel and KVM
+ * documentation is not explicit about it, but it
+ * looks like KVM will return the highest _basic_
+ * leaf (env->cpuid_level) on that case.
+ */
+ if (index > 0x40000001) {
+ index = env->cpuid_level;
+ }
+ break;
case 0x80000000:
if (index > env->cpuid_xlevel) {
index = env->cpuid_xlevel;
@@ -2879,6 +2890,24 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
}
break;
}
+ case 0x40000000:
+ /*
+ * CPUID code in kvm_arch_init_vcpu() ignores stuff
+ * set here, but we restrict to TCG none the less.
+ */
+ if (tcg_enabled() && cpu->expose_tcg) {
+ memcpy(signature, "TCGTCGTCGTCG", 12);
+ *eax = 0;
+ *ebx = signature[0];
+ *ecx = signature[1];
+ *edx = signature[2];
+ } else {
+ *eax = 0;
+ *ebx = 0;
+ *ecx = 0;
+ *edx = 0;
+ }
+ break;
case 0x80000000:
*eax = env->cpuid_xlevel;
*ebx = env->cpuid_vendor1;
@@ -4020,6 +4049,7 @@ static Property x86_cpu_properties[] = {
DEFINE_PROP_BOOL("kvm-no-smi-migration", X86CPU, kvm_no_smi_migration,
false),
DEFINE_PROP_BOOL("vmware-cpuid-freq", X86CPU, vmware_cpuid_freq, true),
+ DEFINE_PROP_BOOL("tcg-cpuid", X86CPU, expose_tcg, true),
DEFINE_PROP_END_OF_LIST()
};
@@ -1216,6 +1216,7 @@ struct X86CPU {
bool check_cpuid;
bool enforce_cpuid;
bool expose_kvm;
+ bool expose_tcg;
bool migratable;
bool max_features; /* Enable all supported features automatically */
uint32_t apic_id;
Currently when running KVM, we expose "KVMKVMKVM\0\0\0" in the 0x40000000 CPUID leaf. Other hypervisors (VMWare, HyperV, Xen, BHyve) all do the same thing, which leaves TCG as the odd one out. The CPUID signature is used by software to detect which virtual environment they are running in and (potentially) change behaviour in certain ways. For example, systemd supports a ConditionVirtualization= setting in unit files. The virt-what command can also report the virt type it is running on Currently both these apps have to resort to custom hacks like looking for 'fw-cfg' entry in the /proc/device-tree file to identify TCG. This change thus proposes a signature "TCGTCGTCGTCG" to be reported when running under TCG. To hide this, the -cpu option tcg-cpuid=off can be used. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- include/hw/i386/pc.h | 5 +++++ target/i386/cpu.c | 30 ++++++++++++++++++++++++++++++ target/i386/cpu.h | 1 + 3 files changed, 36 insertions(+)