From 7c3bc39f3bf8c348c35864e1fcd13520a621a374 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 3 Jan 2014 14:10:35 +1100 Subject: [PATCH] futex: switch to USER_DS for futex test Since e4f2dfbb5e92b ("m68k: implement futex.h to support userspace robust futexes and PI mutexes"), the kernel crashes during boot up on MC68030: Data read fault at 0x00000000 in Super Data (pc=0x3afec) BAD KERNEL BUSERR Oops: 00000000 Modules linked in: PC: [<0003afec>] cmpxchg_futex_value_locked+0x14/0x4a SR: 2004 SP: 0082fed4 a2: 0082c000 d0: 00000000 d1: 00000001 d2: 00000018 d3: 00000000 d4: 00000061 d5: 00001000 a0: 00000000 a1: 0082e000 Process swapper (pid: 1, task=0082c000) Frame format=B ssw=074d isc=4a80 isb=661c daddr=00000000 dobuf=00000001 baddr=0003aff2 dibuf=00000000 ver=f Stack from 0082ff5c: 002b8cb8 0082ff70 00000000 00000000 00000000 00000000 00000000 000020ac 00000018 00000007 00000061 00001000 00000000 00000000 002cab50 00002008 002b3a56 002b8ca4 0082c3f0 00000000 0082c53c 001e316a 00000000 00000000 001e3172 001e316a 000025d4 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 20000000 00000000 Call Trace: [<002b8cb8>] futex_init+0x14/0x54 [<000020ac>] do_one_initcall+0xa4/0x144 [<00001000>] kernel_pg_dir+0x0/0x1000 [<00002008>] do_one_initcall+0x0/0x144 [<002b3a56>] kernel_init_freeable+0xca/0x152 [<002b8ca4>] futex_init+0x0/0x54 [<001e316a>] kernel_init+0x0/0xc8 [<001e3172>] kernel_init+0x8/0xc8 [<001e316a>] kernel_init+0x0/0xc8 [<000025d4>] ret_from_kernel_thread+0xc/0x14 This happens because the futex test in futex_init() lacks a switch to the USER_DS address space, while cmpxchg_futex_value_locked() and futex_atomic_cmpxchg_inatomic() operate on userspace pointers (albeit NULL for this particular test). Fix this by switching to USER_DS before running the test, and restoring the old address space afterwards. Bisected by Finn Thain. Reported-by: Tuxist Reported-by: Patrick McCarthy Suggested-by: Andreas Schwab Tested-by: Finn Thain Signed-off-by: Geert Uytterhoeven Cc: Rusty Russell Cc: Thomas Gleixner Cc: Darren Hart Cc: Signed-off-by: Andrew Morton --- kernel/futex.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kernel/futex.c b/kernel/futex.c index f6ff0191ecf7..66d23727c6ab 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -63,6 +63,7 @@ #include #include #include +#include #include @@ -2733,6 +2734,7 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val, static int __init futex_init(void) { + mm_segment_t fs; u32 curval; int i; @@ -2746,8 +2748,11 @@ static int __init futex_init(void) * implementation, the non-functional ones will return * -ENOSYS. */ + fs = get_fs(); + set_fs(USER_DS); if (cmpxchg_futex_value_locked(&curval, NULL, 0, 0) == -EFAULT) futex_cmpxchg_enabled = 1; + set_fs(fs); for (i = 0; i < ARRAY_SIZE(futex_queues); i++) { plist_head_init(&futex_queues[i].chain); -- 2.39.5