Module Name: src Committed By: cherry Date: Fri Feb 24 08:06:08 UTC 2012
Modified Files: src/sys/arch/amd64/amd64: locore.S src/sys/arch/i386/i386: gdt.c locore.S machdep.c src/sys/arch/xen/x86: cpu.c x86_xpmap.c xen_pmap.c Log Message: (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). To generate a diff of this commit: cvs rdiff -u -r1.66 -r1.67 src/sys/arch/amd64/amd64/locore.S cvs rdiff -u -r1.52 -r1.53 src/sys/arch/i386/i386/gdt.c cvs rdiff -u -r1.95 -r1.96 src/sys/arch/i386/i386/locore.S cvs rdiff -u -r1.720 -r1.721 src/sys/arch/i386/i386/machdep.c cvs rdiff -u -r1.85 -r1.86 src/sys/arch/xen/x86/cpu.c cvs rdiff -u -r1.40 -r1.41 src/sys/arch/xen/x86/x86_xpmap.c cvs rdiff -u -r1.17 -r1.18 src/sys/arch/xen/x86/xen_pmap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.66 src/sys/arch/amd64/amd64/locore.S:1.67 --- src/sys/arch/amd64/amd64/locore.S:1.66 Sun Dec 4 16:24:13 2011 +++ src/sys/arch/amd64/amd64/locore.S Fri Feb 24 08:06:07 2012 @@ -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 @@ start: 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 /* Index: src/sys/arch/i386/i386/gdt.c diff -u src/sys/arch/i386/i386/gdt.c:1.52 src/sys/arch/i386/i386/gdt.c:1.53 --- src/sys/arch/i386/i386/gdt.c:1.52 Sun Nov 6 11:40:46 2011 +++ src/sys/arch/i386/i386/gdt.c Fri Feb 24 08:06:07 2012 @@ -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 @@ gdt_init_cpu(struct cpu_info *ci) * 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__); + } } } Index: src/sys/arch/i386/i386/locore.S diff -u src/sys/arch/i386/i386/locore.S:1.95 src/sys/arch/i386/i386/locore.S:1.96 --- src/sys/arch/i386/i386/locore.S:1.95 Fri Mar 18 15:18:16 2011 +++ src/sys/arch/i386/i386/locore.S Fri Feb 24 08:06:07 2012 @@ -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 @@ _C_LABEL(tablesize): .long 0 .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 @@ start: 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 /* Index: src/sys/arch/i386/i386/machdep.c diff -u src/sys/arch/i386/i386/machdep.c:1.720 src/sys/arch/i386/i386/machdep.c:1.721 --- src/sys/arch/i386/i386/machdep.c:1.720 Thu Feb 23 14:45:55 2012 +++ src/sys/arch/i386/i386/machdep.c Fri Feb 24 08:06:07 2012 @@ -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 @@ i386_proc0_tss_ldt_init(void) } #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 @@ i386_switch_context(lwp_t *l) 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 @@ krwlock_t svr4_fasttrap_lock; #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 cpu_init_idt(void) 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 @@ initgdt(union descriptor *tgdt) setregion(®ion, gdt, NGDT * sizeof(gdt[0]) - 1); lgdt(®ion); #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 @@ initgdt(union descriptor *tgdt) * 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; + + if (HYPERVISOR_update_va_mapping((vaddr_t)gdt, pte, UVMF_INVLPG) < 0) { + panic("gdt page RO update failed.\n"); + } - xpq_queue_pte_update(xpmap_ptetomach(pte), npte); - xpq_flush_queue(); } 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(); + lgdt_finish(); #endif /* !XEN */ } @@ -1364,7 +1364,8 @@ init386(paddr_t first_avail) * 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 @@ init386(paddr_t first_avail) 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(); Index: src/sys/arch/xen/x86/cpu.c diff -u src/sys/arch/xen/x86/cpu.c:1.85 src/sys/arch/xen/x86/cpu.c:1.86 --- src/sys/arch/xen/x86/cpu.c:1.85 Thu Feb 23 07:30:30 2012 +++ src/sys/arch/xen/x86/cpu.c Fri Feb 24 08:06:07 2012 @@ -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 @@ mp_cpu_start_cleanup(struct cpu_info *ci } -/* 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 @@ cpu_init_msrs(struct cpu_info *ci, bool 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__ */ Index: src/sys/arch/xen/x86/x86_xpmap.c diff -u src/sys/arch/xen/x86/x86_xpmap.c:1.40 src/sys/arch/xen/x86/x86_xpmap.c:1.41 --- src/sys/arch/xen/x86/x86_xpmap.c:1.40 Thu Feb 23 18:59:21 2012 +++ src/sys/arch/xen/x86/x86_xpmap.c Fri Feb 24 08:06:08 2012 @@ -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 <m...@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 @@ void xpq_debug_dump(void); 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 @@ retry: 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 @@ retry: } 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 @@ void 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 @@ void 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 @@ xpq_debug_dump(void) { 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 @@ xen_bootstrap_tables (vaddr_t old_pgd, v 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; Index: src/sys/arch/xen/x86/xen_pmap.c diff -u src/sys/arch/xen/x86/xen_pmap.c:1.17 src/sys/arch/xen/x86/xen_pmap.c:1.18 --- src/sys/arch/xen/x86/xen_pmap.c:1.17 Fri Feb 17 18:40:20 2012 +++ src/sys/arch/xen/x86/xen_pmap.c Fri Feb 24 08:06:08 2012 @@ -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 @@ pmap_unmap_recursive_entries(void) #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) {