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:
parent
78ac9f10ca
commit
abdbf599d1
@ -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, ®s[1], 4);
|
||||
bcopy(bhyve_id, ®s[2], 4);
|
||||
bcopy(bhyve_id, ®s[3], 4);
|
||||
bcopy(bhyve_id + 4, ®s[2], 4);
|
||||
bcopy(bhyve_id + 8, ®s[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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user