mirror of
https://github.com/torvalds/linux.git
synced 2024-12-05 10:32:35 +00:00
42e19e6f04
Recent test_kprobe_missed kprobes kunit test uncovers the following error
(reported when CONFIG_DEBUG_ATOMIC_SLEEP is enabled):
BUG: sleeping function called from invalid context at kernel/locking/mutex.c:580
in_atomic(): 0, irqs_disabled(): 1, non_block: 0, pid: 662, name: kunit_try_catch
preempt_count: 0, expected: 0
RCU nest depth: 0, expected: 0
no locks held by kunit_try_catch/662.
irq event stamp: 280
hardirqs last enabled at (279): [<00000003e60a3d42>] __do_pgm_check+0x17a/0x1c0
hardirqs last disabled at (280): [<00000003e3bd774a>] kprobe_exceptions_notify+0x27a/0x318
softirqs last enabled at (0): [<00000003e3c5c890>] copy_process+0x14a8/0x4c80
softirqs last disabled at (0): [<0000000000000000>] 0x0
CPU: 46 PID: 662 Comm: kunit_try_catch Tainted: G N 6.2.0-173644-g44c18d77f0c0 #2
Hardware name: IBM 3931 A01 704 (LPAR)
Call Trace:
[<00000003e60a3a00>] dump_stack_lvl+0x120/0x198
[<00000003e3d02e82>] __might_resched+0x60a/0x668
[<00000003e60b9908>] __mutex_lock+0xc0/0x14e0
[<00000003e60bad5a>] mutex_lock_nested+0x32/0x40
[<00000003e3f7b460>] unregister_kprobe+0x30/0xd8
[<00000003e51b2602>] test_kprobe_missed+0xf2/0x268
[<00000003e51b5406>] kunit_try_run_case+0x10e/0x290
[<00000003e51b7dfa>] kunit_generic_run_threadfn_adapter+0x62/0xb8
[<00000003e3ce30f8>] kthread+0x2d0/0x398
[<00000003e3b96afa>] __ret_from_fork+0x8a/0xe8
[<00000003e60ccada>] ret_from_fork+0xa/0x40
The reason for this error report is that kprobes handling code failed
to restore irqs.
The problem is that when kprobe is triggered from another kprobe
post_handler current sequence of enable_singlestep / disable_singlestep
is the following:
enable_singlestep <- original kprobe (saves kprobe_saved_imask)
enable_singlestep <- kprobe triggered from post_handler (clobbers kprobe_saved_imask)
disable_singlestep <- kprobe triggered from post_handler (restores kprobe_saved_imask)
disable_singlestep <- original kprobe (restores wrong clobbered kprobe_saved_imask)
There is just one kprobe_ctlblk per cpu and both calls saves and
loads irq mask to kprobe_saved_imask. To fix the problem simply move
resume_execution (which calls disable_singlestep) before calling
post_handler. This also fixes the problem that post_handler is called
with pt_regs which were not yet adjusted after single-stepping.
Cc: stable@vger.kernel.org
Fixes:
|
||
---|---|---|
.. | ||
syscalls | ||
vdso32 | ||
vdso64 | ||
.gitignore | ||
abs_lowcore.c | ||
alternative.c | ||
asm-offsets.c | ||
audit.c | ||
audit.h | ||
cache.c | ||
compat_audit.c | ||
compat_linux.c | ||
compat_linux.h | ||
compat_ptrace.h | ||
compat_signal.c | ||
cpcmd.c | ||
cpufeature.c | ||
crash_dump.c | ||
debug.c | ||
diag.c | ||
dis.c | ||
dumpstack.c | ||
early_printk.c | ||
early.c | ||
earlypgm.S | ||
ebcdic.c | ||
entry.h | ||
entry.S | ||
fpu.c | ||
ftrace.c | ||
ftrace.h | ||
guarded_storage.c | ||
head64.S | ||
idle.c | ||
ima_arch.c | ||
ipl_vmparm.c | ||
ipl.c | ||
irq.c | ||
jump_label.c | ||
kdebugfs.c | ||
kexec_elf.c | ||
kexec_image.c | ||
kprobes_insn_page.S | ||
kprobes.c | ||
kprobes.h | ||
lgr.c | ||
machine_kexec_file.c | ||
machine_kexec_reloc.c | ||
machine_kexec.c | ||
Makefile | ||
mcount.S | ||
module.c | ||
nmi.c | ||
nospec-branch.c | ||
nospec-sysfs.c | ||
numa.c | ||
os_info.c | ||
perf_cpum_cf_events.c | ||
perf_cpum_cf.c | ||
perf_cpum_sf.c | ||
perf_event.c | ||
perf_pai_crypto.c | ||
perf_pai_ext.c | ||
perf_regs.c | ||
process.c | ||
processor.c | ||
ptrace.c | ||
reipl.S | ||
relocate_kernel.S | ||
rethook.c | ||
rethook.h | ||
runtime_instr.c | ||
setup.c | ||
signal.c | ||
smp.c | ||
stacktrace.c | ||
sthyi.c | ||
syscall.c | ||
sysinfo.c | ||
text_amode31.S | ||
time.c | ||
topology.c | ||
trace.c | ||
traps.c | ||
unwind_bc.c | ||
uprobes.c | ||
uv.c | ||
vdso.c | ||
vmlinux.lds.S | ||
vtime.c |