svn commit: r194784 - in head/sys: amd64/amd64 arm/arm arm/at91 arm/mv arm/sa11x0 arm/xscale/i80321 arm/xscale/i8134x arm/xscale/ixp425 arm/xscale/pxa i386/i386 i386/xen ia64/ia64 kern mips/mips pc...

Jeff Roberson jeff at FreeBSD.org
Tue Jun 23 22:42:40 UTC 2009


Author: jeff
Date: Tue Jun 23 22:42:39 2009
New Revision: 194784
URL: http://svn.freebsd.org/changeset/base/194784

Log:
  Implement a facility for dynamic per-cpu variables.
   - Modules and kernel code alike may use DPCPU_DEFINE(),
     DPCPU_GET(), DPCPU_SET(), etc. akin to the statically defined
     PCPU_*.  Requires only one extra instruction more than PCPU_* and is
     virtually the same as __thread for builtin and much faster for shared
     objects.  DPCPU variables can be initialized when defined.
   - Modules are supported by relocating the module's per-cpu linker set
     over space reserved in the kernel.  Modules may fail to load if there
     is insufficient space available.
   - Track space available for modules with a one-off extent allocator.
     Free may block for memory to allocate space for an extent.
  
  Reviewed by:    jhb, rwatson, kan, sam, grehan, marius, marcel, stas

Modified:
  head/sys/amd64/amd64/machdep.c
  head/sys/amd64/amd64/mp_machdep.c
  head/sys/arm/arm/elf_machdep.c
  head/sys/arm/at91/at91_machdep.c
  head/sys/arm/mv/mv_machdep.c
  head/sys/arm/sa11x0/assabet_machdep.c
  head/sys/arm/xscale/i80321/ep80219_machdep.c
  head/sys/arm/xscale/i80321/iq31244_machdep.c
  head/sys/arm/xscale/i8134x/crb_machdep.c
  head/sys/arm/xscale/ixp425/avila_machdep.c
  head/sys/arm/xscale/pxa/pxa_machdep.c
  head/sys/i386/i386/elf_machdep.c
  head/sys/i386/i386/machdep.c
  head/sys/i386/i386/mp_machdep.c
  head/sys/i386/xen/mp_machdep.c
  head/sys/ia64/ia64/elf_machdep.c
  head/sys/ia64/ia64/machdep.c
  head/sys/ia64/ia64/mp_machdep.c
  head/sys/kern/link_elf.c
  head/sys/kern/link_elf_obj.c
  head/sys/kern/subr_pcpu.c
  head/sys/mips/mips/elf_machdep.c
  head/sys/mips/mips/mp_machdep.c
  head/sys/mips/mips/pmap.c
  head/sys/pc98/pc98/machdep.c
  head/sys/powerpc/aim/mmu_oea.c
  head/sys/powerpc/aim/mmu_oea64.c
  head/sys/powerpc/booke/pmap.c
  head/sys/powerpc/powerpc/elf_machdep.c
  head/sys/powerpc/powerpc/mp_machdep.c
  head/sys/sparc64/include/pcpu.h
  head/sys/sparc64/sparc64/elf_machdep.c
  head/sys/sparc64/sparc64/machdep.c
  head/sys/sparc64/sparc64/mp_machdep.c
  head/sys/sparc64/sparc64/pmap.c
  head/sys/sun4v/include/pcpu.h
  head/sys/sun4v/sun4v/machdep.c
  head/sys/sun4v/sun4v/mp_machdep.c
  head/sys/sun4v/sun4v/pmap.c
  head/sys/sys/linker.h
  head/sys/sys/pcpu.h
  head/sys/sys/sysctl.h

Modified: head/sys/amd64/amd64/machdep.c
==============================================================================
--- head/sys/amd64/amd64/machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/amd64/amd64/machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -1501,6 +1501,8 @@ hammer_time(u_int64_t modulep, u_int64_t
 	wrmsr(MSR_KGSBASE, 0);		/* User value while in the kernel */
 
 	pcpu_init(pc, 0, sizeof(struct pcpu));
+	dpcpu_init((void *)(physfree + KERNBASE), 0);
+	physfree += DPCPU_SIZE;
 	PCPU_SET(prvspace, pc);
 	PCPU_SET(curthread, &thread0);
 	PCPU_SET(curpcb, thread0.td_pcb);

Modified: head/sys/amd64/amd64/mp_machdep.c
==============================================================================
--- head/sys/amd64/amd64/mp_machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/amd64/amd64/mp_machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -93,9 +93,10 @@ static int bootAP;
 /* Free these after use */
 void *bootstacks[MAXCPU];
 
-/* Temporary holder for double fault stack */
+/* Temporary variables for init_secondary()  */
 char *doublefault_stack;
 char *nmi_stack;
+void *dpcpu;
 
 /* Hotwire a 0->4MB V==P mapping */
 extern pt_entry_t *KPTphys;
@@ -590,6 +591,7 @@ init_secondary(void)
 
 	/* prime data page for it to use */
 	pcpu_init(pc, cpu, sizeof(struct pcpu));
+	dpcpu_init(dpcpu, cpu);
 	pc->pc_apic_id = cpu_apic_ids[cpu];
 	pc->pc_prvspace = pc;
 	pc->pc_curthread = 0;
@@ -885,6 +887,7 @@ start_all_aps(void)
 		bootstacks[cpu] = (void *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE);
 		doublefault_stack = (char *)kmem_alloc(kernel_map, PAGE_SIZE);
 		nmi_stack = (char *)kmem_alloc(kernel_map, PAGE_SIZE);
+		dpcpu = (void *)kmem_alloc(kernel_map, DPCPU_SIZE);
 
 		bootSTK = (char *)bootstacks[cpu] + KSTACK_PAGES * PAGE_SIZE - 8;
 		bootAP = cpu;

Modified: head/sys/arm/arm/elf_machdep.c
==============================================================================
--- head/sys/arm/arm/elf_machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/arm/arm/elf_machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -149,7 +149,7 @@ elf_reloc_internal(linker_file_t lf, Elf
 
 	if (local) {
 		if (rtype == R_ARM_RELATIVE) {	/* A + B */
-			addr = relocbase + addend;
+			addr = elf_relocaddr(lf, relocbase + addend);
 			if (*where != addr)
 				*where = addr;
 		}

Modified: head/sys/arm/at91/at91_machdep.c
==============================================================================
--- head/sys/arm/at91/at91_machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/arm/at91/at91_machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -215,6 +215,7 @@ void *
 initarm(void *arg, void *arg2)
 {
 	struct pv_addr  kernel_l1pt;
+	struct pv_addr  dpcpu;
 	int loop, i;
 	u_int l1pagetable;
 	vm_offset_t freemempos;
@@ -264,6 +265,10 @@ initarm(void *arg, void *arg2)
 	 */
 	valloc_pages(systempage, 1);
 
+	/* Allocate dynamic per-cpu area. */
+	valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
+	dpcpu_init((void *)dpcpu.pv_va, 0);
+
 	/* Allocate stacks for all modes */
 	valloc_pages(irqstack, IRQ_STACK_SIZE);
 	valloc_pages(abtstack, ABT_STACK_SIZE);

Modified: head/sys/arm/mv/mv_machdep.c
==============================================================================
--- head/sys/arm/mv/mv_machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/arm/mv/mv_machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -358,6 +358,7 @@ void *
 initarm(void *mdp, void *unused __unused)
 {
 	struct pv_addr kernel_l1pt;
+	struct pv_addr dpcpu;
 	vm_offset_t freemempos, l2_start, lastaddr;
 	uint32_t memsize, l2size;
 	struct bi_mem_region *mr;
@@ -479,6 +480,10 @@ initarm(void *mdp, void *unused __unused
 	 */
 	valloc_pages(systempage, 1);
 
+	/* Allocate dynamic per-cpu area. */
+	valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
+	dpcpu_init((void *)dpcpu.pv_va, 0);
+
 	/* Allocate stacks for all modes */
 	valloc_pages(irqstack, IRQ_STACK_SIZE);
 	valloc_pages(abtstack, ABT_STACK_SIZE);

Modified: head/sys/arm/sa11x0/assabet_machdep.c
==============================================================================
--- head/sys/arm/sa11x0/assabet_machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/arm/sa11x0/assabet_machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -209,6 +209,7 @@ initarm(void *arg, void *arg2)
 	struct pv_addr  kernel_l1pt;
 	struct pv_addr	md_addr;
 	struct pv_addr	md_bla;
+	struct pv_addr  dpcpu;
 	int loop;
 	u_int l1pagetable;
 	vm_offset_t freemempos;
@@ -268,6 +269,10 @@ initarm(void *arg, void *arg2)
 	 */
 	valloc_pages(systempage, 1);
 
+	/* Allocate dynamic per-cpu area. */
+	valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
+	dpcpu_init((void *)dpcpu.pv_va, 0);
+
 	/* Allocate stacks for all modes */
 	valloc_pages(irqstack, IRQ_STACK_SIZE);
 	valloc_pages(abtstack, ABT_STACK_SIZE);

Modified: head/sys/arm/xscale/i80321/ep80219_machdep.c
==============================================================================
--- head/sys/arm/xscale/i80321/ep80219_machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/arm/xscale/i80321/ep80219_machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -186,6 +186,7 @@ void *
 initarm(void *arg, void *arg2)
 {
 	struct pv_addr  kernel_l1pt;
+	struct pv_addr  dpcpu;
 	int loop, i;
 	u_int l1pagetable;
 	vm_offset_t freemempos;
@@ -236,6 +237,10 @@ initarm(void *arg, void *arg2)
 	 */
 	valloc_pages(systempage, 1);
 
+	/* Allocate dynamic per-cpu area. */
+	valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
+	dpcpu_init((void *)dpcpu.pv_va, 0);
+
 	/* Allocate stacks for all modes */
 	valloc_pages(irqstack, IRQ_STACK_SIZE);
 	valloc_pages(abtstack, ABT_STACK_SIZE);

Modified: head/sys/arm/xscale/i80321/iq31244_machdep.c
==============================================================================
--- head/sys/arm/xscale/i80321/iq31244_machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/arm/xscale/i80321/iq31244_machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -187,6 +187,7 @@ void *
 initarm(void *arg, void *arg2)
 {
 	struct pv_addr  kernel_l1pt;
+	struct pv_addr  dpcpu;
 	int loop, i;
 	u_int l1pagetable;
 	vm_offset_t freemempos;
@@ -236,6 +237,10 @@ initarm(void *arg, void *arg2)
 	 */
 	valloc_pages(systempage, 1);
 
+	/* Allocate dynamic per-cpu area. */
+	valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
+	dpcpu_init((void *)dpcpu.pv_va, 0);
+
 	/* Allocate stacks for all modes */
 	valloc_pages(irqstack, IRQ_STACK_SIZE);
 	valloc_pages(abtstack, ABT_STACK_SIZE);

Modified: head/sys/arm/xscale/i8134x/crb_machdep.c
==============================================================================
--- head/sys/arm/xscale/i8134x/crb_machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/arm/xscale/i8134x/crb_machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -183,6 +183,7 @@ void *
 initarm(void *arg, void *arg2)
 {
 	struct pv_addr  kernel_l1pt;
+	struct pv_addr  dpcpu;
 	int loop, i;
 	u_int l1pagetable;
 	vm_offset_t freemempos;
@@ -232,6 +233,10 @@ initarm(void *arg, void *arg2)
 	 */
 	valloc_pages(systempage, 1);
 
+	/* Allocate dynamic per-cpu area. */
+	valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
+	dpcpu_init((void *)dpcpu.pv_va, 0);
+
 	/* Allocate stacks for all modes */
 	valloc_pages(irqstack, IRQ_STACK_SIZE);
 	valloc_pages(abtstack, ABT_STACK_SIZE);

Modified: head/sys/arm/xscale/ixp425/avila_machdep.c
==============================================================================
--- head/sys/arm/xscale/ixp425/avila_machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/arm/xscale/ixp425/avila_machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -232,6 +232,7 @@ initarm(void *arg, void *arg2)
 #define	next_chunk2(a,b)	(((a) + (b)) &~ ((b)-1))
 #define	next_page(a)		next_chunk2(a,PAGE_SIZE)
 	struct pv_addr  kernel_l1pt;
+	struct pv_addr  dpcpu;
 	int loop, i;
 	u_int l1pagetable;
 	vm_offset_t freemempos;
@@ -303,6 +304,10 @@ initarm(void *arg, void *arg2)
 	 */
 	valloc_pages(systempage, 1);
 
+	/* Allocate dynamic per-cpu area. */
+	valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
+	dpcpu_init((void *)dpcpu.pv_va, 0);
+
 	/* Allocate stacks for all modes */
 	valloc_pages(irqstack, IRQ_STACK_SIZE);
 	valloc_pages(abtstack, ABT_STACK_SIZE);

Modified: head/sys/arm/xscale/pxa/pxa_machdep.c
==============================================================================
--- head/sys/arm/xscale/pxa/pxa_machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/arm/xscale/pxa/pxa_machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -166,6 +166,7 @@ void *
 initarm(void *arg, void *arg2)
 {
 	struct pv_addr  kernel_l1pt;
+	struct pv_addr  dpcpu;
 	int loop;
 	u_int l1pagetable;
 	vm_offset_t freemempos;
@@ -218,6 +219,10 @@ initarm(void *arg, void *arg2)
 	 */
 	valloc_pages(systempage, 1);
 
+	/* Allocate dynamic per-cpu area. */
+	valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
+	dpcpu_init((void *)dpcpu.pv_va, 0);
+
 	/* Allocate stacks for all modes */
 	valloc_pages(irqstack, IRQ_STACK_SIZE);
 	valloc_pages(abtstack, ABT_STACK_SIZE);

Modified: head/sys/i386/i386/elf_machdep.c
==============================================================================
--- head/sys/i386/i386/elf_machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/i386/i386/elf_machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -149,7 +149,7 @@ elf_reloc_internal(linker_file_t lf, Elf
 
 	if (local) {
 		if (rtype == R_386_RELATIVE) {	/* A + B */
-			addr = relocbase + addend;
+			addr = elf_relocaddr(lf, relocbase + addend);
 			if (*where != addr)
 				*where = addr;
 		}

Modified: head/sys/i386/i386/machdep.c
==============================================================================
--- head/sys/i386/i386/machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/i386/i386/machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -2448,7 +2448,7 @@ init386(first)
 	int first;
 {
 	unsigned long gdtmachpfn;
-	int error, gsel_tss, metadata_missing, x;
+	int error, gsel_tss, metadata_missing, x, pa;
 	struct pcpu *pc;
 	struct callback_register event = {
 		.type = CALLBACKTYPE_event,
@@ -2532,6 +2532,11 @@ init386(first)
 		    GSEL(GCODE_SEL, SEL_KPL), (unsigned long)failsafe_callback);
 #endif
 	pcpu_init(pc, 0, sizeof(struct pcpu));
+	for (pa = first; pa < first + DPCPU_SIZE; pa += PAGE_SIZE)
+		pmap_kenter(pa + KERNBASE, pa);
+	dpcpu_init((void *)(first + KERNBASE), 0);
+	first += DPCPU_SIZE;
+
 	PCPU_SET(prvspace, pc);
 	PCPU_SET(curthread, &thread0);
 	PCPU_SET(curpcb, thread0.td_pcb);
@@ -2665,7 +2670,7 @@ init386(first)
 	int first;
 {
 	struct gate_descriptor *gdp;
-	int gsel_tss, metadata_missing, x;
+	int gsel_tss, metadata_missing, x, pa;
 	struct pcpu *pc;
 
 	thread0.td_kstack = proc0kstack;
@@ -2718,6 +2723,10 @@ init386(first)
 	lgdt(&r_gdt);
 
 	pcpu_init(pc, 0, sizeof(struct pcpu));
+	for (pa = first; pa < first + DPCPU_SIZE; pa += PAGE_SIZE)
+		pmap_kenter(pa + KERNBASE, pa);
+	dpcpu_init((void *)(first + KERNBASE), 0);
+	first += DPCPU_SIZE;
 	PCPU_SET(prvspace, pc);
 	PCPU_SET(curthread, &thread0);
 	PCPU_SET(curpcb, thread0.td_pcb);

Modified: head/sys/i386/i386/mp_machdep.c
==============================================================================
--- head/sys/i386/i386/mp_machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/i386/i386/mp_machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -143,6 +143,7 @@ static int bootAP;
 
 /* Free these after use */
 void *bootstacks[MAXCPU];
+static void *dpcpu;
 
 /* Hotwire a 0->4MB V==P mapping */
 extern pt_entry_t *KPTphys;
@@ -610,6 +611,7 @@ init_secondary(void)
 
 	/* prime data page for it to use */
 	pcpu_init(pc, myid, sizeof(struct pcpu));
+	dpcpu_init(dpcpu, myid);
 	pc->pc_apic_id = cpu_apic_ids[myid];
 	pc->pc_prvspace = pc;
 	pc->pc_curthread = 0;
@@ -897,8 +899,9 @@ start_all_aps(void)
 		apic_id = cpu_apic_ids[cpu];
 
 		/* allocate and set up a boot stack data page */
-		bootstacks[cpu] = (char *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE);
-
+		bootstacks[cpu] =
+		    (char *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE);
+		dpcpu = (void *)kmem_alloc(kernel_map, DPCPU_SIZE);
 		/* setup a vector to our boot code */
 		*((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET;
 		*((volatile u_short *) WARMBOOT_SEG) = (boot_address >> 4);

Modified: head/sys/i386/xen/mp_machdep.c
==============================================================================
--- head/sys/i386/xen/mp_machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/i386/xen/mp_machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -744,6 +744,7 @@ start_all_aps(void)
 		/* Get per-cpu data */
 		pc = &__pcpu[bootAP];
 		pcpu_init(pc, bootAP, sizeof(struct pcpu));
+		dpcpu_init((void *)kmem_alloc(kernel_map, DPCPU_SIZE), bootAP);
 		pc->pc_apic_id = cpu_apic_ids[bootAP];
 		pc->pc_prvspace = pc;
 		pc->pc_curthread = 0;

Modified: head/sys/ia64/ia64/elf_machdep.c
==============================================================================
--- head/sys/ia64/ia64/elf_machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/ia64/ia64/elf_machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -211,7 +211,7 @@ elf_reloc_internal(linker_file_t lf, Elf
 
 	if (local) {
 		if (rtype == R_IA_64_REL64LSB)
-			*where = relocbase + addend;
+			*where = elf_relocaddr(lf, relocbase + addend);
 		return (0);
 	}
 

Modified: head/sys/ia64/ia64/machdep.c
==============================================================================
--- head/sys/ia64/ia64/machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/ia64/ia64/machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -647,6 +647,21 @@ ia64_init(void)
 		bootverbose = 1;
 
 	/*
+	 * Find the beginning and end of the kernel.
+	 */
+	kernstart = trunc_page(kernel_text);
+#ifdef DDB
+	ksym_start = bootinfo.bi_symtab;
+	ksym_end = bootinfo.bi_esymtab;
+	kernend = (vm_offset_t)round_page(ksym_end);
+#else
+	kernend = (vm_offset_t)round_page(_end);
+#endif
+	/* But if the bootstrap tells us otherwise, believe it! */
+	if (bootinfo.bi_kernend)
+		kernend = round_page(bootinfo.bi_kernend);
+
+	/*
 	 * Setup the PCPU data for the bootstrap processor. It is needed
 	 * by printf(). Also, since printf() has critical sections, we
 	 * need to initialize at least pc_curthread.
@@ -654,6 +669,8 @@ ia64_init(void)
 	pcpup = &pcpu0;
 	ia64_set_k4((u_int64_t)pcpup);
 	pcpu_init(pcpup, 0, sizeof(pcpu0));
+	dpcpu_init((void *)kernend, 0);
+	kernend += DPCPU_SIZE;
 	PCPU_SET(curthread, &thread0);
 
 	/*
@@ -682,21 +699,6 @@ ia64_init(void)
 	ia64_sal_init();
 	calculate_frequencies();
 
-	/*
-	 * Find the beginning and end of the kernel.
-	 */
-	kernstart = trunc_page(kernel_text);
-#ifdef DDB
-	ksym_start = bootinfo.bi_symtab;
-	ksym_end = bootinfo.bi_esymtab;
-	kernend = (vm_offset_t)round_page(ksym_end);
-#else
-	kernend = (vm_offset_t)round_page(_end);
-#endif
-
-	/* But if the bootstrap tells us otherwise, believe it! */
-	if (bootinfo.bi_kernend)
-		kernend = round_page(bootinfo.bi_kernend);
 	if (metadata_missing)
 		printf("WARNING: loader(8) metadata is missing!\n");
 

Modified: head/sys/ia64/ia64/mp_machdep.c
==============================================================================
--- head/sys/ia64/ia64/mp_machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/ia64/ia64/mp_machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -207,6 +207,7 @@ cpu_mp_add(u_int acpiid, u_int apicid, u
 {
 	struct pcpu *pc;
 	u_int64_t lid;
+	void *dpcpu;
 
 	/* Ignore any processor numbers outside our range */
 	if (acpiid > mp_maxid)
@@ -224,7 +225,9 @@ cpu_mp_add(u_int acpiid, u_int apicid, u
 
 	if (acpiid != 0) {
 		pc = (struct pcpu *)malloc(sizeof(*pc), M_SMP, M_WAITOK);
+		dpcpu = (void *)kmem_alloc(kernel_map, DPCPU_SIZE);
 		pcpu_init(pc, acpiid, sizeof(*pc));
+		dpcpu_init(dpcpu, acpiid);
 	} else
 		pc = pcpup;
 

Modified: head/sys/kern/link_elf.c
==============================================================================
--- head/sys/kern/link_elf.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/kern/link_elf.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/malloc.h>
 #include <sys/mutex.h>
 #include <sys/mount.h>
+#include <sys/pcpu.h>
 #include <sys/proc.h>
 #include <sys/namei.h>
 #include <sys/fcntl.h>
@@ -107,6 +108,9 @@ typedef struct elf_file {
     caddr_t		ctfoff;		/* CTF offset table */
     caddr_t		typoff;		/* Type offset table */
     long		typlen;		/* Number of type entries. */
+    Elf_Addr		pcpu_start;	/* Pre-relocation pcpu set start. */
+    Elf_Addr		pcpu_stop;	/* Pre-relocation pcpu set stop. */
+    Elf_Addr		pcpu_base;	/* Relocated pcpu set address. */
 #ifdef GDB
     struct link_map	gdb;		/* hooks for gdb */
 #endif
@@ -475,6 +479,34 @@ parse_dynamic(elf_file_t ef)
 }
 
 static int
+parse_dpcpu(elf_file_t ef)
+{ 
+    int count;
+    int error;
+
+    ef->pcpu_start = 0;
+    ef->pcpu_stop = 0;
+    error = link_elf_lookup_set(&ef->lf, "pcpu", (void ***)&ef->pcpu_start,
+                               (void ***)&ef->pcpu_stop, &count);
+    /* Error just means there is no pcpu set to relocate. */
+    if (error)
+        return (0);
+    count *= sizeof(void *);
+    /*
+     * Allocate space in the primary pcpu area.  Copy in our initialization
+     * from the data section and then initialize all per-cpu storage from
+     * that.
+     */
+    ef->pcpu_base = (Elf_Addr)(uintptr_t)dpcpu_alloc(count);
+    if (ef->pcpu_base == (Elf_Addr)NULL)
+        return (ENOSPC);
+    memcpy((void *)ef->pcpu_base, (void *)ef->pcpu_start, count);
+    dpcpu_copy((void *)ef->pcpu_base, count);
+
+    return (0);
+}
+
+static int
 link_elf_link_preload(linker_class_t cls,
 		      const char* filename, linker_file_t *result)
 {
@@ -519,6 +551,8 @@ link_elf_link_preload(linker_class_t cls
     lf->size = *(size_t *)sizeptr;
 
     error = parse_dynamic(ef);
+    if (error == 0)
+        error = parse_dpcpu(ef);
     if (error) {
 	linker_file_unload(lf, LINKER_UNLOAD_FORCE);
 	return error;
@@ -801,6 +835,9 @@ link_elf_load_file(linker_class_t cls, c
     error = parse_dynamic(ef);
     if (error)
 	goto out;
+    error = parse_dpcpu(ef);
+    if (error)
+        goto out;
     link_elf_reloc_local(lf);
 
     VOP_UNLOCK(nd.ni_vp, 0);
@@ -897,11 +934,26 @@ out:
     return error;
 }
 
+Elf_Addr
+elf_relocaddr(linker_file_t lf, Elf_Addr x)
+{
+    elf_file_t ef;
+
+    ef = (elf_file_t)lf;
+    if (x >= ef->pcpu_start && x < ef->pcpu_stop)
+	return ((x - ef->pcpu_start) + ef->pcpu_base);
+    return (x);
+}
+
+
 static void
 link_elf_unload_file(linker_file_t file)
 {
     elf_file_t ef = (elf_file_t) file;
 
+    if (ef->pcpu_base) {
+        dpcpu_free((void *)ef->pcpu_base, ef->pcpu_stop - ef->pcpu_start);
+    }
 #ifdef GDB
     if (ef->gdb.l_ld) {
 	GDB_STATE(RT_DELETE);

Modified: head/sys/kern/link_elf_obj.c
==============================================================================
--- head/sys/kern/link_elf_obj.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/kern/link_elf_obj.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -333,6 +333,20 @@ link_elf_link_preload(linker_class_t cls
 			if (ef->shstrtab && shdr[i].sh_name != 0)
 				ef->progtab[pb].name =
 				    ef->shstrtab + shdr[i].sh_name;
+			if (ef->progtab[pb].name != NULL && 
+			    !strcmp(ef->progtab[pb].name, "set_pcpu")) {
+				void *dpcpu;
+
+				dpcpu = dpcpu_alloc(shdr[i].sh_size);
+				if (dpcpu == NULL) {
+					error = ENOSPC;
+					goto out;
+				}
+				memcpy(dpcpu, ef->progtab[pb].addr,
+				    ef->progtab[pb].size);
+				dpcpu_copy(dpcpu, shdr[i].sh_size);
+				ef->progtab[pb].addr = dpcpu;
+			}
 
 			/* Update all symbol values with the offset. */
 			for (j = 0; j < ef->ddbsymcnt; j++) {
@@ -712,9 +726,27 @@ link_elf_load_file(linker_class_t cls, c
 			alignmask = shdr[i].sh_addralign - 1;
 			mapbase += alignmask;
 			mapbase &= ~alignmask;
-			ef->progtab[pb].addr = (void *)(uintptr_t)mapbase;
-			if (shdr[i].sh_type == SHT_PROGBITS) {
+			if (ef->shstrtab && shdr[i].sh_name != 0)
+				ef->progtab[pb].name =
+				    ef->shstrtab + shdr[i].sh_name;
+			else if (shdr[i].sh_type == SHT_PROGBITS)
 				ef->progtab[pb].name = "<<PROGBITS>>";
+			else
+				ef->progtab[pb].name = "<<NOBITS>>";
+			if (ef->progtab[pb].name != NULL && 
+			    !strcmp(ef->progtab[pb].name, "set_pcpu"))
+				ef->progtab[pb].addr =
+				    dpcpu_alloc(shdr[i].sh_size);
+			else
+				ef->progtab[pb].addr =
+				    (void *)(uintptr_t)mapbase;
+			if (ef->progtab[pb].addr == NULL) {
+				error = ENOSPC;
+				goto out;
+			}
+			ef->progtab[pb].size = shdr[i].sh_size;
+			ef->progtab[pb].sec = i;
+			if (shdr[i].sh_type == SHT_PROGBITS) {
 				error = vn_rdwr(UIO_READ, nd.ni_vp,
 				    ef->progtab[pb].addr,
 				    shdr[i].sh_size, shdr[i].sh_offset,
@@ -726,15 +758,12 @@ link_elf_load_file(linker_class_t cls, c
 					error = EINVAL;
 					goto out;
 				}
-			} else {
-				ef->progtab[pb].name = "<<NOBITS>>";
+				/* Initialize the per-cpu area. */
+				if (ef->progtab[pb].addr != (void *)mapbase)
+					dpcpu_copy(ef->progtab[pb].addr,
+					    shdr[i].sh_size);
+			} else
 				bzero(ef->progtab[pb].addr, shdr[i].sh_size);
-			}
-			ef->progtab[pb].size = shdr[i].sh_size;
-			ef->progtab[pb].sec = i;
-			if (ef->shstrtab && shdr[i].sh_name != 0)
-				ef->progtab[pb].name =
-				    ef->shstrtab + shdr[i].sh_name;
 
 			/* Update all symbol values with the offset. */
 			for (j = 0; j < ef->ddbsymcnt; j++) {
@@ -839,6 +868,17 @@ link_elf_unload_file(linker_file_t file)
 	/* Notify MD code that a module is being unloaded. */
 	elf_cpu_unload_file(file);
 
+	if (ef->progtab) {
+		for (i = 0; i < ef->nprogtab; i++) {
+			if (ef->progtab[i].size == 0)
+				continue;
+			if (ef->progtab[i].name == NULL)
+				continue;
+			if (!strcmp(ef->progtab[i].name, "set_pcpu"))
+				dpcpu_free(ef->progtab[i].addr,
+				    ef->progtab[i].size);
+		}
+	}
 	if (ef->preloaded) {
 		if (ef->reltab)
 			free(ef->reltab, M_LINKER);

Modified: head/sys/kern/subr_pcpu.c
==============================================================================
--- head/sys/kern/subr_pcpu.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/kern/subr_pcpu.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -3,6 +3,9 @@
  * All rights reserved.
  * Written by: John Baldwin <jhb at FreeBSD.org>
  *
+ * Copyright (c) 2009 Jeffrey Roberson <jeff at freebsd.org>
+ * All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -49,13 +52,28 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/sysctl.h>
 #include <sys/linker_set.h>
 #include <sys/lock.h>
+#include <sys/malloc.h>
 #include <sys/pcpu.h>
 #include <sys/proc.h>
 #include <sys/smp.h>
+#include <sys/sx.h>
 #include <ddb/ddb.h>
 
+MALLOC_DEFINE(M_PCPU, "Per-cpu", "Per-cpu resource accouting.");
+
+struct dpcpu_free {
+	uintptr_t	df_start;
+	int		df_len;
+	TAILQ_ENTRY(dpcpu_free) df_link;
+};
+
+static DPCPU_DEFINE(char, modspace[DPCPU_MODMIN]);
+static TAILQ_HEAD(, dpcpu_free) dpcpu_head = TAILQ_HEAD_INITIALIZER(dpcpu_head);
+static struct sx dpcpu_lock;
+uintptr_t dpcpu_off[MAXCPU];
 struct pcpu *cpuid_to_pcpu[MAXCPU];
 struct cpuhead cpuhead = SLIST_HEAD_INITIALIZER(cpuhead);
 
@@ -79,7 +97,146 @@ pcpu_init(struct pcpu *pcpu, int cpuid, 
 #ifdef KTR
 	snprintf(pcpu->pc_name, sizeof(pcpu->pc_name), "CPU %d", cpuid);
 #endif
+}
+
+void
+dpcpu_init(void *dpcpu, int cpuid)
+{
+	struct pcpu *pcpu;
+
+	pcpu = pcpu_find(cpuid);
+	pcpu->pc_dynamic = (uintptr_t)dpcpu - DPCPU_START;
+
+	/*
+	 * Initialize defaults from our linker section.
+	 */
+	memcpy(dpcpu, (void *)DPCPU_START, DPCPU_BYTES);
+
+	/*
+	 * Place it in the global pcpu offset array.
+	 */
+	dpcpu_off[cpuid] = pcpu->pc_dynamic;
+}
+
+static void
+dpcpu_startup(void *dummy __unused)
+{
+	struct dpcpu_free *df;
+
+	df = malloc(sizeof(*df), M_PCPU, M_WAITOK | M_ZERO);
+	df->df_start = (uintptr_t)&DPCPU_NAME(modspace);
+	df->df_len = DPCPU_MODSIZE;
+	TAILQ_INSERT_HEAD(&dpcpu_head, df, df_link);
+	sx_init(&dpcpu_lock, "dpcpu alloc lock");
+}
+SYSINIT(dpcpu, SI_SUB_KLD, SI_ORDER_FIRST, dpcpu_startup, 0);
+
+/*
+ * First-fit extent based allocator for allocating space in the per-cpu
+ * region reserved for modules.  This is only intended for use by the
+ * kernel linkers to place module linker sets.
+ */
+void *
+dpcpu_alloc(int size)
+{
+	struct dpcpu_free *df;
+	void *s;
+
+	s = NULL;
+	size = roundup2(size, sizeof(void *));
+	sx_xlock(&dpcpu_lock);
+	TAILQ_FOREACH(df, &dpcpu_head, df_link) {
+		if (df->df_len < size)
+			continue;
+		if (df->df_len == size) {
+			s = (void *)df->df_start;
+			TAILQ_REMOVE(&dpcpu_head, df, df_link);
+			free(df, M_PCPU);
+			break;
+		}
+		s = (void *)df->df_start;
+		df->df_len -= size;
+		df->df_start = df->df_start + size;
+		break;
+	}
+	sx_xunlock(&dpcpu_lock);
+
+	return (s);
+}
+
+/*
+ * Free dynamic per-cpu space at module unload time. 
+ */
+void
+dpcpu_free(void *s, int size)
+{
+	struct dpcpu_free *df;
+	struct dpcpu_free *dn;
+	uintptr_t start;
+	uintptr_t end;
+
+	size = roundup2(size, sizeof(void *));
+	start = (uintptr_t)s;
+	end = start + size;
+	/*
+	 * Free a region of space and merge it with as many neighbors as
+	 * possible.  Keeping the list sorted simplifies this operation.
+	 */
+	sx_xlock(&dpcpu_lock);
+	TAILQ_FOREACH(df, &dpcpu_head, df_link) {
+		if (df->df_start > end)
+			break;
+		/*
+		 * If we expand at the end of an entry we may have to
+		 * merge it with the one following it as well.
+		 */
+		if (df->df_start + df->df_len == start) {
+			df->df_len += size;
+			dn = TAILQ_NEXT(df, df_link);
+			if (df->df_start + df->df_len == dn->df_start) {
+				df->df_len += dn->df_len;
+				TAILQ_REMOVE(&dpcpu_head, dn, df_link);
+				free(dn, M_PCPU);
+			}
+			sx_xunlock(&dpcpu_lock);
+			return;
+		}
+		if (df->df_start == end) {
+			df->df_start = start;
+			df->df_len += size;
+			sx_xunlock(&dpcpu_lock);
+			return;
+		}
+	}
+	dn = malloc(sizeof(*df), M_PCPU, M_WAITOK | M_ZERO);
+	dn->df_start = start;
+	dn->df_len = size;
+	if (df)
+		TAILQ_INSERT_BEFORE(df, dn, df_link);
+	else
+		TAILQ_INSERT_TAIL(&dpcpu_head, dn, df_link);
+	sx_xunlock(&dpcpu_lock);
+}
 
+/*
+ * Initialize the per-cpu storage from an updated linker-set region.
+ */
+void
+dpcpu_copy(void *s, int size)
+{
+#ifdef SMP
+	uintptr_t dpcpu;
+	int i;
+
+	for (i = 0; i < mp_ncpus; ++i) {
+		dpcpu = dpcpu_off[i];
+		if (dpcpu == 0)
+			continue;
+		memcpy((void *)(dpcpu + (uintptr_t)s), s, size);
+	}
+#else
+	memcpy((void *)(dpcpu_off[0] + (uintptr_t)s), s, size);
+#endif
 }
 
 /*
@@ -91,6 +248,7 @@ pcpu_destroy(struct pcpu *pcpu)
 
 	SLIST_REMOVE(&cpuhead, pcpu, pcpu, pc_allcpu);
 	cpuid_to_pcpu[pcpu->pc_cpuid] = NULL;
+	dpcpu_off[pcpu->pc_cpuid] = 0;
 }
 
 /*
@@ -103,6 +261,48 @@ pcpu_find(u_int cpuid)
 	return (cpuid_to_pcpu[cpuid]);
 }
 
+int
+sysctl_dpcpu_quad(SYSCTL_HANDLER_ARGS)
+{
+	int64_t count;
+#ifdef SMP
+	uintptr_t dpcpu;
+	int i;
+
+	count = 0;
+	for (i = 0; i < mp_ncpus; ++i) {
+		dpcpu = dpcpu_off[i];
+		if (dpcpu == 0)
+			continue;
+		count += *(int64_t *)(dpcpu + (uintptr_t)arg1);
+	}
+#else
+	count = *(int64_t *)(dpcpu_off[0] + (uintptr_t)arg1);
+#endif
+	return (SYSCTL_OUT(req, &count, sizeof(count)));
+}
+
+int
+sysctl_dpcpu_int(SYSCTL_HANDLER_ARGS)
+{
+	int count;
+#ifdef SMP
+	uintptr_t dpcpu;
+	int i;
+
+	count = 0;
+	for (i = 0; i < mp_ncpus; ++i) {
+		dpcpu = dpcpu_off[i];
+		if (dpcpu == 0)
+			continue;
+		count += *(int *)(dpcpu + (uintptr_t)arg1);
+	}
+#else
+	count = *(int *)(dpcpu_off[0] + (uintptr_t)arg1);
+#endif
+	return (SYSCTL_OUT(req, &count, sizeof(count)));
+}
+
 #ifdef DDB
 
 static void
@@ -111,6 +311,7 @@ show_pcpu(struct pcpu *pc)
 	struct thread *td;
 
 	db_printf("cpuid        = %d\n", pc->pc_cpuid);
+	db_printf("dynamic pcpu	= %p\n", (void *)pc->pc_dynamic);
 	db_printf("curthread    = ");
 	td = pc->pc_curthread;
 	if (td != NULL)

Modified: head/sys/mips/mips/elf_machdep.c
==============================================================================
--- head/sys/mips/mips/elf_machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/mips/mips/elf_machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -134,7 +134,7 @@ elf_reloc_internal(linker_file_t lf, Elf
 	if (local) {
 #if 0 /* TBD  */
 		if (rtype == R_386_RELATIVE) {	/* A + B */
-			addr = relocbase + addend;
+			addr = elf_relocaddr(lf, relocbase + addend);
 			if (*where != addr)
 				*where = addr;
 		}

Modified: head/sys/mips/mips/mp_machdep.c
==============================================================================
--- head/sys/mips/mips/mp_machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/mips/mips/mp_machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -224,12 +224,15 @@ static int
 smp_start_secondary(int cpuid)
 {
 	struct pcpu *pcpu;
+	void *dpcpu;
 	int i;
 
 	if (bootverbose)
 		printf("smp_start_secondary: starting cpu %d\n", cpuid);
 
+	dpcpu = (void *)kmem_alloc(kernel_map, DPCPU_SIZE);
 	pcpu_init(&__pcpu[cpuid], cpuid, sizeof(struct pcpu));
+	dpcpu_init(dpcpu, cpuid);
 
 	if (bootverbose)
 		printf("smp_start_secondary: cpu %d started\n", cpuid);

Modified: head/sys/mips/mips/pmap.c
==============================================================================
--- head/sys/mips/mips/pmap.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/mips/mips/pmap.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -331,6 +331,9 @@ again:
 	msgbufp = (struct msgbuf *)pmap_steal_memory(MSGBUF_SIZE);
 	msgbufinit(msgbufp, MSGBUF_SIZE);
 
+	/* Steal memory for the dynamic per-cpu area. */
+	dpcpu_init((void *)pmap_steal_memory(DPCPU_SIZE), 0);
+
 	/*
 	 * Steal thread0 kstack.
 	 */

Modified: head/sys/pc98/pc98/machdep.c
==============================================================================
--- head/sys/pc98/pc98/machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/pc98/pc98/machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -1954,6 +1954,7 @@ init386(first)
 	struct gate_descriptor *gdp;
 	int gsel_tss, metadata_missing, x;
 	struct pcpu *pc;
+	int pa;
 
 	thread0.td_kstack = proc0kstack;
 	thread0.td_pcb = (struct pcb *)
@@ -2010,6 +2011,11 @@ init386(first)
 	lgdt(&r_gdt);
 
 	pcpu_init(pc, 0, sizeof(struct pcpu));
+	for (pa = first; pa < first + DPCPU_SIZE; pa += PAGE_SIZE)
+		pmap_kenter(pa + KERNBASE, pa);
+	dpcpu_init((void *)(first + KERNBASE), 0);
+	first += DPCPU_SIZE;
+
 	PCPU_SET(prvspace, pc);
 	PCPU_SET(curthread, &thread0);
 	PCPU_SET(curpcb, thread0.td_pcb);

Modified: head/sys/powerpc/aim/mmu_oea.c
==============================================================================
--- head/sys/powerpc/aim/mmu_oea.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/powerpc/aim/mmu_oea.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -669,6 +669,7 @@ moea_bootstrap(mmu_t mmup, vm_offset_t k
 	int		ofw_mappings;
 	vm_size_t	size, physsz, hwphyssz;
 	vm_offset_t	pa, va, off;
+	void		*dpcpu;
 
         /*
          * Set up BAT0 to map the lowest 256 MB area
@@ -938,6 +939,20 @@ moea_bootstrap(mmu_t mmup, vm_offset_t k
 		pa += PAGE_SIZE;
 		va += PAGE_SIZE;
 	}
+
+	/*
+	 * Allocate virtual address space for the dynamic percpu area.
+	 */
+	pa = moea_bootstrap_alloc(DPCPU_SIZE, PAGE_SIZE);
+	dpcpu = (void *)virtual_avail;
+	va = virtual_avail;
+	virtual_avail += DPCPU_SIZE;
+	while (va < virtual_avail) {
+		moea_kenter(mmup, va, pa);;
+		pa += PAGE_SIZE;
+		va += PAGE_SIZE;
+	}
+	dpcpu_init(dpcpu, 0);
 }
 
 /*

Modified: head/sys/powerpc/aim/mmu_oea64.c
==============================================================================
--- head/sys/powerpc/aim/mmu_oea64.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/powerpc/aim/mmu_oea64.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -726,6 +726,7 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_o
 	vm_size_t	size, physsz, hwphyssz;
 	vm_offset_t	pa, va, off;
 	uint32_t	msr;
+	void		*dpcpu;
 
 	/* We don't have a direct map since there is no BAT */
 	hw_direct_map = 0;
@@ -1027,6 +1028,20 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_o
 		pa += PAGE_SIZE;
 		va += PAGE_SIZE;
 	}
+
+	/*
+	 * Allocate virtual address space for the dynamic percpu area.
+	 */
+	pa = moea64_bootstrap_alloc(DPCPU_SIZE, PAGE_SIZE);
+	dpcpu = (void *)virtual_avail;
+	va = virtual_avail;
+	virtual_avail += DPCPU_SIZE;
+	while (va < virtual_avail) {
+		moea64_kenter(mmup, va, pa);;
+		pa += PAGE_SIZE;
+		va += PAGE_SIZE;
+	}
+	dpcpu_init(dpcpu, 0);
 }
 
 /*

Modified: head/sys/powerpc/booke/pmap.c
==============================================================================
--- head/sys/powerpc/booke/pmap.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/powerpc/booke/pmap.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -963,6 +963,7 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset
 	vm_size_t physsz, hwphyssz, kstack0_sz;
 	vm_offset_t kernel_pdir, kstack0, va;
 	vm_paddr_t kstack0_phys;
+	void *dpcpu;
 	pte_t *pte;
 
 	debugf("mmu_booke_bootstrap: entered\n");
@@ -988,6 +989,11 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset
 
 	data_end = round_page(data_end);
 
+	/* Allocate the dynamic per-cpu area. */
+	dpcpu = (void *)data_end;
+	data_end += DPCPU_SIZE;
+	dpcpu_init(dpcpu, 0);
+
 	/* Allocate space for ptbl_bufs. */
 	ptbl_bufs = (struct ptbl_buf *)data_end;
 	data_end += sizeof(struct ptbl_buf) * PTBL_BUFS;

Modified: head/sys/powerpc/powerpc/elf_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/elf_machdep.c	Tue Jun 23 22:28:44 2009	(r194783)
+++ head/sys/powerpc/powerpc/elf_machdep.c	Tue Jun 23 22:42:39 2009	(r194784)
@@ -194,7 +194,7 @@ elf_reloc_internal(linker_file_t lf, Elf
 		break;
 
 	case R_PPC_RELATIVE: /* word32 B + A */
-       		*where = relocbase + addend;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list