From 0597840564d09d897e993a462ae1707addf6aacc Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 29 Oct 2009 22:34:15 +0900 Subject: [PATCH] --- yaml --- r: 185009 b: refs/heads/master c: 545695fb41da117928ab946067a42d9e15fd009d h: refs/heads/master i: 185007: 1221306828aaae2571dc855bde48d063179c9f4e v: v3 --- [refs] | 2 +- trunk/include/asm-generic/percpu.h | 6 ++++-- trunk/include/linux/percpu-defs.h | 20 ++++++++++++++++++-- trunk/include/linux/percpu.h | 2 ++ 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index 56edd9fc10e8..7f747012eee8 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e0fdb0e050eae331046385643618f12452aa7e73 +refs/heads/master: 545695fb41da117928ab946067a42d9e15fd009d diff --git a/trunk/include/asm-generic/percpu.h b/trunk/include/asm-generic/percpu.h index fded453fd25c..04f91c2d3f7b 100644 --- a/trunk/include/asm-generic/percpu.h +++ b/trunk/include/asm-generic/percpu.h @@ -42,8 +42,10 @@ extern unsigned long __per_cpu_offset[NR_CPUS]; */ #ifndef SHIFT_PERCPU_PTR /* Weird cast keeps both GCC and sparse happy. */ -#define SHIFT_PERCPU_PTR(__p, __offset) \ - RELOC_HIDE((typeof(*(__p)) __kernel __force *)(__p), (__offset)) +#define SHIFT_PERCPU_PTR(__p, __offset) ({ \ + __verify_pcpu_ptr((__p)); \ + RELOC_HIDE((typeof(*(__p)) __kernel __force *)(__p), (__offset)); \ +}) #endif /* diff --git a/trunk/include/linux/percpu-defs.h b/trunk/include/linux/percpu-defs.h index 0fa0cb524250..1fa36eb54b6a 100644 --- a/trunk/include/linux/percpu-defs.h +++ b/trunk/include/linux/percpu-defs.h @@ -18,6 +18,16 @@ #define __PCPU_DUMMY_ATTRS \ __attribute__((section(".discard"), unused)) +/* + * Macro which verifies @ptr is a percpu pointer without evaluating + * @ptr. This is to be used in percpu accessors to verify that the + * input parameter is a percpu pointer. + */ +#define __verify_pcpu_ptr(ptr) do { \ + void __percpu *__vpp_verify = (typeof(ptr))NULL; \ + (void)__vpp_verify; \ +} while (0) + /* * s390 and alpha modules require percpu variables to be defined as * weak to force the compiler to generate GOT based external @@ -129,10 +139,16 @@ __aligned(PAGE_SIZE) /* - * Intermodule exports for per-CPU variables. + * Intermodule exports for per-CPU variables. sparse forgets about + * address space across EXPORT_SYMBOL(), change EXPORT_SYMBOL() to + * noop if __CHECKER__. */ +#ifndef __CHECKER__ #define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(var) #define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(var) - +#else +#define EXPORT_PER_CPU_SYMBOL(var) +#define EXPORT_PER_CPU_SYMBOL_GPL(var) +#endif #endif /* _LINUX_PERCPU_DEFS_H */ diff --git a/trunk/include/linux/percpu.h b/trunk/include/linux/percpu.h index 2c0d31a3f6b6..42878f0cd0e2 100644 --- a/trunk/include/linux/percpu.h +++ b/trunk/include/linux/percpu.h @@ -237,6 +237,7 @@ extern void __bad_size_call_parameter(void); #define __pcpu_size_call_return(stem, variable) \ ({ typeof(variable) pscr_ret__; \ + __verify_pcpu_ptr(&(variable)); \ switch(sizeof(variable)) { \ case 1: pscr_ret__ = stem##1(variable);break; \ case 2: pscr_ret__ = stem##2(variable);break; \ @@ -250,6 +251,7 @@ extern void __bad_size_call_parameter(void); #define __pcpu_size_call(stem, variable, ...) \ do { \ + __verify_pcpu_ptr(&(variable)); \ switch(sizeof(variable)) { \ case 1: stem##1(variable, __VA_ARGS__);break; \ case 2: stem##2(variable, __VA_ARGS__);break; \