Module Name: src Committed By: cherry Date: Wed Aug 10 06:38:02 UTC 2011
Modified Files: src/sys/arch/i386/i386: machdep.c Log Message: tweak the xen specific startup path to not use %fs before it is setup. Minor refactoring. Use Xen specific ipi calls. To generate a diff of this commit: cvs rdiff -u -r1.706 -r1.707 src/sys/arch/i386/i386/machdep.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/i386/i386/machdep.c diff -u src/sys/arch/i386/i386/machdep.c:1.706 src/sys/arch/i386/i386/machdep.c:1.707 --- src/sys/arch/i386/i386/machdep.c:1.706 Fri Jul 1 18:14:15 2011 +++ src/sys/arch/i386/i386/machdep.c Wed Aug 10 06:38:02 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.706 2011/07/01 18:14:15 dyoung Exp $ */ +/* $NetBSD: machdep.c,v 1.707 2011/08/10 06:38:02 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.706 2011/07/01 18:14:15 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.707 2011/08/10 06:38:02 cherry Exp $"); #include "opt_beep.h" #include "opt_compat_ibcs2.h" @@ -560,6 +560,12 @@ HYPERVISOR_stack_switch(GSEL(GDATA_SEL, SEL_KPL), pcb->pcb_esp0); + /* Update TLS segment pointers */ + update_descriptor(&ci->ci_gdt[GUFS_SEL], + (union descriptor *) &pcb->pcb_fsd); + update_descriptor(&ci->ci_gdt[GUGS_SEL], + (union descriptor *) &pcb->pcb_gsd); + physop.cmd = PHYSDEVOP_SET_IOPL; physop.u.set_iopl.iopl = pcb->pcb_iopl; HYPERVISOR_physdev_op(&physop); @@ -949,8 +955,12 @@ } #ifdef MULTIPROCESSOR +#ifdef XEN + xen_broadcast_ipi(XEN_IPI_HALT); +#else /* XEN */ x86_broadcast_ipi(X86_IPI_HALT); -#endif +#endif /* XEN */ +#endif /* MULTIPROCESSOR */ if (howto & RB_HALT) { #if NACPICA > 0 @@ -1123,14 +1133,18 @@ int xen_idt_idx; #endif -#ifndef XEN void cpu_init_idt(void) { +#ifndef XEN struct region_descriptor region; setregion(®ion, pentium_idt, NIDT * sizeof(idt[0]) - 1); lidt(®ion); -} +#else /* XEN */ + XENPRINTF(("HYPERVISOR_set_trap_table %p\n", xen_idt)); + if (HYPERVISOR_set_trap_table(xen_idt)) + panic("HYPERVISOR_set_trap_table %p failed\n", xen_idt); #endif /* !XEN */ +} void initgdt(union descriptor *tgdt) @@ -1166,7 +1180,28 @@ lgdt(®ion); #else /* !XEN */ frames[0] = xpmap_ptom((uint32_t)gdt - KERNBASE) >> PAGE_SHIFT; - pmap_kenter_pa((vaddr_t)gdt, (uint32_t)gdt - KERNBASE, VM_PROT_READ, 0); + { /* + * Enter the gdt page RO into the kernel map. We can't + * use pmap_kenter_pa() here, because %fs is not + * usable until the gdt is loaded, and %fs is used as + * 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 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; + + 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 ? */)) @@ -1579,10 +1614,7 @@ xen_idt[xen_idt_idx].address = (uint32_t)&IDTVEC(svr4_fasttrap); xen_idt_idx++; lldt(GSEL(GLDT_SEL, SEL_KPL)); - - XENPRINTF(("HYPERVISOR_set_trap_table %p\n", xen_idt)); - if (HYPERVISOR_set_trap_table(xen_idt)) - panic("HYPERVISOR_set_trap_table %p failed\n", xen_idt); + cpu_init_idt(); #endif /* XEN */ init386_ksyms();