Author: lcapitulino
Date: Tue Feb 13 14:07:12 2007
New Revision: 120386
Added:
packages/updates/2007.0/kernel-2.6/current/PATCHES/patches/CA79_ppc64_make_current_preempt_safe.patch
Modified:
packages/updates/2007.0/kernel-2.6/current/SPECS/kernel-2.6.spec
Log:
PowerPC: Make current preempt-safe (thanks to Hugh Dickins <[EMAIL PROTECTED]>)
Added:
packages/updates/2007.0/kernel-2.6/current/PATCHES/patches/CA79_ppc64_make_current_preempt_safe.patch
==============================================================================
--- (empty file)
+++
packages/updates/2007.0/kernel-2.6/current/PATCHES/patches/CA79_ppc64_make_current_preempt_safe.patch
Tue Feb 13 14:07:12 2007
@@ -0,0 +1,43 @@
+[POWERPC] Make 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 <[EMAIL PROTECTED]>
+
+--- 2.6.17.14/include/asm-powerpc/current.h 2006-03-20 05:53:29.000000000
+0000
++++ linux/include/asm-powerpc/current.h 2007-01-24 18:03:26.000000000
+0000
+@@ -14,7 +14,17 @@ struct task_struct;
+ #ifdef __powerpc64__
+ #include <asm/paca.h>
+
+-#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
+
Modified: packages/updates/2007.0/kernel-2.6/current/SPECS/kernel-2.6.spec
==============================================================================
--- packages/updates/2007.0/kernel-2.6/current/SPECS/kernel-2.6.spec
(original)
+++ packages/updates/2007.0/kernel-2.6/current/SPECS/kernel-2.6.spec Tue Feb
13 14:07:12 2007
@@ -1045,6 +1045,8 @@
<[EMAIL PROTECTED]>)
- Fix umask when noACL kernel meets extN tuned for ACLs
(thanks to Hugh Dickins <[EMAIL PROTECTED]>)
+ - PowerPC: Make current preempt-safe (thanks to Hugh Dickins
+ <[EMAIL PROTECTED]>)
* Fri Feb 02 2007 Luiz Capitulino <[EMAIL PROTECTED]> 2.6.17-10mdv2007.0
o Gwenole Beauchesne <[EMAIL PROTECTED]>