Skip to content

Commit 560d5ed

Browse files
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
1 parent cb754f6 commit 560d5ed

File tree

1 file changed

+38
-10
lines changed

1 file changed

+38
-10
lines changed

sys/amd64/vmm/x86.c

+38-10
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ __FBSDID("$FreeBSD$");
4545

4646
#define CPUID_VM_HIGH 0x40000000
4747

48-
static const char bhyve_id[12] = "BHyVE BHyVE ";
48+
static const char bhyve_id[12] = "bhyve bhyve ";
49+
50+
static uint64_t bhyve_xcpuids;
4951

5052
int
5153
x86_emulate_cpuid(struct vm *vm, int vcpu_id,
@@ -77,15 +79,13 @@ x86_emulate_cpuid(struct vm *vm, int vcpu_id,
7779
* no multi-core or SMT.
7880
*/
7981
switch (func) {
82+
/*
83+
* Pass these through to the guest
84+
*/
8085
case CPUID_0000_0000:
8186
case CPUID_0000_0002:
8287
case CPUID_0000_0003:
83-
case CPUID_0000_000A:
84-
cpuid_count(*eax, *ecx, regs);
85-
break;
86-
8788
case CPUID_8000_0000:
88-
case CPUID_8000_0001:
8989
case CPUID_8000_0002:
9090
case CPUID_8000_0003:
9191
case CPUID_8000_0004:
@@ -94,6 +94,15 @@ x86_emulate_cpuid(struct vm *vm, int vcpu_id,
9494
cpuid_count(*eax, *ecx, regs);
9595
break;
9696

97+
case CPUID_8000_0001:
98+
/*
99+
* Hide rdtscp/ia32_tsc_aux until we know how
100+
* to deal with them.
101+
*/
102+
cpuid_count(*eax, *ecx, regs);
103+
regs[3] &= ~AMDID_RDTSCP;
104+
break;
105+
97106
case CPUID_8000_0007:
98107
cpuid_count(*eax, *ecx, regs);
99108
/*
@@ -150,6 +159,11 @@ x86_emulate_cpuid(struct vm *vm, int vcpu_id,
150159
*/
151160
regs[2] &= ~CPUID2_MON;
152161

162+
/*
163+
* Hide the performance and debug features.
164+
*/
165+
regs[2] &= ~CPUID2_PDCM;
166+
153167
/*
154168
* Hide thermal monitoring
155169
*/
@@ -161,6 +175,11 @@ x86_emulate_cpuid(struct vm *vm, int vcpu_id,
161175
*/
162176
regs[3] &= ~(CPUID_MCA | CPUID_MCE | CPUID_MTRR);
163177

178+
/*
179+
* Hide the debug store capability.
180+
*/
181+
regs[3] &= ~CPUID_DS;
182+
164183
/*
165184
* Disable multi-core.
166185
*/
@@ -180,6 +199,7 @@ x86_emulate_cpuid(struct vm *vm, int vcpu_id,
180199

181200
case CPUID_0000_0006:
182201
case CPUID_0000_0007:
202+
case CPUID_0000_000A:
183203
/*
184204
* Handle the access, but report 0 for
185205
* all options
@@ -203,17 +223,25 @@ x86_emulate_cpuid(struct vm *vm, int vcpu_id,
203223
case 0x40000000:
204224
regs[0] = CPUID_VM_HIGH;
205225
bcopy(bhyve_id, &regs[1], 4);
206-
bcopy(bhyve_id, &regs[2], 4);
207-
bcopy(bhyve_id, &regs[3], 4);
226+
bcopy(bhyve_id + 4, &regs[2], 4);
227+
bcopy(bhyve_id + 8, &regs[3], 4);
208228
break;
229+
209230
default:
210-
/* XXX: Leaf 5? */
211-
return (0);
231+
/*
232+
* The leaf value has already been clamped so
233+
* simply pass this through, keeping count of
234+
* how many unhandled leaf values have been seen.
235+
*/
236+
atomic_add_long(&bhyve_xcpuids, 1);
237+
cpuid_count(*eax, *ecx, regs);
238+
break;
212239
}
213240

214241
*eax = regs[0];
215242
*ebx = regs[1];
216243
*ecx = regs[2];
217244
*edx = regs[3];
245+
218246
return (1);
219247
}

0 commit comments

Comments
 (0)