Make sure all CPUID values are handled, instead of exiting the

bhyve process when an unhandled one is encountered.

Hide some additional capabilities from the guest (e.g. debug store).

This fixes the issue with FreeBSD 9.1 MP guests exiting the VM on
AP spinup (where CPUID is used when sync'ing the TSCs) and the
issue with the Java build where CPUIDs are issued from a guest
userspace.

Submitted by:	tycho nightingale at pluribusnetworks com
Reviewed by:	neel
Reported by:	many
This commit is contained in:
Peter Grehan 2013-06-28 06:05:33 +00:00
parent cb754f614f
commit 560d5eda2c

View File

@ -45,7 +45,9 @@ __FBSDID("$FreeBSD$");
#define CPUID_VM_HIGH 0x40000000
static const char bhyve_id[12] = "BHyVE BHyVE ";
static const char bhyve_id[12] = "bhyve bhyve ";
static uint64_t bhyve_xcpuids;
int
x86_emulate_cpuid(struct vm *vm, int vcpu_id,
@ -77,15 +79,13 @@ x86_emulate_cpuid(struct vm *vm, int vcpu_id,
* no multi-core or SMT.
*/
switch (func) {
/*
* Pass these through to the guest
*/
case CPUID_0000_0000:
case CPUID_0000_0002:
case CPUID_0000_0003:
case CPUID_0000_000A:
cpuid_count(*eax, *ecx, regs);
break;
case CPUID_8000_0000:
case CPUID_8000_0001:
case CPUID_8000_0002:
case CPUID_8000_0003:
case CPUID_8000_0004:
@ -94,6 +94,15 @@ x86_emulate_cpuid(struct vm *vm, int vcpu_id,
cpuid_count(*eax, *ecx, regs);
break;
case CPUID_8000_0001:
/*
* Hide rdtscp/ia32_tsc_aux until we know how
* to deal with them.
*/
cpuid_count(*eax, *ecx, regs);
regs[3] &= ~AMDID_RDTSCP;
break;
case CPUID_8000_0007:
cpuid_count(*eax, *ecx, regs);
/*
@ -150,6 +159,11 @@ x86_emulate_cpuid(struct vm *vm, int vcpu_id,
*/
regs[2] &= ~CPUID2_MON;
/*
* Hide the performance and debug features.
*/
regs[2] &= ~CPUID2_PDCM;
/*
* Hide thermal monitoring
*/
@ -161,6 +175,11 @@ x86_emulate_cpuid(struct vm *vm, int vcpu_id,
*/
regs[3] &= ~(CPUID_MCA | CPUID_MCE | CPUID_MTRR);
/*
* Hide the debug store capability.
*/
regs[3] &= ~CPUID_DS;
/*
* Disable multi-core.
*/
@ -180,6 +199,7 @@ x86_emulate_cpuid(struct vm *vm, int vcpu_id,
case CPUID_0000_0006:
case CPUID_0000_0007:
case CPUID_0000_000A:
/*
* Handle the access, but report 0 for
* all options
@ -203,17 +223,25 @@ x86_emulate_cpuid(struct vm *vm, int vcpu_id,
case 0x40000000:
regs[0] = CPUID_VM_HIGH;
bcopy(bhyve_id, &regs[1], 4);
bcopy(bhyve_id, &regs[2], 4);
bcopy(bhyve_id, &regs[3], 4);
bcopy(bhyve_id + 4, &regs[2], 4);
bcopy(bhyve_id + 8, &regs[3], 4);
break;
default:
/* XXX: Leaf 5? */
return (0);
/*
* The leaf value has already been clamped so
* simply pass this through, keeping count of
* how many unhandled leaf values have been seen.
*/
atomic_add_long(&bhyve_xcpuids, 1);
cpuid_count(*eax, *ecx, regs);
break;
}
*eax = regs[0];
*ebx = regs[1];
*ecx = regs[2];
*edx = regs[3];
return (1);
}