Date: Thu, 2 Jun 2011 14:04:08 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r222610 - in projects/bhyve/sys/amd64/vmm: . intel Message-ID: <201106021404.p52E48b2020411@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Thu Jun 2 14:04:07 2011 New Revision: 222610 URL: http://svn.freebsd.org/changeset/base/222610 Log: Some tweaks to the CPUID support: - Don't always pass the cpuid request to the current CPU as some nodes we will emulate purely in software. - Pass in the APIC ID of the virtual CPU so we can return the proper APIC ID. - Always report a completely flat topology with no SMT or multicore. - Report the CPUID2_HV feature and implement support for the 0x40000000 CPUID level. - Use existing constants from <machine/specialreg.h> when possible and use cpu_feature2 when checking for VMX support. Modified: projects/bhyve/sys/amd64/vmm/intel/vmx.c projects/bhyve/sys/amd64/vmm/x86.c projects/bhyve/sys/amd64/vmm/x86.h Modified: projects/bhyve/sys/amd64/vmm/intel/vmx.c ============================================================================== --- projects/bhyve/sys/amd64/vmm/intel/vmx.c Thu Jun 2 14:03:12 2011 (r222609) +++ projects/bhyve/sys/amd64/vmm/intel/vmx.c Thu Jun 2 14:04:07 2011 (r222610) @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include <machine/psl.h> #include <machine/cpufunc.h> +#include <machine/md_var.h> #include <machine/pmap.h> #include <machine/segments.h> #include <machine/vmparam.h> @@ -418,13 +419,11 @@ static int vmx_init(void) { int error; - unsigned int regs[4]; uint64_t fixed0, fixed1; uint32_t tmp; /* CPUID.1:ECX[bit 5] must be 1 for processor to support VMX */ - do_cpuid(1, regs); - if ((regs[2] & CPUID_0000_0001_FEAT0_VMX) == 0) { + if (!(cpu_feature2 & CPUID2_VMX)) { printf("vmx_init: processor does not support VMX operation\n"); return (ENXIO); } @@ -705,7 +704,7 @@ vmx_vminit(struct vm *vm) } static int -vmx_handle_cpuid(struct vmxctx *vmxctx) +vmx_handle_cpuid(int vcpu, struct vmxctx *vmxctx) { int handled, func; @@ -713,7 +712,7 @@ vmx_handle_cpuid(struct vmxctx *vmxctx) handled = x86_emulate_cpuid((uint32_t*)(&vmxctx->guest_rax), (uint32_t*)(&vmxctx->guest_rbx), (uint32_t*)(&vmxctx->guest_rcx), - (uint32_t*)(&vmxctx->guest_rdx)); + (uint32_t*)(&vmxctx->guest_rdx), vcpu); #if 0 printf("%s: func %x rax %lx rbx %lx rcx %lx rdx %lx handled %d\n", __func__, func, vmxctx->guest_rax, vmxctx->guest_rbx, @@ -1148,7 +1147,7 @@ vmx_exit_process(struct vmx *vmx, int vc vmexit->u.inout.eax = (uint32_t)(vmxctx->guest_rax); break; case EXIT_REASON_CPUID: - handled = vmx_handle_cpuid(vmxctx); + handled = vmx_handle_cpuid(vcpu, vmxctx); break; default: break; Modified: projects/bhyve/sys/amd64/vmm/x86.c ============================================================================== --- projects/bhyve/sys/amd64/vmm/x86.c Thu Jun 2 14:03:12 2011 (r222609) +++ projects/bhyve/sys/amd64/vmm/x86.c Thu Jun 2 14:04:07 2011 (r222610) @@ -30,27 +30,51 @@ __FBSDID("$FreeBSD$"); #include <sys/types.h> +#include <sys/systm.h> #include <machine/cpufunc.h> +#include <machine/md_var.h> #include <machine/specialreg.h> #include "x86.h" +#define CPUID_VM_HIGH 0x40000000 + +static const char bhyve_id[12] = "BHyVE BHyVE "; + int -x86_emulate_cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) +x86_emulate_cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx, + uint32_t vcpu_id) { unsigned int func, regs[4]; func = *eax; - cpuid_count(*eax, *ecx, regs); + /* + * Requests for invalid CPUID levels should map to the highest + * available level instead. + */ + if (cpu_exthigh != 0 && *eax >= 0x80000000) { + if (*eax > cpu_exthigh) + *eax = cpu_exthigh; + } else if (*eax >= 0x40000000) { + if (*eax > CPUID_VM_HIGH) + *eax = CPUID_VM_HIGH; + } else if (*eax > cpu_high) { + *eax = cpu_high; + } - switch(func) { + /* + * In general the approach used for CPU topology is to + * advertise a flat topology where all CPUs are packages with + * no multi-core or SMT. + */ + switch (func) { case CPUID_0000_0000: case CPUID_0000_0002: case CPUID_0000_0003: - case CPUID_0000_0004: case CPUID_0000_000A: + cpuid_count(*eax, *ecx, regs); break; case CPUID_8000_0000: @@ -61,26 +85,24 @@ x86_emulate_cpuid(uint32_t *eax, uint32_ case CPUID_8000_0006: case CPUID_8000_0007: case CPUID_8000_0008: - + cpuid_count(*eax, *ecx, regs); break; case CPUID_0000_0001: + do_cpuid(1, regs); + /* * Override the APIC ID only in ebx */ - regs[1] &= ~(CPUID_0000_0001_APICID_MASK); - /* - * XXX fixme for MP case, set apicid properly for cpu. - */ - regs[1] |= (0 << CPUID_0000_0001_APICID_SHIFT); + regs[1] &= ~(CPUID_LOCAL_APIC_ID); + regs[1] |= (vcpu_id << CPUID_0000_0001_APICID_SHIFT); /* * Don't expose VMX, SpeedStep or TME capability. - * Advertise x2APIC capability. + * Advertise x2APIC capability and Hypervisor guest. */ - regs[2] &= ~(CPUID_0000_0001_FEAT0_VMX | CPUID2_EST | - CPUID2_TM2); - regs[2] |= CPUID2_X2APIC; + regs[2] &= ~(CPUID2_VMX | CPUID2_EST | CPUID2_TM2); + regs[2] |= CPUID2_X2APIC | CPUID2_HV; /* * Hide thermal monitoring @@ -93,6 +115,21 @@ x86_emulate_cpuid(uint32_t *eax, uint32_ */ regs[3] &= ~(CPUID_MCA | CPUID_MCE | CPUID_MTRR); + /* + * Disable multi-core. + */ + regs[1] &= ~CPUID_HTT_CORES; + regs[3] &= ~CPUID_HTT; + break; + + case CPUID_0000_0004: + do_cpuid(4, regs); + + /* + * Do not expose topology. + */ + regs[0] &= 0xffff8000; + regs[0] |= 0x04008000; break; case CPUID_0000_0006: @@ -108,16 +145,22 @@ x86_emulate_cpuid(uint32_t *eax, uint32_ case CPUID_0000_000B: /* - * XXXSMP fixme * Processor topology enumeration */ regs[0] = 0; regs[1] = 0; regs[2] = *ecx & 0xff; - regs[3] = 0; + regs[3] = vcpu_id; break; + 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); + break; default: + /* XXX: Leaf 5? */ return (0); } @@ -127,4 +170,3 @@ x86_emulate_cpuid(uint32_t *eax, uint32_ *edx = regs[3]; return (1); } - Modified: projects/bhyve/sys/amd64/vmm/x86.h ============================================================================== --- projects/bhyve/sys/amd64/vmm/x86.h Thu Jun 2 14:03:12 2011 (r222609) +++ projects/bhyve/sys/amd64/vmm/x86.h Thu Jun 2 14:04:07 2011 (r222610) @@ -58,6 +58,6 @@ #define CPUID_0000_0001_FEAT0_VMX (1<<5) int x86_emulate_cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx, - uint32_t *edx); + uint32_t *edx, uint32_t vcpu_id); #endif
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106021404.p52E48b2020411>