i386: expose TCGTCGTCGTCG in the 0x40000000 CPUID leaf

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.

Backports commits 4ed3d478c63dc65a02eba774c35116618ea5ff10 and  1ce36bfe6424243082d3d7c2330e1a0a4ff72a43 from qemu
This commit is contained in:
Daniel P. Berrange 2018-03-03 22:53:17 -05:00 committed by Lioncash
parent 570c064065
commit abf3c71af2
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
2 changed files with 43 additions and 20 deletions

View file

@ -2418,28 +2418,26 @@ 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 limit;
uint32_t signature[3];
/* test if maximum index reached */
if (index & 0x80000000) {
if (index > env->cpuid_xlevel) {
if (env->cpuid_xlevel2 > 0) {
/* Handle the Centaur's CPUID instruction. */
if (index > env->cpuid_xlevel2) {
index = env->cpuid_xlevel2;
} else if (index < 0xC0000000) {
index = env->cpuid_xlevel;
}
} else {
/* Intel documentation states that invalid EAX input will
* return the same information as EAX=cpuid_level
* (Intel SDM Vol. 2A - Instruction Set Reference - CPUID)
*/
index = env->cpuid_level;
}
}
/* Calculate & apply limits for different index ranges */
if (index >= 0xC0000000) {
limit = env->cpuid_xlevel2;
} else if (index >= 0x80000000) {
limit = env->cpuid_xlevel;
} else if (index >= 0x40000000) {
limit = 0x40000001;
} else {
if (index > env->cpuid_level)
index = env->cpuid_level;
limit = env->cpuid_level;
}
if (index > limit) {
/* Intel documentation states that invalid EAX input will
* return the same information as EAX=cpuid_level
* (Intel SDM Vol. 2A - Instruction Set Reference - CPUID)
*/
index = env->cpuid_level;
}
switch(index) {
@ -2655,6 +2653,30 @@ 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(env->uc) && cpu->expose_tcg) {
memcpy(signature, "TCGTCGTCGTCG", 12);
*eax = 0x40000001;
*ebx = signature[0];
*ecx = signature[1];
*edx = signature[2];
} else {
*eax = 0;
*ebx = 0;
*ecx = 0;
*edx = 0;
}
break;
case 0x40000001:
*eax = 0;
*ebx = 0;
*ecx = 0;
*edx = 0;
break;
case 0x80000000:
*eax = env->cpuid_xlevel;
*ebx = env->cpuid_vendor1;

View file

@ -1199,6 +1199,7 @@ typedef 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;