aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Blunck <jblunck@suse.de>2006-09-26 02:30:53 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-26 11:48:44 -0400
commit632bbfeee4f042c05bc65150b4433a297d3fe387 (patch)
treece67b5fa4bec38610fc0ecb9b20be6aa69763bb3
parent0a2966b48fb784e437520e400ddc94874ddbd4e8 (diff)
[PATCH] trigger a syntax error if percpu macros are incorrectly used
get_cpu_var()/per_cpu()/__get_cpu_var() arguments must be simple identifiers. Otherwise the arch dependent implementations might break. This patch enforces the correct usage of the macros by producing a syntax error if the variable is not a simple identifier. Signed-off-by: Jan Blunck <jblunck@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--include/asm-generic/percpu.h4
-rw-r--r--include/asm-s390/percpu.h20
-rw-r--r--include/asm-x86_64/percpu.h12
-rw-r--r--include/linux/percpu.h10
4 files changed, 31 insertions, 15 deletions
diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h
index e160e04290fb..6d45ee5472af 100644
--- a/include/asm-generic/percpu.h
+++ b/include/asm-generic/percpu.h
@@ -14,7 +14,9 @@ extern unsigned long __per_cpu_offset[NR_CPUS];
14 __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name 14 __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name
15 15
16/* var is in discarded region: offset to particular copy we want */ 16/* var is in discarded region: offset to particular copy we want */
17#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu])) 17#define per_cpu(var, cpu) (*({ \
18 extern int simple_indentifier_##var(void); \
19 RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); }))
18#define __get_cpu_var(var) per_cpu(var, smp_processor_id()) 20#define __get_cpu_var(var) per_cpu(var, smp_processor_id())
19#define __raw_get_cpu_var(var) per_cpu(var, raw_smp_processor_id()) 21#define __raw_get_cpu_var(var) per_cpu(var, raw_smp_processor_id())
20 22
diff --git a/include/asm-s390/percpu.h b/include/asm-s390/percpu.h
index 28b3517e787c..495ad99c7635 100644
--- a/include/asm-s390/percpu.h
+++ b/include/asm-s390/percpu.h
@@ -15,18 +15,20 @@
15 */ 15 */
16#if defined(__s390x__) && defined(MODULE) 16#if defined(__s390x__) && defined(MODULE)
17 17
18#define __reloc_hide(var,offset) \ 18#define __reloc_hide(var,offset) (*({ \
19 (*({ unsigned long *__ptr; \ 19 extern int simple_indentifier_##var(void); \
20 asm ( "larl %0,per_cpu__"#var"@GOTENT" \ 20 unsigned long *__ptr; \
21 : "=a" (__ptr) : "X" (per_cpu__##var) ); \ 21 asm ( "larl %0,per_cpu__"#var"@GOTENT" \
22 (typeof(&per_cpu__##var))((*__ptr) + (offset)); })) 22 : "=a" (__ptr) : "X" (per_cpu__##var) ); \
23 (typeof(&per_cpu__##var))((*__ptr) + (offset)); }))
23 24
24#else 25#else
25 26
26#define __reloc_hide(var, offset) \ 27#define __reloc_hide(var, offset) (*({ \
27 (*({ unsigned long __ptr; \ 28 extern int simple_indentifier_##var(void); \
28 asm ( "" : "=a" (__ptr) : "0" (&per_cpu__##var) ); \ 29 unsigned long __ptr; \
29 (typeof(&per_cpu__##var)) (__ptr + (offset)); })) 30 asm ( "" : "=a" (__ptr) : "0" (&per_cpu__##var) ); \
31 (typeof(&per_cpu__##var)) (__ptr + (offset)); }))
30 32
31#endif 33#endif
32 34
diff --git a/include/asm-x86_64/percpu.h b/include/asm-x86_64/percpu.h
index 08dd9f9dda81..bffb2f886a51 100644
--- a/include/asm-x86_64/percpu.h
+++ b/include/asm-x86_64/percpu.h
@@ -21,9 +21,15 @@
21 __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name 21 __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name
22 22
23/* var is in discarded region: offset to particular copy we want */ 23/* var is in discarded region: offset to particular copy we want */
24#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu))) 24#define per_cpu(var, cpu) (*({ \
25#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __my_cpu_offset())) 25 extern int simple_indentifier_##var(void); \
26#define __raw_get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __my_cpu_offset())) 26 RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu)); }))
27#define __get_cpu_var(var) (*({ \
28 extern int simple_indentifier_##var(void); \
29 RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()); }))
30#define __raw_get_cpu_var(var) (*({ \
31 extern int simple_indentifier_##var(void); \
32 RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()); }))
27 33
28/* A macro to avoid #include hell... */ 34/* A macro to avoid #include hell... */
29#define percpu_modcopy(pcpudst, src, size) \ 35#define percpu_modcopy(pcpudst, src, size) \
diff --git a/include/linux/percpu.h b/include/linux/percpu.h
index cb9039a21f2a..f926490a7d8b 100644
--- a/include/linux/percpu.h
+++ b/include/linux/percpu.h
@@ -11,8 +11,14 @@
11#define PERCPU_ENOUGH_ROOM 32768 11#define PERCPU_ENOUGH_ROOM 32768
12#endif 12#endif
13 13
14/* Must be an lvalue. */ 14/*
15#define get_cpu_var(var) (*({ preempt_disable(); &__get_cpu_var(var); })) 15 * Must be an lvalue. Since @var must be a simple identifier,
16 * we force a syntax error here if it isn't.
17 */
18#define get_cpu_var(var) (*({ \
19 extern int simple_indentifier_##var(void); \
20 preempt_disable(); \
21 &__get_cpu_var(var); }))
16#define put_cpu_var(var) preempt_enable() 22#define put_cpu_var(var) preempt_enable()
17 23
18#ifdef CONFIG_SMP 24#ifdef CONFIG_SMP