aboutsummaryrefslogtreecommitdiff
path: root/sys/amd64
diff options
context:
space:
mode:
authorPeter Grehan <grehan@FreeBSD.org>2013-06-28 06:05:33 +0000
committerPeter Grehan <grehan@FreeBSD.org>2013-06-28 06:05:33 +0000
commit560d5eda2cb0861d11dd055fc63199e21116f6e5 (patch)
tree6f386a48dbb4ef8901420ea3365d5a8f8a5bd210 /sys/amd64
parentcb754f614f3c26a0435289d378ad7df4d7abbefe (diff)
downloadsrc-560d5eda2cb0861d11dd055fc63199e21116f6e5.tar.gz
src-560d5eda2cb0861d11dd055fc63199e21116f6e5.zip
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
Notes
Notes: svn path=/head/; revision=252335
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/vmm/x86.c48
1 files changed, 38 insertions, 10 deletions
diff --git a/sys/amd64/vmm/x86.c b/sys/amd64/vmm/x86.c
index fa2eabc51940..262efbd898ce 100644
--- a/sys/amd64/vmm/x86.c
+++ b/sys/amd64/vmm/x86.c
@@ -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);
}