[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:
parent
0a2966b48f
commit
632bbfeee4
4 changed files with 31 additions and 15 deletions
|
@ -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())
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue