mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-04 01:49:36 +00:00
[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 <hugh@veritas.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
parent
302439d216
commit
5fe8e8b88e
1 changed files with 11 additions and 1 deletions
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue