diff options
Diffstat (limited to 'include/asm-s390/percpu.h')
-rw-r--r-- | include/asm-s390/percpu.h | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/include/asm-s390/percpu.h b/include/asm-s390/percpu.h new file mode 100644 index 000000000000..123fcaca295e --- /dev/null +++ b/include/asm-s390/percpu.h | |||
@@ -0,0 +1,70 @@ | |||
1 | #ifndef __ARCH_S390_PERCPU__ | ||
2 | #define __ARCH_S390_PERCPU__ | ||
3 | |||
4 | #include <linux/compiler.h> | ||
5 | #include <asm/lowcore.h> | ||
6 | |||
7 | #define __GENERIC_PER_CPU | ||
8 | |||
9 | /* | ||
10 | * s390 uses its own implementation for per cpu data, the offset of | ||
11 | * the cpu local data area is cached in the cpu's lowcore memory. | ||
12 | * For 64 bit module code s390 forces the use of a GOT slot for the | ||
13 | * address of the per cpu variable. This is needed because the module | ||
14 | * may be more than 4G above the per cpu area. | ||
15 | */ | ||
16 | #if defined(__s390x__) && defined(MODULE) | ||
17 | |||
18 | #define __reloc_hide(var,offset) \ | ||
19 | (*({ unsigned long *__ptr; \ | ||
20 | asm ( "larl %0,per_cpu__"#var"@GOTENT" \ | ||
21 | : "=a" (__ptr) : "X" (per_cpu__##var) ); \ | ||
22 | (typeof(&per_cpu__##var))((*__ptr) + (offset)); })) | ||
23 | |||
24 | #else | ||
25 | |||
26 | #define __reloc_hide(var, offset) \ | ||
27 | (*({ unsigned long __ptr; \ | ||
28 | asm ( "" : "=a" (__ptr) : "0" (&per_cpu__##var) ); \ | ||
29 | (typeof(&per_cpu__##var)) (__ptr + (offset)); })) | ||
30 | |||
31 | #endif | ||
32 | |||
33 | #ifdef CONFIG_SMP | ||
34 | |||
35 | extern unsigned long __per_cpu_offset[NR_CPUS]; | ||
36 | |||
37 | /* Separate out the type, so (int[3], foo) works. */ | ||
38 | #define DEFINE_PER_CPU(type, name) \ | ||
39 | __attribute__((__section__(".data.percpu"))) \ | ||
40 | __typeof__(type) per_cpu__##name | ||
41 | |||
42 | #define __get_cpu_var(var) __reloc_hide(var,S390_lowcore.percpu_offset) | ||
43 | #define per_cpu(var,cpu) __reloc_hide(var,__per_cpu_offset[cpu]) | ||
44 | |||
45 | /* A macro to avoid #include hell... */ | ||
46 | #define percpu_modcopy(pcpudst, src, size) \ | ||
47 | do { \ | ||
48 | unsigned int __i; \ | ||
49 | for (__i = 0; __i < NR_CPUS; __i++) \ | ||
50 | if (cpu_possible(__i)) \ | ||
51 | memcpy((pcpudst)+__per_cpu_offset[__i], \ | ||
52 | (src), (size)); \ | ||
53 | } while (0) | ||
54 | |||
55 | #else /* ! SMP */ | ||
56 | |||
57 | #define DEFINE_PER_CPU(type, name) \ | ||
58 | __typeof__(type) per_cpu__##name | ||
59 | |||
60 | #define __get_cpu_var(var) __reloc_hide(var,0) | ||
61 | #define per_cpu(var,cpu) __reloc_hide(var,0) | ||
62 | |||
63 | #endif /* SMP */ | ||
64 | |||
65 | #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name | ||
66 | |||
67 | #define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) | ||
68 | #define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var) | ||
69 | |||
70 | #endif /* __ARCH_S390_PERCPU__ */ | ||