Date: Fri, 21 Sep 2012 03:09:24 +0000 (UTC) From: Neel Natu <neel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r240772 - in projects/bhyve/sys/amd64/vmm: . io Message-ID: <201209210309.q8L39O7c045473@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: neel Date: Fri Sep 21 03:09:23 2012 New Revision: 240772 URL: http://svn.freebsd.org/changeset/base/240772 Log: Restructure the x2apic access code in preparation for supporting memory mapped access to the local apic. The vlapic code is now aware of the mode that the guest is using to access the local apic. Reviewed by: grehan@ Modified: projects/bhyve/sys/amd64/vmm/io/vlapic.c projects/bhyve/sys/amd64/vmm/io/vlapic.h projects/bhyve/sys/amd64/vmm/vmm_lapic.c projects/bhyve/sys/amd64/vmm/vmm_lapic.h projects/bhyve/sys/amd64/vmm/vmm_msr.c Modified: projects/bhyve/sys/amd64/vmm/io/vlapic.c ============================================================================== --- projects/bhyve/sys/amd64/vmm/io/vlapic.c Fri Sep 21 03:07:34 2012 (r240771) +++ projects/bhyve/sys/amd64/vmm/io/vlapic.c Fri Sep 21 03:09:23 2012 (r240772) @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include <sys/smp.h> #include <machine/clock.h> +#include <x86/specialreg.h> #include <x86/apicreg.h> #include <machine/vmm.h> @@ -86,6 +87,8 @@ static MALLOC_DEFINE(M_VLAPIC, "vlapic", #define VLAPIC_VERSION (16) #define VLAPIC_MAXLVT_ENTRIES (5) +#define x2apic(vlapic) ((vlapic)->msr_apicbase & APICBASE_X2APIC) + struct vlapic { struct vm *vm; int vcpuid; @@ -107,6 +110,8 @@ struct vlapic { */ uint8_t isrvec_stk[ISRVEC_STK_SIZE]; int isrvec_stk_top; + + uint64_t msr_apicbase; }; static void @@ -161,7 +166,6 @@ vlapic_op_reset(void* dev) struct LAPIC *lapic = &vlapic->apic; memset(lapic, 0, sizeof(*lapic)); - lapic->id = vlapic->vcpuid << 24; lapic->apr = vlapic->vcpuid; vlapic_init_ipi(vlapic); @@ -542,7 +546,10 @@ vlapic_op_mem_read(void* dev, uint64_t g switch(offset) { case APIC_OFFSET_ID: - *data = lapic->id; + if (x2apic(vlapic)) + *data = vlapic->vcpuid; + else + *data = vlapic->vcpuid << 24; break; case APIC_OFFSET_VER: *data = lapic->version; @@ -631,7 +638,6 @@ vlapic_op_mem_write(void* dev, uint64_t switch(offset) { case APIC_OFFSET_ID: - lapic->id = data; break; case APIC_OFFSET_TPR: lapic->tpr = data & 0xff; @@ -760,6 +766,14 @@ vlapic_init(struct vm *vm, int vcpuid) vlapic = malloc(sizeof(struct vlapic), M_VLAPIC, M_WAITOK | M_ZERO); vlapic->vm = vm; vlapic->vcpuid = vcpuid; + + vlapic->msr_apicbase = DEFAULT_APIC_BASE | + APICBASE_ENABLED | + APICBASE_X2APIC; + + if (vcpuid == 0) + vlapic->msr_apicbase |= APICBASE_BSP; + vlapic->ops = &vlapic_dev_ops; vlapic->mmio = vlapic_mmio + vcpuid; @@ -782,3 +796,17 @@ vlapic_cleanup(struct vlapic *vlapic) vdev_unregister(vlapic); free(vlapic, M_VLAPIC); } + +uint64_t +vlapic_get_apicbase(struct vlapic *vlapic) +{ + + return (vlapic->msr_apicbase); +} + +void +vlapic_set_apicbase(struct vlapic *vlapic, uint64_t val) +{ + + vlapic->msr_apicbase = val; +} Modified: projects/bhyve/sys/amd64/vmm/io/vlapic.h ============================================================================== --- projects/bhyve/sys/amd64/vmm/io/vlapic.h Fri Sep 21 03:07:34 2012 (r240771) +++ projects/bhyve/sys/amd64/vmm/io/vlapic.h Fri Sep 21 03:09:23 2012 (r240772) @@ -102,4 +102,7 @@ void vlapic_intr_accepted(struct vlapic void vlapic_set_intr_ready(struct vlapic *vlapic, int vector); void vlapic_timer_tick(struct vlapic *vlapic); +uint64_t vlapic_get_apicbase(struct vlapic *vlapic); +void vlapic_set_apicbase(struct vlapic *vlapic, uint64_t val); + #endif /* _VLAPIC_H_ */ Modified: projects/bhyve/sys/amd64/vmm/vmm_lapic.c ============================================================================== --- projects/bhyve/sys/amd64/vmm/vmm_lapic.c Fri Sep 21 03:07:34 2012 (r240771) +++ projects/bhyve/sys/amd64/vmm/vmm_lapic.c Fri Sep 21 03:09:23 2012 (r240772) @@ -33,20 +33,18 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <sys/smp.h> +#include <x86/specialreg.h> + #include <machine/vmm.h> #include "vmm_ipi.h" #include "vmm_lapic.h" #include "vlapic.h" -int -lapic_write(struct vm *vm, int cpu, u_int offset, uint64_t val) +static int +lapic_write(struct vlapic *vlapic, u_int offset, uint64_t val) { int handled; - struct vlapic *vlapic; - - vlapic = vm_lapic(vm, cpu); - if (vlapic_op_mem_write(vlapic, offset, DWORD, val) == 0) handled = 1; else @@ -55,15 +53,11 @@ lapic_write(struct vm *vm, int cpu, u_in return (handled); } -int -lapic_read(struct vm *vm, int cpu, u_int offset, uint64_t *rv) +static int +lapic_read(struct vlapic *vlapic, u_int offset, uint64_t *rv) { int handled; - struct vlapic *vlapic; - - vlapic = vm_lapic(vm, cpu); - if (vlapic_op_mem_read(vlapic, offset, DWORD, rv) == 0) handled = 1; else @@ -120,3 +114,63 @@ lapic_timer_tick(struct vm *vm, int cpu) vlapic_timer_tick(vlapic); } + +static boolean_t +x2apic_msr(u_int msr) +{ + if (msr >= 0x800 && msr <= 0xBFF) + return (TRUE); + else + return (FALSE); +} + +static u_int +x2apic_msr_to_regoff(u_int msr) +{ + + return ((msr - 0x800) << 4); +} + +boolean_t +lapic_msr(u_int msr) +{ + + if (x2apic_msr(msr) || (msr == MSR_APICBASE)) + return (TRUE); + else + return (FALSE); +} + +int +lapic_rdmsr(struct vm *vm, int cpu, u_int msr, uint64_t *rval) +{ + int handled; + struct vlapic *vlapic; + + vlapic = vm_lapic(vm, cpu); + + if (msr == MSR_APICBASE) { + *rval = vlapic_get_apicbase(vlapic); + handled = 1; + } else + handled = lapic_read(vlapic, x2apic_msr_to_regoff(msr), rval); + + return (handled); +} + +int +lapic_wrmsr(struct vm *vm, int cpu, u_int msr, uint64_t val) +{ + int handled; + struct vlapic *vlapic; + + vlapic = vm_lapic(vm, cpu); + + if (msr == MSR_APICBASE) { + vlapic_set_apicbase(vlapic, val); + handled = 1; + } else + handled = lapic_write(vlapic, x2apic_msr_to_regoff(msr), val); + + return (handled); +} Modified: projects/bhyve/sys/amd64/vmm/vmm_lapic.h ============================================================================== --- projects/bhyve/sys/amd64/vmm/vmm_lapic.h Fri Sep 21 03:07:34 2012 (r240771) +++ projects/bhyve/sys/amd64/vmm/vmm_lapic.h Fri Sep 21 03:09:23 2012 (r240772) @@ -31,8 +31,10 @@ struct vm; -int lapic_write(struct vm *vm, int cpu, u_int offset, uint64_t val); -int lapic_read(struct vm *vm, int cpu, u_int offset, uint64_t *retval); +boolean_t lapic_msr(u_int num); +int lapic_rdmsr(struct vm *vm, int cpu, u_int msr, uint64_t *rval); +int lapic_wrmsr(struct vm *vm, int cpu, u_int msr, uint64_t wval); + void lapic_timer_tick(struct vm *vm, int cpu); /* Modified: projects/bhyve/sys/amd64/vmm/vmm_msr.c ============================================================================== --- projects/bhyve/sys/amd64/vmm/vmm_msr.c Fri Sep 21 03:07:34 2012 (r240771) +++ projects/bhyve/sys/amd64/vmm/vmm_msr.c Fri Sep 21 03:09:23 2012 (r240772) @@ -34,7 +34,6 @@ __FBSDID("$FreeBSD$"); #include <sys/smp.h> #include <machine/specialreg.h> -#include <x86/apicreg.h> #include <machine/vmm.h> #include "vmm_lapic.h" @@ -56,7 +55,6 @@ static struct vmm_msr vmm_msr[] = { { MSR_STAR, 0 }, { MSR_SF_MASK, 0 }, { MSR_PAT, VMM_MSR_F_EMULATE | VMM_MSR_F_INVALID }, - { MSR_APICBASE, VMM_MSR_F_EMULATE }, { MSR_BIOS_SIGN,VMM_MSR_F_EMULATE }, { MSR_MCG_CAP, VMM_MSR_F_EMULATE | VMM_MSR_F_READONLY }, }; @@ -107,12 +105,6 @@ guest_msrs_init(struct vm *vm, int cpu) case MSR_MCG_CAP: guest_msrs[i] = 0; break; - case MSR_APICBASE: - guest_msrs[i] = DEFAULT_APIC_BASE | APICBASE_ENABLED | - APICBASE_X2APIC; - if (cpu == 0) - guest_msrs[i] |= APICBASE_BSP; - break; case MSR_PAT: guest_msrs[i] = PAT_VALUE(0, PAT_WRITE_BACK) | PAT_VALUE(1, PAT_WRITE_THROUGH) | @@ -130,29 +122,6 @@ guest_msrs_init(struct vm *vm, int cpu) } } -static boolean_t -x2apic_msr(u_int num) -{ - - if (num >= 0x800 && num <= 0xBFF) - return (TRUE); - else - return (FALSE); -} - -static u_int -x2apic_msr_to_regoff(u_int msr) -{ - - return ((msr - 0x800) << 4); -} - -static boolean_t -x2apic_msr_id(u_int num) -{ - return (num == 0x802); -} - static int msr_num_to_idx(u_int num) { @@ -173,8 +142,8 @@ emulate_wrmsr(struct vm *vm, int cpu, u_ handled = 0; - if (x2apic_msr(num)) - return (lapic_write(vm, cpu, x2apic_msr_to_regoff(num), val)); + if (lapic_msr(num)) + return (lapic_wrmsr(vm, cpu, num, val)); idx = msr_num_to_idx(num); if (idx < 0) @@ -208,15 +177,8 @@ emulate_rdmsr(struct vm *vm, int cpu, u_ handled = 0; - if (x2apic_msr(num)) { - handled = lapic_read(vm, cpu, x2apic_msr_to_regoff(num), - &result); - /* - * The version ID needs to be massaged - */ - if (x2apic_msr_id(num)) { - result = result >> 24; - } + if (lapic_msr(num)) { + handled = lapic_rdmsr(vm, cpu, num, &result); goto done; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201209210309.q8L39O7c045473>