svn commit: r240772 - in projects/bhyve/sys/amd64/vmm: . io

Neel Natu neel at FreeBSD.org
Fri Sep 21 03:09:24 UTC 2012


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;
 	}
 


More information about the svn-src-projects mailing list