Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 632bbfee authored by Jan Blunck's avatar Jan Blunck Committed by Linus Torvalds
Browse files

[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: default avatarJan Blunck <jblunck@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 0a2966b4
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -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())

+11 −9
Original line number Diff line number Diff line
@@ -15,16 +15,18 @@
 */
#if defined(__s390x__) && defined(MODULE)

#define __reloc_hide(var,offset) \
  (*({ unsigned long *__ptr; \
#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; \
#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)); }))

+9 −3
Original line number Diff line number Diff line
@@ -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)			\
+8 −2
Original line number Diff line number Diff line
@@ -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