aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>2010-04-20 10:38:10 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-04-26 10:48:03 -0400
commite6813c83b2ef1fe0abb88fca3c4dfc4c5a01f473 (patch)
treee989ca1cb01b3aeadc03828f742dc6430921151d
parenteabe8c241a9ecbc15a9d51e0bfc3dde1c27d8a65 (diff)
module: fix __module_ref_addr()
The __module_ref_addr() problem disappears in 2.6.34-rc kernels because these percpu accesses were re-factored. __module_ref_addr() should use per_cpu_ptr() to obfuscate the pointer (RELOC_HIDE is needed for per cpu pointers). This non-standard per-cpu pointer use has been introduced by commit 720eba31f47aeade8ec130ca7f4353223c49170f It causes a NULL pointer exception on some configurations when CONFIG_TRACING is enabled on 2.6.33. This patch fixes the problem (acknowledged by Randy who reported the bug). It did not appear to hurt previously because most of the accesses were done through local_inc, which probably obfuscated the access enough that no compiler optimizations were done. But with local_read() done when CONFIG_TRACING is active, this becomes a problem. Non-CONFIG_TRACING is probably affected as well (module.c contains local_set and local_read that use __module_ref_addr()), but I guess nobody noticed because we've been lucky enough that the compiler did not generate the inappropriate optimization pattern there. This patch should be queued for the 2.6.29.x through 2.6.33.x stable branches. (tested on 2.6.33.1 x86_64) Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Tested-by: Randy Dunlap <randy.dunlap@oracle.com> CC: Eric Dumazet <dada1@cosmosbay.com> CC: Rusty Russell <rusty@rustcorp.com.au> CC: Peter Zijlstra <a.p.zijlstra@chello.nl> CC: Tejun Heo <tj@kernel.org> CC: Ingo Molnar <mingo@elte.hu> CC: Andrew Morton <akpm@linux-foundation.org> CC: Linus Torvalds <torvalds@linux-foundation.org> CC: Greg Kroah-Hartman <gregkh@suse.de> CC: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--include/linux/module.h2
1 files changed, 1 insertions, 1 deletions
diff --git a/include/linux/module.h b/include/linux/module.h
index 6cb1a3cab5d3..bd465d47216a 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -457,7 +457,7 @@ void symbol_put_addr(void *addr);
457static inline local_t *__module_ref_addr(struct module *mod, int cpu) 457static inline local_t *__module_ref_addr(struct module *mod, int cpu)
458{ 458{
459#ifdef CONFIG_SMP 459#ifdef CONFIG_SMP
460 return (local_t *) (mod->refptr + per_cpu_offset(cpu)); 460 return (local_t *) per_cpu_ptr(mod->refptr, cpu);
461#else 461#else
462 return &mod->ref; 462 return &mod->ref;
463#endif 463#endif