summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Blunck <jblunck@suse.de>2006-09-25 23:30:53 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-26 08:48:44 -0700
commit632bbfeee4f042c05bc65150b4433a297d3fe387 (patch)
treece67b5fa4bec38610fc0ecb9b20be6aa69763bb3
parent0a2966b48fb784e437520e400ddc94874ddbd4e8 (diff)
downloadlinux-632bbfeee4f042c05bc65150b4433a297d3fe387.tar.gz
linux-632bbfeee4f042c05bc65150b4433a297d3fe387.tar.bz2
linux-632bbfeee4f042c05bc65150b4433a297d3fe387.zip
[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];
__attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name
/* var is in discarded region: offset to particular copy we want */
-#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]))
+#define per_cpu(var, cpu) (*({ \
+ extern int simple_indentifier_##var(void); \
+ RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); }))
#define __get_cpu_var(var) per_cpu(var, smp_processor_id())
#define __raw_get_cpu_var(var) per_cpu(var, raw_smp_processor_id())
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 @@
*/
#if defined(__s390x__) && defined(MODULE)
-#define __reloc_hide(var,offset) \
- (*({ unsigned long *__ptr; \
- asm ( "larl %0,per_cpu__"#var"@GOTENT" \
- : "=a" (__ptr) : "X" (per_cpu__##var) ); \
- (typeof(&per_cpu__##var))((*__ptr) + (offset)); }))
+#define __reloc_hide(var,offset) (*({ \
+ extern int simple_indentifier_##var(void); \
+ unsigned long *__ptr; \
+ asm ( "larl %0,per_cpu__"#var"@GOTENT" \
+ : "=a" (__ptr) : "X" (per_cpu__##var) ); \
+ (typeof(&per_cpu__##var))((*__ptr) + (offset)); }))
#else
-#define __reloc_hide(var, offset) \
- (*({ unsigned long __ptr; \
- asm ( "" : "=a" (__ptr) : "0" (&per_cpu__##var) ); \
- (typeof(&per_cpu__##var)) (__ptr + (offset)); }))
+#define __reloc_hide(var, offset) (*({ \
+ extern int simple_indentifier_##var(void); \
+ unsigned long __ptr; \
+ asm ( "" : "=a" (__ptr) : "0" (&per_cpu__##var) ); \
+ (typeof(&per_cpu__##var)) (__ptr + (offset)); }))
#endif
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 @@
__attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name
/* var is in discarded region: offset to particular copy we want */
-#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu)))
-#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()))
-#define __raw_get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()))
+#define per_cpu(var, cpu) (*({ \
+ extern int simple_indentifier_##var(void); \
+ RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu)); }))
+#define __get_cpu_var(var) (*({ \
+ extern int simple_indentifier_##var(void); \
+ RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()); }))
+#define __raw_get_cpu_var(var) (*({ \
+ extern int simple_indentifier_##var(void); \
+ RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()); }))
/* A macro to avoid #include hell... */
#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 @@
#define PERCPU_ENOUGH_ROOM 32768
#endif
-/* Must be an lvalue. */
-#define get_cpu_var(var) (*({ preempt_disable(); &__get_cpu_var(var); }))
+/*
+ * Must be an lvalue. Since @var must be a simple identifier,
+ * we force a syntax error here if it isn't.
+ */
+#define get_cpu_var(var) (*({ \
+ extern int simple_indentifier_##var(void); \
+ preempt_disable(); \
+ &__get_cpu_var(var); }))
#define put_cpu_var(var) preempt_enable()
#ifdef CONFIG_SMP