aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/setup_64.c26
-rw-r--r--include/asm-powerpc/paca.h1
-rw-r--r--include/asm-powerpc/percpu.h56
3 files changed, 83 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 0420418f317a..e29b275e09e0 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -33,6 +33,7 @@
33#include <linux/unistd.h> 33#include <linux/unistd.h>
34#include <linux/serial.h> 34#include <linux/serial.h>
35#include <linux/serial_8250.h> 35#include <linux/serial_8250.h>
36#include <linux/bootmem.h>
36#include <asm/io.h> 37#include <asm/io.h>
37#include <asm/kdump.h> 38#include <asm/kdump.h>
38#include <asm/prom.h> 39#include <asm/prom.h>
@@ -654,3 +655,28 @@ void cpu_die(void)
654 if (ppc_md.cpu_die) 655 if (ppc_md.cpu_die)
655 ppc_md.cpu_die(); 656 ppc_md.cpu_die();
656} 657}
658
659#ifdef CONFIG_SMP
660void __init setup_per_cpu_areas(void)
661{
662 int i;
663 unsigned long size;
664 char *ptr;
665
666 /* Copy section for each CPU (we discard the original) */
667 size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES);
668#ifdef CONFIG_MODULES
669 if (size < PERCPU_ENOUGH_ROOM)
670 size = PERCPU_ENOUGH_ROOM;
671#endif
672
673 for_each_cpu(i) {
674 ptr = alloc_bootmem_node(NODE_DATA(cpu_to_node(i)), size);
675 if (!ptr)
676 panic("Cannot allocate cpu data for CPU %d\n", i);
677
678 paca[i].data_offset = ptr - __per_cpu_start;
679 memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
680 }
681}
682#endif
diff --git a/include/asm-powerpc/paca.h b/include/asm-powerpc/paca.h
index 3ae52d9dc9ff..a64b4d425dab 100644
--- a/include/asm-powerpc/paca.h
+++ b/include/asm-powerpc/paca.h
@@ -65,6 +65,7 @@ struct paca_struct {
65 u64 stab_real; /* Absolute address of segment table */ 65 u64 stab_real; /* Absolute address of segment table */
66 u64 stab_addr; /* Virtual address of segment table */ 66 u64 stab_addr; /* Virtual address of segment table */
67 void *emergency_sp; /* pointer to emergency stack */ 67 void *emergency_sp; /* pointer to emergency stack */
68 u64 data_offset; /* per cpu data offset */
68 s16 hw_cpu_id; /* Physical processor number */ 69 s16 hw_cpu_id; /* Physical processor number */
69 u8 cpu_start; /* At startup, processor spins until */ 70 u8 cpu_start; /* At startup, processor spins until */
70 /* this becomes non-zero. */ 71 /* this becomes non-zero. */
diff --git a/include/asm-powerpc/percpu.h b/include/asm-powerpc/percpu.h
index 06a959d67234..e31922c50e53 100644
--- a/include/asm-powerpc/percpu.h
+++ b/include/asm-powerpc/percpu.h
@@ -1 +1,57 @@
1#ifndef _ASM_POWERPC_PERCPU_H_
2#define _ASM_POWERPC_PERCPU_H_
3#ifdef __powerpc64__
4#include <linux/compiler.h>
5
6/*
7 * Same as asm-generic/percpu.h, except that we store the per cpu offset
8 * in the paca. Based on the x86-64 implementation.
9 */
10
11#ifdef CONFIG_SMP
12
13#include <asm/paca.h>
14
15#define __per_cpu_offset(cpu) (paca[cpu].data_offset)
16#define __my_cpu_offset() get_paca()->data_offset
17
18/* Separate out the type, so (int[3], foo) works. */
19#define DEFINE_PER_CPU(type, name) \
20 __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name
21
22/* var is in discarded region: offset to particular copy we want */
23#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu)))
24#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()))
25
26/* A macro to avoid #include hell... */
27#define percpu_modcopy(pcpudst, src, size) \
28do { \
29 unsigned int __i; \
30 for (__i = 0; __i < NR_CPUS; __i++) \
31 if (cpu_possible(__i)) \
32 memcpy((pcpudst)+__per_cpu_offset(__i), \
33 (src), (size)); \
34} while (0)
35
36extern void setup_per_cpu_areas(void);
37
38#else /* ! SMP */
39
40#define DEFINE_PER_CPU(type, name) \
41 __typeof__(type) per_cpu__##name
42
43#define per_cpu(var, cpu) (*((void)(cpu), &per_cpu__##var))
44#define __get_cpu_var(var) per_cpu__##var
45
46#endif /* SMP */
47
48#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
49
50#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var)
51#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var)
52
53#else
1#include <asm-generic/percpu.h> 54#include <asm-generic/percpu.h>
55#endif
56
57#endif /* _ASM_POWERPC_PERCPU_H_ */