Skip to content

Commit b0f4c74

Browse files
abrestic-rivospalmer-dabbelt
authored andcommitted
RISC-V: Fix unannoted hardirqs-on in return to userspace slow-path
The return to userspace path in entry.S may enable interrupts without the corresponding lockdep annotation, producing a splat[0] when DEBUG_LOCKDEP is enabled. Simply calling __trace_hardirqs_on() here gets a bit messy due to the use of RA to point back to ret_from_exception, so just move the whole slow-path loop into C. It's more readable and it lets us use local_irq_{enable,disable}(), avoiding the need for manual annotations altogether. [0]: ------------[ cut here ]------------ DEBUG_LOCKS_WARN_ON(!lockdep_hardirqs_enabled()) WARNING: CPU: 2 PID: 1 at kernel/locking/lockdep.c:5512 check_flags+0x10a/0x1e0 Modules linked in: CPU: 2 PID: 1 Comm: init Not tainted 6.1.0-rc4-00160-gb56b6e2b4f31 raspberrypi#53 Hardware name: riscv-virtio,qemu (DT) epc : check_flags+0x10a/0x1e0 ra : check_flags+0x10a/0x1e0 <snip> status: 0000000200000100 badaddr: 0000000000000000 cause: 0000000000000003 [<ffffffff808edb90>] lock_is_held_type+0x78/0x14e [<ffffffff8003dae2>] __might_resched+0x26/0x22c [<ffffffff8003dd24>] __might_sleep+0x3c/0x66 [<ffffffff80022c60>] get_signal+0x9e/0xa70 [<ffffffff800054a2>] do_notify_resume+0x6e/0x422 [<ffffffff80003c68>] ret_from_exception+0x0/0x10 irq event stamp: 44512 hardirqs last enabled at (44511): [<ffffffff808f901c>] _raw_spin_unlock_irqrestore+0x54/0x62 hardirqs last disabled at (44512): [<ffffffff80008200>] __trace_hardirqs_off+0xc/0x14 softirqs last enabled at (44472): [<ffffffff808f9fbe>] __do_softirq+0x3de/0x51e softirqs last disabled at (44467): [<ffffffff80017760>] irq_exit+0xd6/0x104 ---[ end trace 0000000000000000 ]--- possible reason: unannotated irqs-on. Signed-off-by: Andrew Bresticker <[email protected]> Fixes: 3c46979 ("riscv: Enable LOCKDEP_SUPPORT & fixup TRACE_IRQFLAGS_SUPPORT") Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 9abf231 commit b0f4c74

File tree

2 files changed

+26
-26
lines changed

2 files changed

+26
-26
lines changed

arch/riscv/kernel/entry.S

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -263,12 +263,11 @@ ret_from_exception:
263263
#endif
264264
bnez s0, resume_kernel
265265

266-
resume_userspace:
267266
/* Interrupts must be disabled here so flags are checked atomically */
268267
REG_L s0, TASK_TI_FLAGS(tp) /* current_thread_info->flags */
269268
andi s1, s0, _TIF_WORK_MASK
270-
bnez s1, work_pending
271-
269+
bnez s1, resume_userspace_slow
270+
resume_userspace:
272271
#ifdef CONFIG_CONTEXT_TRACKING_USER
273272
call user_enter_callable
274273
#endif
@@ -368,19 +367,12 @@ resume_kernel:
368367
j restore_all
369368
#endif
370369

371-
work_pending:
370+
resume_userspace_slow:
372371
/* Enter slow path for supplementary processing */
373-
la ra, ret_from_exception
374-
andi s1, s0, _TIF_NEED_RESCHED
375-
bnez s1, work_resched
376-
work_notifysig:
377-
/* Handle pending signals and notify-resume requests */
378-
csrs CSR_STATUS, SR_IE /* Enable interrupts for do_notify_resume() */
379372
move a0, sp /* pt_regs */
380373
move a1, s0 /* current_thread_info->flags */
381-
tail do_notify_resume
382-
work_resched:
383-
tail schedule
374+
call do_work_pending
375+
j resume_userspace
384376

385377
/* Slow paths for ptrace. */
386378
handle_syscall_trace_enter:

arch/riscv/kernel/signal.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -313,19 +313,27 @@ static void do_signal(struct pt_regs *regs)
313313
}
314314

315315
/*
316-
* notification of userspace execution resumption
317-
* - triggered by the _TIF_WORK_MASK flags
316+
* Handle any pending work on the resume-to-userspace path, as indicated by
317+
* _TIF_WORK_MASK. Entered from assembly with IRQs off.
318318
*/
319-
asmlinkage __visible void do_notify_resume(struct pt_regs *regs,
320-
unsigned long thread_info_flags)
319+
asmlinkage __visible void do_work_pending(struct pt_regs *regs,
320+
unsigned long thread_info_flags)
321321
{
322-
if (thread_info_flags & _TIF_UPROBE)
323-
uprobe_notify_resume(regs);
324-
325-
/* Handle pending signal delivery */
326-
if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
327-
do_signal(regs);
328-
329-
if (thread_info_flags & _TIF_NOTIFY_RESUME)
330-
resume_user_mode_work(regs);
322+
do {
323+
if (thread_info_flags & _TIF_NEED_RESCHED) {
324+
schedule();
325+
} else {
326+
local_irq_enable();
327+
if (thread_info_flags & _TIF_UPROBE)
328+
uprobe_notify_resume(regs);
329+
/* Handle pending signal delivery */
330+
if (thread_info_flags & (_TIF_SIGPENDING |
331+
_TIF_NOTIFY_SIGNAL))
332+
do_signal(regs);
333+
if (thread_info_flags & _TIF_NOTIFY_RESUME)
334+
resume_user_mode_work(regs);
335+
}
336+
local_irq_disable();
337+
thread_info_flags = read_thread_flags();
338+
} while (thread_info_flags & _TIF_WORK_MASK);
331339
}

0 commit comments

Comments
 (0)