diff options
-rw-r--r-- | include/asm-generic/percpu.h | 6 | ||||
-rw-r--r-- | include/linux/percpu-defs.h | 20 | ||||
-rw-r--r-- | include/linux/percpu.h | 2 |
3 files changed, 24 insertions, 4 deletions
diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h index fded453fd25c..04f91c2d3f7b 100644 --- a/include/asm-generic/percpu.h +++ b/include/asm-generic/percpu.h | |||
@@ -42,8 +42,10 @@ extern unsigned long __per_cpu_offset[NR_CPUS]; | |||
42 | */ | 42 | */ |
43 | #ifndef SHIFT_PERCPU_PTR | 43 | #ifndef SHIFT_PERCPU_PTR |
44 | /* Weird cast keeps both GCC and sparse happy. */ | 44 | /* Weird cast keeps both GCC and sparse happy. */ |
45 | #define SHIFT_PERCPU_PTR(__p, __offset) \ | 45 | #define SHIFT_PERCPU_PTR(__p, __offset) ({ \ |
46 | RELOC_HIDE((typeof(*(__p)) __kernel __force *)(__p), (__offset)) | 46 | __verify_pcpu_ptr((__p)); \ |
47 | RELOC_HIDE((typeof(*(__p)) __kernel __force *)(__p), (__offset)); \ | ||
48 | }) | ||
47 | #endif | 49 | #endif |
48 | 50 | ||
49 | /* | 51 | /* |
diff --git a/include/linux/percpu-defs.h b/include/linux/percpu-defs.h index 0fa0cb524250..1fa36eb54b6a 100644 --- a/include/linux/percpu-defs.h +++ b/include/linux/percpu-defs.h | |||
@@ -19,6 +19,16 @@ | |||
19 | __attribute__((section(".discard"), unused)) | 19 | __attribute__((section(".discard"), unused)) |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * Macro which verifies @ptr is a percpu pointer without evaluating | ||
23 | * @ptr. This is to be used in percpu accessors to verify that the | ||
24 | * input parameter is a percpu pointer. | ||
25 | */ | ||
26 | #define __verify_pcpu_ptr(ptr) do { \ | ||
27 | void __percpu *__vpp_verify = (typeof(ptr))NULL; \ | ||
28 | (void)__vpp_verify; \ | ||
29 | } while (0) | ||
30 | |||
31 | /* | ||
22 | * s390 and alpha modules require percpu variables to be defined as | 32 | * s390 and alpha modules require percpu variables to be defined as |
23 | * weak to force the compiler to generate GOT based external | 33 | * weak to force the compiler to generate GOT based external |
24 | * references for them. This is necessary because percpu sections | 34 | * references for them. This is necessary because percpu sections |
@@ -129,10 +139,16 @@ | |||
129 | __aligned(PAGE_SIZE) | 139 | __aligned(PAGE_SIZE) |
130 | 140 | ||
131 | /* | 141 | /* |
132 | * Intermodule exports for per-CPU variables. | 142 | * Intermodule exports for per-CPU variables. sparse forgets about |
143 | * address space across EXPORT_SYMBOL(), change EXPORT_SYMBOL() to | ||
144 | * noop if __CHECKER__. | ||
133 | */ | 145 | */ |
146 | #ifndef __CHECKER__ | ||
134 | #define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(var) | 147 | #define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(var) |
135 | #define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(var) | 148 | #define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(var) |
136 | 149 | #else | |
150 | #define EXPORT_PER_CPU_SYMBOL(var) | ||
151 | #define EXPORT_PER_CPU_SYMBOL_GPL(var) | ||
152 | #endif | ||
137 | 153 | ||
138 | #endif /* _LINUX_PERCPU_DEFS_H */ | 154 | #endif /* _LINUX_PERCPU_DEFS_H */ |
diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 2c0d31a3f6b6..42878f0cd0e2 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h | |||
@@ -237,6 +237,7 @@ extern void __bad_size_call_parameter(void); | |||
237 | 237 | ||
238 | #define __pcpu_size_call_return(stem, variable) \ | 238 | #define __pcpu_size_call_return(stem, variable) \ |
239 | ({ typeof(variable) pscr_ret__; \ | 239 | ({ typeof(variable) pscr_ret__; \ |
240 | __verify_pcpu_ptr(&(variable)); \ | ||
240 | switch(sizeof(variable)) { \ | 241 | switch(sizeof(variable)) { \ |
241 | case 1: pscr_ret__ = stem##1(variable);break; \ | 242 | case 1: pscr_ret__ = stem##1(variable);break; \ |
242 | case 2: pscr_ret__ = stem##2(variable);break; \ | 243 | case 2: pscr_ret__ = stem##2(variable);break; \ |
@@ -250,6 +251,7 @@ extern void __bad_size_call_parameter(void); | |||
250 | 251 | ||
251 | #define __pcpu_size_call(stem, variable, ...) \ | 252 | #define __pcpu_size_call(stem, variable, ...) \ |
252 | do { \ | 253 | do { \ |
254 | __verify_pcpu_ptr(&(variable)); \ | ||
253 | switch(sizeof(variable)) { \ | 255 | switch(sizeof(variable)) { \ |
254 | case 1: stem##1(variable, __VA_ARGS__);break; \ | 256 | case 1: stem##1(variable, __VA_ARGS__);break; \ |
255 | case 2: stem##2(variable, __VA_ARGS__);break; \ | 257 | case 2: stem##2(variable, __VA_ARGS__);break; \ |