[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>
This commit is contained in:
Jan Blunck 2006-09-25 23:30:53 -07:00 committed by Linus Torvalds
parent 0a2966b48f
commit 632bbfeee4
4 changed files with 31 additions and 15 deletions

View File

@ -14,7 +14,9 @@ extern unsigned long __per_cpu_offset[NR_CPUS];
__attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name
/* var is in discarded region: offset to particular copy we want */ /* 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 __get_cpu_var(var) per_cpu(var, smp_processor_id())
#define __raw_get_cpu_var(var) per_cpu(var, raw_smp_processor_id()) #define __raw_get_cpu_var(var) per_cpu(var, raw_smp_processor_id())

View File

@ -15,18 +15,20 @@
*/ */
#if defined(__s390x__) && defined(MODULE) #if defined(__s390x__) && defined(MODULE)
#define __reloc_hide(var,offset) \ #define __reloc_hide(var,offset) (*({ \
(*({ unsigned long *__ptr; \ extern int simple_indentifier_##var(void); \
asm ( "larl %0,per_cpu__"#var"@GOTENT" \ unsigned long *__ptr; \
: "=a" (__ptr) : "X" (per_cpu__##var) ); \ asm ( "larl %0,per_cpu__"#var"@GOTENT" \
(typeof(&per_cpu__##var))((*__ptr) + (offset)); })) : "=a" (__ptr) : "X" (per_cpu__##var) ); \
(typeof(&per_cpu__##var))((*__ptr) + (offset)); }))
#else #else
#define __reloc_hide(var, offset) \ #define __reloc_hide(var, offset) (*({ \
(*({ unsigned long __ptr; \ extern int simple_indentifier_##var(void); \
asm ( "" : "=a" (__ptr) : "0" (&per_cpu__##var) ); \ unsigned long __ptr; \
(typeof(&per_cpu__##var)) (__ptr + (offset)); })) asm ( "" : "=a" (__ptr) : "0" (&per_cpu__##var) ); \
(typeof(&per_cpu__##var)) (__ptr + (offset)); }))
#endif #endif

View File

@ -21,9 +21,15 @@
__attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name
/* var is in discarded region: offset to particular copy we want */ /* 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) (*({ \
#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __my_cpu_offset())) extern int simple_indentifier_##var(void); \
#define __raw_get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __my_cpu_offset())) 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... */ /* A macro to avoid #include hell... */
#define percpu_modcopy(pcpudst, src, size) \ #define percpu_modcopy(pcpudst, src, size) \

View File

@ -11,8 +11,14 @@
#define PERCPU_ENOUGH_ROOM 32768 #define PERCPU_ENOUGH_ROOM 32768
#endif #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() #define put_cpu_var(var) preempt_enable()
#ifdef CONFIG_SMP #ifdef CONFIG_SMP