do_signal() does __put_user() which can fault, resulting in a might_sleep()
warning in down_read(&mm->mmap_sem) and a "scheduling while atomic" warning
when mmap_sem is contented. On Swarm this also results in:
WARNING: at kernel/smp.c:459 smp_call_function_many+0x148/0x398()
Modules linked in:
Call Trace:
[<
ffffffff804b48a4>] dump_stack+0x1c/0x50
[<
ffffffff8013dc94>] warn_slowpath_common+0x8c/0xc8
[<
ffffffff8013dcfc>] warn_slowpath_null+0x2c/0x40
[<
ffffffff801864a0>] smp_call_function_many+0x148/0x398
[<
ffffffff80186748>] smp_call_function+0x58/0xa8
[<
ffffffff80119b5c>] r4k_flush_data_cache_page+0x54/0xd8
[<
ffffffff801f39bc>] handle_pte_fault+0xa9c/0xad0
[<
ffffffff801f40d0>] handle_mm_fault+0x158/0x200
[<
ffffffff80115548>] do_page_fault+0x218/0x3b0
[<
ffffffff80102744>] ret_from_exception+0x0/0x10
[<
ffffffff8010eb18>] copy_siginfo_to_user32+0x50/0x298
[<
ffffffff8010edf0>] setup_rt_frame_32+0x90/0x250
[<
ffffffff80106414>] do_notify_resume+0x154/0x358
[<
ffffffff80102930>] work_notifysig+0xc/0x14
Fixed by enabling interrupts in do_notify_resume before delivering signals.
[ralf@linux-mips.org: Reported and original fix by tglx but I wanted to
minimize the amount of code being run with interrupts disabled so I moved
the local_irq_disable() call right into do_notify_resume. Which is saner
than doing it in entry.S.]
Reported-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/
#include <linux/cache.h>
+#include <linux/irqflags.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/personality.h>
asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
__u32 thread_info_flags)
{
+ local_irq_enable();
+
/* deal with pending signal delivery */
if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
do_signal(regs);