[PATCH] trigger a syntax error if percpu macros are incorrectly used
authorJan Blunck <jblunck@suse.de>
Tue, 26 Sep 2006 06:30:53 +0000 (23:30 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Tue, 26 Sep 2006 15:48:44 +0000 (08:48 -0700)
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>
include/asm-generic/percpu.h
include/asm-s390/percpu.h
include/asm-x86_64/percpu.h
include/linux/percpu.h

index e160e04290fb9ed2e0977e0a460a49ec18f62a81..6d45ee5472aff9668de59dbefb9ea8e3e8d53391 100644 (file)
@@ -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())
 
index 28b3517e787cd141d8c778e37cff68f143b6bf53..495ad99c76351c005ed6f95977902b4c2ea4f53f 100644 (file)
  */
 #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
 
index 08dd9f9dda81854dc1b222dacd24ef209e6be29f..bffb2f886a510256974c679095186af021537c3c 100644 (file)
     __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)                     \
index cb9039a21f2a7da99b05f9e8d00b930ab7108a6f..f926490a7d8baca01974332070bb486de4d4b366 100644 (file)
 #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