(xen) - remove the (*xpq_cpu)() shim.We hasten the %fs/%gs setup process during boot.Although this is hacky, it lets us use the non-xen specificpmap_pte_xxx() functions in pmap code (and others). trunk
authorcherry <cherry@NetBSD.org>
Fri, 24 Feb 2012 08:06:07 +0000
branchtrunk
changeset 209445 a16d59444d1a
parent 209444 6345085a3c6e
child 209446 667d60059909
(xen) - remove the (*xpq_cpu)() shim.We hasten the %fs/%gs setup process during boot.Although this is hacky, it lets us use the non-xen specificpmap_pte_xxx() functions in pmap code (and others).
sys/arch/amd64/amd64/locore.S
sys/arch/i386/i386/gdt.c
sys/arch/i386/i386/locore.S
sys/arch/i386/i386/machdep.c
sys/arch/xen/x86/cpu.c
sys/arch/xen/x86/x86_xpmap.c
sys/arch/xen/x86/xen_pmap.c
--- a/sys/arch/amd64/amd64/locore.S	Fri Feb 24 06:48:23 2012 +0000
+++ b/sys/arch/amd64/amd64/locore.S	Fri Feb 24 08:06:07 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore.S,v 1.66 2011/12/04 16:24:13 chs Exp $	*/
+/*	$NetBSD: locore.S,v 1.67 2012/02/24 08:06:07 cherry Exp $	*/
 
 /*
  * Copyright-o-rama!
@@ -778,6 +778,11 @@
 	cpuid
 	movl	%eax,_C_LABEL(cpuid_level)
 
+	movq	$cpu_info_primary, %rdi
+	movq	%rdi, CPU_INFO_SELF(%rdi) /* ci->ci_self = ci */
+	movq	$1, %rsi
+	call	cpu_init_msrs	/* cpu_init_msrs(ci, true); */
+
 	call	xen_pmap_bootstrap
 
 	/*
--- a/sys/arch/i386/i386/gdt.c	Fri Feb 24 06:48:23 2012 +0000
+++ b/sys/arch/i386/i386/gdt.c	Fri Feb 24 08:06:07 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: gdt.c,v 1.52 2011/11/06 11:40:46 cherry Exp $	*/
+/*	$NetBSD: gdt.c,v 1.53 2012/02/24 08:06:07 cherry Exp $	*/
 
 /*-
  * Copyright (c) 1996, 1997, 2009 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.52 2011/11/06 11:40:46 cherry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.53 2012/02/24 08:06:07 cherry Exp $");
 
 #include "opt_multiprocessor.h"
 #include "opt_xen.h"
@@ -214,9 +214,10 @@
 		    * properly yet, ie; curcpu() won't work at this
 		    * point and spl() will break.
 		    */
-		   xpq_queue_pte_update(xpmap_ptetomach(ptp),
-					*ptp & ~PG_RW);
-		   xpq_flush_queue();
+			if (HYPERVISOR_update_va_mapping((vaddr_t)va,
+				*ptp & ~PG_RW, UVMF_INVLPG) < 0) {
+				panic("%s page RO update failed.\n", __func__);
+			}
 		}
 	}
 
--- a/sys/arch/i386/i386/locore.S	Fri Feb 24 06:48:23 2012 +0000
+++ b/sys/arch/i386/i386/locore.S	Fri Feb 24 08:06:07 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore.S,v 1.95 2011/03/18 15:18:16 joerg Exp $	*/
+/*	$NetBSD: locore.S,v 1.96 2012/02/24 08:06:07 cherry Exp $	*/
 
 /*
  * Copyright-o-rama!
@@ -129,7 +129,7 @@
  */
 
 #include <machine/asm.h>
-__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.95 2011/03/18 15:18:16 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.96 2012/02/24 08:06:07 cherry Exp $");
 
 #include "opt_compat_oldboot.h"
 #include "opt_ddb.h"
@@ -238,7 +238,12 @@
 
 	.space 512
 tmpstk:
-
+#ifdef XEN
+	.align 		PAGE_SIZE, 0x0	# Align on page boundary
+_C_LABEL(tmpgdt):
+	.space 		PAGE_SIZE	# Xen expects a page
+#endif /* XEN */
+	.globl tmpgdt
 #ifndef XEN
 #define	_RELOC(x)	((x) - KERNBASE)
 #else
@@ -787,6 +792,15 @@
 	cpuid
 	movl	%eax,RELOC(cpuid_level)
 
+	/*
+	 * Use a temp page. We'll re- add it to uvm(9) once we're
+	 * done using it.
+	 */
+	movl	$RELOC(tmpgdt), %eax
+	pushl	%eax		# start of temporary gdt
+	call	_C_LABEL(initgdt)
+	addl	$4,%esp
+
 	call	xen_pmap_bootstrap
 
 	/*
--- a/sys/arch/i386/i386/machdep.c	Fri Feb 24 06:48:23 2012 +0000
+++ b/sys/arch/i386/i386/machdep.c	Fri Feb 24 08:06:07 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: machdep.c,v 1.720 2012/02/23 14:45:55 chs Exp $	*/
+/*	$NetBSD: machdep.c,v 1.721 2012/02/24 08:06:07 cherry Exp $	*/
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 2000, 2004, 2006, 2008, 2009
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.720 2012/02/23 14:45:55 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.721 2012/02/24 08:06:07 cherry Exp $");
 
 #include "opt_beep.h"
 #include "opt_compat_ibcs2.h"
@@ -525,9 +525,6 @@
 }
 
 #ifdef XEN
-/* Shim for curcpu() until %fs is ready */
-extern struct cpu_info	* (*xpq_cpu)(void);
-
 /*
  * Switch context:
  * - honor CR0_TS in saved CR0 and request DNA exception on FPU use
@@ -554,12 +551,6 @@
 	update_descriptor(&ci->ci_gdt[GUGS_SEL], 
 			  (union descriptor *) &pcb->pcb_gsd);
 
-	/* setup curcpu() to use %fs now */
-	/* XXX: find a way to do this, just once */
-	if (__predict_false(xpq_cpu != x86_curcpu)) {
-		xpq_cpu = x86_curcpu;
-	}
-
 	physop.cmd = PHYSDEVOP_SET_IOPL;
 	physop.u.set_iopl.iopl = pcb->pcb_iopl;
 	HYPERVISOR_physdev_op(&physop);
@@ -1077,6 +1068,7 @@
 #define MAX_XEN_IDT 128
 trap_info_t xen_idt[MAX_XEN_IDT];
 int xen_idt_idx;
+extern union descriptor tmpgdt[];
 #endif
 
 void cpu_init_idt(void)
@@ -1095,11 +1087,13 @@
 void
 initgdt(union descriptor *tgdt)
 {
+	KASSERT(tgdt != NULL);
+	
+	gdt = tgdt;
 #ifdef XEN
 	u_long	frames[16];
 #else
 	struct region_descriptor region;
-	gdt = tgdt;
 	memset(gdt, 0, NGDT*sizeof(*gdt));
 #endif /* XEN */
 	/* make gdt gates and memory segments */
@@ -1125,6 +1119,14 @@
 	setregion(&region, gdt, NGDT * sizeof(gdt[0]) - 1);
 	lgdt(&region);
 #else /* !XEN */
+	/*
+	 * We jumpstart the bootstrap process a bit so we can update
+	 * page permissions. This is done redundantly later from
+	 * x86_xpmap.c:xen_pmap_bootstrap() - harmless.
+	 */
+	xpmap_phys_to_machine_mapping =
+	    (unsigned long *)xen_start_info.mfn_list;
+
 	frames[0] = xpmap_ptom((uint32_t)gdt - KERNBASE) >> PAGE_SHIFT;
 	{	/*
 		 * Enter the gdt page RO into the kernel map. We can't
@@ -1133,27 +1135,25 @@
 		 * the base pointer for curcpu() and curlwp(), both of
 		 * which are in the callpath of pmap_kenter_pa().
 		 * So we mash up our own - this is MD code anyway.
-		 *
-		 * XXX: review this once we have finegrained locking
-		 * for xpq.
 		 */
-		pt_entry_t *pte, npte;
+		pt_entry_t pte;
 		pt_entry_t pg_nx = (cpu_feature[2] & CPUID_NOX ? PG_NX : 0);
 
-		pte = kvtopte((vaddr_t)gdt);
-		npte = pmap_pa2pte((vaddr_t)gdt - KERNBASE);
-		npte |= PG_RO | pg_nx | PG_V;
+		pte = pmap_pa2pte((vaddr_t)gdt - KERNBASE);
+		pte |= PG_k | PG_RO | pg_nx | PG_V;
 
-		xpq_queue_pte_update(xpmap_ptetomach(pte), npte);
-		xpq_flush_queue();
+		if (HYPERVISOR_update_va_mapping((vaddr_t)gdt, pte, UVMF_INVLPG) < 0) {
+			panic("gdt page RO update failed.\n");
+		}
+
 	}
 
 	XENPRINTK(("loading gdt %lx, %d entries\n", frames[0] << PAGE_SHIFT,
 	    NGDT));
 	if (HYPERVISOR_set_gdt(frames, NGDT /* XXX is it right ? */))
 		panic("HYPERVISOR_set_gdt failed!\n");
+
 	lgdt_finish();
-
 #endif /* !XEN */
 }
 
@@ -1364,7 +1364,8 @@
 	 * initialised. initgdt() uses pmap_kenter_pa so it can't be called
 	 * before the above variables are set.
 	 */
-	initgdt(NULL);
+
+	initgdt(gdt);
 
 	mutex_init(&pte_lock, MUTEX_DEFAULT, IPL_VM);
 #endif /* XEN */
@@ -1411,6 +1412,24 @@
 	uvm_page_physload(atop(avail_start), atop(avail_end),
 	    atop(avail_start), atop(avail_end),
 	    VM_FREELIST_DEFAULT);
+
+	/* Reclaim the boot gdt page - see locore.s */
+	{
+		pt_entry_t pte;
+		pt_entry_t pg_nx = (cpu_feature[2] & CPUID_NOX ? PG_NX : 0);
+
+		pte = pmap_pa2pte((vaddr_t)tmpgdt - KERNBASE);
+		pte |= PG_k | PG_RW | pg_nx | PG_V;
+
+		if (HYPERVISOR_update_va_mapping((vaddr_t)tmpgdt, pte, UVMF_INVLPG) < 0) {
+			panic("tmpgdt page relaim RW update failed.\n");
+		}
+	}
+
+	uvm_page_physload(atop((vaddr_t)tmpgdt), atop((vaddr_t)tmpgdt + PAGE_SIZE),
+	    atop((vaddr_t)tmpgdt), atop((vaddr_t)tmpgdt + PAGE_SIZE),
+	    VM_FREELIST_DEFAULT);
+
 #endif /* !XEN */
 
 	init386_msgbuf();
--- a/sys/arch/xen/x86/cpu.c	Fri Feb 24 06:48:23 2012 +0000
+++ b/sys/arch/xen/x86/cpu.c	Fri Feb 24 08:06:07 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.c,v 1.85 2012/02/23 07:30:30 cherry Exp $	*/
+/*	$NetBSD: cpu.c,v 1.86 2012/02/24 08:06:07 cherry Exp $	*/
 /* NetBSD: cpu.c,v 1.18 2004/02/20 17:35:01 yamt Exp  */
 
 /*-
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.85 2012/02/23 07:30:30 cherry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.86 2012/02/24 08:06:07 cherry Exp $");
 
 #include "opt_ddb.h"
 #include "opt_multiprocessor.h"
@@ -1057,14 +1057,6 @@
 
 }
 
-/* curcpu() uses %fs - shim for until cpu_init_msrs(), below */
-static struct cpu_info *cpu_primary(void)
-{
-	return &cpu_info_primary;
-}
-/* XXX: rename to something more generic. users other than xpq exist */
-struct cpu_info	* (*xpq_cpu)(void) = cpu_primary;
-
 void
 cpu_init_msrs(struct cpu_info *ci, bool full)
 {
@@ -1073,7 +1065,6 @@
 		HYPERVISOR_set_segment_base (SEGBASE_FS, 0);
 		HYPERVISOR_set_segment_base (SEGBASE_GS_KERNEL, (uint64_t) ci);
 		HYPERVISOR_set_segment_base (SEGBASE_GS_USER, 0);
-		xpq_cpu = x86_curcpu;
 	}
 #endif	/* __x86_64__ */
 
--- a/sys/arch/xen/x86/x86_xpmap.c	Fri Feb 24 06:48:23 2012 +0000
+++ b/sys/arch/xen/x86/x86_xpmap.c	Fri Feb 24 08:06:07 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: x86_xpmap.c,v 1.40 2012/02/23 18:59:21 bouyer Exp $	*/
+/*	$NetBSD: x86_xpmap.c,v 1.41 2012/02/24 08:06:08 cherry Exp $	*/
 
 /*
  * Copyright (c) 2006 Mathieu Ropert <mro@adviseo.fr>
@@ -69,7 +69,7 @@
 
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: x86_xpmap.c,v 1.40 2012/02/23 18:59:21 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: x86_xpmap.c,v 1.41 2012/02/24 08:06:08 cherry Exp $");
 
 #include "opt_xen.h"
 #include "opt_ddb.h"
@@ -166,15 +166,16 @@
 static mmu_update_t xpq_queue_array[MAXCPUS][XPQUEUE_SIZE];
 static int xpq_idx_array[MAXCPUS];
 
-extern struct cpu_info * (*xpq_cpu)(void);
-
+#ifdef i386
+extern union descriptor tmpgdt[];
+#endif /* i386 */
 void
 xpq_flush_queue(void)
 {
 	int i, ok = 0, ret;
 
-	mmu_update_t *xpq_queue = xpq_queue_array[xpq_cpu()->ci_cpuid];
-	int xpq_idx = xpq_idx_array[xpq_cpu()->ci_cpuid];
+	mmu_update_t *xpq_queue = xpq_queue_array[curcpu()->ci_cpuid];
+	int xpq_idx = xpq_idx_array[curcpu()->ci_cpuid];
 
 	XENPRINTK2(("flush queue %p entries %d\n", xpq_queue, xpq_idx));
 	for (i = 0; i < xpq_idx; i++)
@@ -190,7 +191,7 @@
 
 		printf("xpq_flush_queue: %d entries (%d successful) on "
 		    "cpu%d (%ld)\n",
-		    xpq_idx, ok, xpq_cpu()->ci_index, xpq_cpu()->ci_cpuid);
+		    xpq_idx, ok, curcpu()->ci_index, curcpu()->ci_cpuid);
 
 		if (ok != 0) {
 			xpq_queue += ok;
@@ -218,14 +219,14 @@
 		}
 		panic("HYPERVISOR_mmu_update failed, ret: %d\n", ret);
 	}
-	xpq_idx_array[xpq_cpu()->ci_cpuid] = 0;
+	xpq_idx_array[curcpu()->ci_cpuid] = 0;
 }
 
 static inline void
 xpq_increment_idx(void)
 {
 
-	if (__predict_false(++xpq_idx_array[xpq_cpu()->ci_cpuid] == XPQUEUE_SIZE))
+	if (__predict_false(++xpq_idx_array[curcpu()->ci_cpuid] == XPQUEUE_SIZE))
 		xpq_flush_queue();
 }
 
@@ -233,8 +234,8 @@
 xpq_queue_machphys_update(paddr_t ma, paddr_t pa)
 {
 
-	mmu_update_t *xpq_queue = xpq_queue_array[xpq_cpu()->ci_cpuid];
-	int xpq_idx = xpq_idx_array[xpq_cpu()->ci_cpuid];
+	mmu_update_t *xpq_queue = xpq_queue_array[curcpu()->ci_cpuid];
+	int xpq_idx = xpq_idx_array[curcpu()->ci_cpuid];
 
 	XENPRINTK2(("xpq_queue_machphys_update ma=0x%" PRIx64 " pa=0x%" PRIx64
 	    "\n", (int64_t)ma, (int64_t)pa));
@@ -251,8 +252,8 @@
 xpq_queue_pte_update(paddr_t ptr, pt_entry_t val)
 {
 
-	mmu_update_t *xpq_queue = xpq_queue_array[xpq_cpu()->ci_cpuid];
-	int xpq_idx = xpq_idx_array[xpq_cpu()->ci_cpuid];
+	mmu_update_t *xpq_queue = xpq_queue_array[curcpu()->ci_cpuid];
+	int xpq_idx = xpq_idx_array[curcpu()->ci_cpuid];
 
 	KASSERT((ptr & 3) == 0);
 	xpq_queue[xpq_idx].ptr = (paddr_t)ptr | MMU_NORMAL_PT_UPDATE;
@@ -501,8 +502,8 @@
 {
 	int i;
 
-	mmu_update_t *xpq_queue = xpq_queue_array[xpq_cpu()->ci_cpuid];
-	int xpq_idx = xpq_idx_array[xpq_cpu()->ci_cpuid];
+	mmu_update_t *xpq_queue = xpq_queue_array[curcpu()->ci_cpuid];
+	int xpq_idx = xpq_idx_array[curcpu()->ci_cpuid];
 
 	XENPRINTK2(("idx: %d\n", xpq_idx));
 	for (i = 0; i < xpq_idx; i++) {
@@ -878,6 +879,18 @@
 			    page < new_pgd + ((new_count + l2_4_count) * PAGE_SIZE)) {
 				/* map new page tables RO */
 				pte[pl1_pi(page)] |= 0;
+#ifdef i386
+			} else if (page == (vaddr_t)tmpgdt) {
+				/*
+				 * Map bootstrap gdt R/O. Later, we
+				 * will re-add this to page to uvm
+				 * after making it writable.
+				 */
+
+				pte[pl1_pi(page)] = 0;
+				page += PAGE_SIZE;
+				continue;
+#endif /* i386 */
 			} else {
 				/* map page RW */
 				pte[pl1_pi(page)] |= PG_RW;
--- a/sys/arch/xen/x86/xen_pmap.c	Fri Feb 24 06:48:23 2012 +0000
+++ b/sys/arch/xen/x86/xen_pmap.c	Fri Feb 24 08:06:07 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: xen_pmap.c,v 1.17 2012/02/17 18:40:20 bouyer Exp $	*/
+/*	$NetBSD: xen_pmap.c,v 1.18 2012/02/24 08:06:08 cherry Exp $	*/
 
 /*
  * Copyright (c) 2007 Manuel Bouyer.
@@ -102,7 +102,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xen_pmap.c,v 1.17 2012/02/17 18:40:20 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xen_pmap.c,v 1.18 2012/02/24 08:06:08 cherry Exp $");
 
 #include "opt_user_ldt.h"
 #include "opt_lockdebug.h"
@@ -334,7 +334,6 @@
 
 #if defined(PAE) || defined(__x86_64__)
 
-extern struct cpu_info	* (*xpq_cpu)(void);
 static __inline void
 pmap_kpm_setpte(struct cpu_info *ci, struct pmap *pmap, int index)
 {