Skip to content

Commit a720e36

Browse files
clementlegerd3athjest3r
authored andcommitted
k1c: Add LOCKDEP support
Summary: In order to enable lockdep support, we need a compelte TRACE_IRQFLAGS support. While enabled previously, there no trace_hardirqs support leading to various errors when enabling PROVE_LOCKING. This patch adds necessary calls to trace_hardirqs_on/off in assembly to correctly track irqs state when entering exceptions. During testing, a problem arose when calling trace_hardirqs_off indirectly from module: ``` ------------[ cut here ]------------ WARNING: CPU: 0 PID: 59 at kernel/locking/lockdep.c:4329 check_flags.part.23+0x23c/0x240 DEBUG_LOCKS_WARN_ON(current->hardirqs_enabled) Modules linked in: crc32c_generic(+) loop ext4 crc16 mbcache jbd2 crypto_hash crypto_algapi crypto m) CPU: 0 PID: 59 Comm: modprobe Tainted: G O 5.3.0 torvalds#135 Hardware name: Kalray HAPS prototyping (LS) (DT) ... Call Trace: [<ffffff80007816e8>] dump_stack+0x30/0x50 [<ffffff8000216c98>] __warn+0x138/0x158 [<ffffff8000216d10>] warn_slowpath_fmt+0x58/0x78 [<ffffff800026224c>] check_flags.part.23+0x23c/0x240 [<ffffff800026649c>] lock_is_held_type+0x1a4/0x1b0 [<ffffff8000282dd0>] rcu_read_lock_sched_held+0x88/0x90 [<ffffff80002a2fac>] module_assert_mutex_or_preempt+0x2c/0x98 [<ffffff80002a3988>] __module_address+0x48/0x150 [<ffffff80002a3ab0>] __module_text_address+0x20/0xb0 [<ffffff80002a7900>] is_module_text_address+0x18/0x38 [<ffffff800023be04>] kernel_text_address+0x8c/0xb8 [<ffffff800023be50>] __kernel_text_address+0x20/0x90 [<ffffff800020ded8>] walk_stackframe+0x78/0xe0 [<ffffff800020e5e8>] return_address+0x58/0x90 [<ffffff80002c3650>] trace_hardirqs_off+0x68/0x1b8 [<ffffff800036912c>] kfree+0xe4/0x328 [<ffffff8040087c3c>] crypto_larval_destroy+0x54/0x78 [crypto] [<ffffff8040087464>] crypto_larval_kill+0xd4/0xf8 [crypto] [<ffffff804008080c>] crypto_wait_for_test+0x9c/0x108 [crypto_algapi] [<ffffff8040080e24>] crypto_register_alg+0xdc/0xe8 [crypto_algapi] [<ffffff804008d308>] crypto_register_shash+0x48/0x70 [crypto_hash] [<ffffff8040096030>] crc32c_mod_init+0x30/0x4c [crc32c_generic] [<ffffff80002099d8>] do_one_initcall+0x70/0x2b0 [<ffffff80002a7ed4>] do_init_module+0x74/0x270 [<ffffff80002a6a04>] load_module+0x223c/0x26f0 [<ffffff80002a70c8>] sys_finit_module+0xb0/0x118 irq event stamp: 1989 hardirqs last enabled at (1989): [<ffffff80007a8854>] _raw_spin_unlock_irqrestore+0x8c/0xa0 hardirqs last disabled at (1988): [<ffffff80007a861c>] _raw_spin_lock_irqsave+0x34/0x88 softirqs last enabled at (1940): [<ffffff80007ab04c>] _etext+0x38c/0x2340 softirqs last disabled at (1935): [<ffffff800021c754>] irq_exit+0xa4/0xa8 ---[ end trace f667df957dc78eed ]--- possible reason: unannotated irqs-off. ``` Problem is due to the fact trace_hardirqs_off used CALLER_ADDR0 and CALLER_ADDR1. These macros indirectly uses return_addr. Then in walk_stackframe, address of frame pointer ra is checked to be a kernel address using __kernel_text_address. In this function, __module_address take a lock which trigger a hardirqs check that fails. However, since we are calling it to report that trace_hardirqs are off, this is triggering a check before even tracking that irqs are off. Remove the call to __kernel_text_address as it is also not done on arm64. Ref T10401 Test Plan: Executed both smp & valid images on FPGA and verified that there are no signaled lockdep errors. Note that this can't run on debug image since the overhead to call trace_hardirqs_on in exception does not leave any time for normal code to execute. Reviewers: O51 Linux Coolidge, gthouvenin Reviewed By: O51 Linux Coolidge, gthouvenin Subscribers: gthouvenin, jcpince, alfred, #linux_coolidge_cc Maniphest Tasks: T10401 Differential Revision: https://phab.kalray.eu/D2034
1 parent 028eece commit a720e36

File tree

5 files changed

+44
-4
lines changed

5 files changed

+44
-4
lines changed

arch/k1c/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ config ZONE_DMA32
3939
config STACKTRACE_SUPPORT
4040
def_bool y
4141

42+
config LOCKDEP_SUPPORT
43+
def_bool y
44+
4245
config TRACE_IRQFLAGS_SUPPORT
4346
def_bool y
4447

arch/k1c/kernel/entry.S

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,17 @@ asn_error_panic_str_label:
6464
.string "ASN mismatch !"
6565
#endif
6666

67+
/**
68+
* call_trace_hardirqs: hardirqs tracing call
69+
* state: State of hardirqs to be reported (on/off)
70+
*/
71+
.macro call_trace_hardirqs state
72+
#ifdef CONFIG_TRACE_IRQFLAGS
73+
call trace_hardirqs_\state
74+
;;
75+
#endif
76+
.endm
77+
6778
/**
6879
* disable_interrupts: Disable interrupts
6980
* tmp_reg: Temporary register to use for interrupt disabling
@@ -79,6 +90,7 @@ asn_error_panic_str_label:
7990
* call_do_work_pending: Call do_work_pending and set stack argument ($r0)
8091
* NOTE: Since do_work_pending requires thread_flags in $r1, they must
8192
* be provided in $r1 before calling this macro.
93+
* Moreover, do_work_pending expects interrupts to be disabled.
8294
*/
8395
.macro call_do_work_pending
8496
copyd $r0 = $sp
@@ -221,10 +233,15 @@ asn_error_panic_str_label:
221233
make $fp = 0
222234
/* Reenable hwloop and clear exception taken */
223235
make $r8 = PS_HWLOOP_EN_ET_EN
224-
copyd \pt_regs_sp = $sp
225236
;;
226237
wfxl $ps, $r8
227238
;;
239+
/* When entering exceptions, IRQs are always disabled */
240+
call_trace_hardirqs off
241+
;;
242+
/* Copy regs stack pointer for macro caller */
243+
copyd \pt_regs_sp = $sp
244+
;;
228245
#ifdef CONFIG_DEBUG_EXCEPTION_STACK
229246
addd $sp = $sp, -REG_SIZE
230247
;;
@@ -289,7 +306,22 @@ _check_ok:
289306
;;
290307
call_do_work_pending
291308
;;
309+
#ifdef CONFIG_TRACE_IRQFLAGS
310+
/* reload sps value from saved registers */
311+
ld $r6 = PT_SPS[$sp]
312+
;;
313+
#endif
292314
_restore_regs:
315+
#ifdef CONFIG_TRACE_IRQFLAGS
316+
/* Check if IRQs are going to be reenable in next context */
317+
andd $r6 = $r6, K1C_SFR_SPS_IE_MASK
318+
;;
319+
cb.deqz $r6? 1f
320+
;;
321+
call trace_hardirqs_on
322+
;;
323+
1:
324+
#endif
293325
lo $r0r1r2r3 = PT_CS_SPC_SPS_ES[$sp]
294326
;;
295327
lo $r4r5r6r7 = PT_LC_LE_LS_RA[$sp]
@@ -1136,6 +1168,9 @@ call_work_pending:
11361168
;;
11371169
call_do_work_pending
11381170
;;
1171+
/* Since we are returning to user, interrupts will be reenabled */
1172+
call_trace_hardirqs on
1173+
;;
11391174
goto ret_to_user
11401175
;;
11411176

arch/k1c/kernel/signal.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,13 @@ asmlinkage void do_signal(struct pt_regs *regs)
242242
restore_saved_sigmask();
243243
}
244244

245+
245246
asmlinkage void do_work_pending(struct pt_regs *regs,
246247
unsigned long thread_flags)
247248
{
249+
/* We are called with IRQs disabled */
250+
trace_hardirqs_off();
251+
248252
do {
249253
if (thread_flags & _TIF_NEED_RESCHED) {
250254
schedule();

arch/k1c/kernel/smpboot.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ void __init start_kernel_secondary(void)
114114

115115
notify_cpu_starting(cpu);
116116
set_cpu_online(cpu, true);
117+
trace_hardirqs_off();
117118

118119
local_flush_tlb_all();
119120

arch/k1c/kernel/stacktrace.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,6 @@ void notrace walk_stackframe(struct task_struct *task, struct stackframe *frame,
5555
while (1) {
5656
addr = frame->ra;
5757

58-
if (unlikely(!__kernel_text_address(addr)))
59-
break;
60-
6158
if (fn(addr, arg))
6259
break;
6360

0 commit comments

Comments
 (0)