Skip to content

Commit

Permalink
[POWERPC] Make current preempt-safe
Browse files Browse the repository at this point in the history
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 <hugh@veritas.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
  • Loading branch information
Hugh Dickins authored and Paul Mackerras committed Nov 1, 2006
1 parent 302439d commit 5fe8e8b
Showing 1 changed file with 11 additions and 1 deletion.
12 changes: 11 additions & 1 deletion include/asm-powerpc/current.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit 5fe8e8b

Please sign in to comment.