From: Hugh Dickins Date: Thu, 4 Jan 2007 20:26:22 +0000 (+0000) Subject: make ppc64 current preempt-safe X-Git-Tag: v2.6.18.8~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f102c840f7f72492a83c93fa65396fe0edcf1df6;p=thirdparty%2Fkernel%2Fstable.git make ppc64 current preempt-safe Repeated -j20 kernel builds on a G5 Quad running an SMP PREEMPT kernel would often collapse within a day, some exec failing with "Bad address". In each case examined, load_elf_binary was doing a kernel_read, but generic_file_aio_read's access_ok saw current->thread.fs.seg as USER_DS instead of KERNEL_DS. objdump of filemap.o shows gcc 4.1.0 emitting "mr r5,r13 ... ld r9,416(r5)" here for get_paca()->__current, instead of the expected and much more usual "ld r9,416(r13)"; I've seen other gcc4s do the same, but perhaps not gcc3s. So, if the task is preempted and rescheduled on a different cpu in between the mr and the ld, r5 will be looking at a different paca_struct from the one it's now on, pick up the wrong __current, and perhaps the wrong seg. Presumably much worse could happen elsewhere, though that split is rare. Other architectures appear to be safe (x86_64's read_pda is more limiting than get_paca), but ppc64 needs to force "current" into one instruction. Signed-off-by: Hugh Dickins Signed-off-by: Chris Wright Signed-off-by: Greg Kroah-Hartman --- diff --git a/include/asm-powerpc/current.h b/include/asm-powerpc/current.h index 1938d6abd2550..b8708aedf9253 100644 --- a/include/asm-powerpc/current.h +++ b/include/asm-powerpc/current.h @@ -14,7 +14,17 @@ struct task_struct; #ifdef __powerpc64__ #include -#define current (get_paca()->__current) +static inline struct task_struct *get_current(void) +{ + struct task_struct *task; + + __asm__ __volatile__("ld %0,%1(13)" + : "=r" (task) + : "i" (offsetof(struct paca_struct, __current))); + + return task; +} +#define current get_current() #else