aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStafford Horne <shorne@gmail.com>2017-07-24 08:55:16 -0400
committerStafford Horne <shorne@gmail.com>2017-11-03 01:01:16 -0400
commit78cdfb5cf15e0f9fb4c2a9176a13a907a1d024f0 (patch)
treeaba15bb0ca2fab3ec50d75d48944bc209589ac99
parenteecac38b0423a69715073ecbde581dafd1abb28b (diff)
openrisc: enable LOCKDEP_SUPPORT and irqflags tracing
Lockdep is needed for proving the spinlocks and rwlocks work fine on our platform. It also requires calling the trace_hardirqs_off() and trace_hardirqs_on() pair of routines when entering and exiting an interrupt. For OpenRISC the interrupt stack frame does not support frame pointers, so to call trace_hardirqs_on() and trace_hardirqs_off() here the macro's build up a stack frame each time. There is one necessary small change in _sys_call_handler to move interrupt enabling later so they can get re-enabled during syscall restart. This was done to fix lockdep warnings that are now possible due to this patch. Signed-off-by: Stafford Horne <shorne@gmail.com>
-rw-r--r--arch/openrisc/Kconfig3
-rw-r--r--arch/openrisc/kernel/entry.S74
2 files changed, 74 insertions, 3 deletions
diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig
index 399f55e82dcb..f8cfb3ba9e89 100644
--- a/arch/openrisc/Kconfig
+++ b/arch/openrisc/Kconfig
@@ -64,6 +64,9 @@ config GENERIC_CSUM
64config STACKTRACE_SUPPORT 64config STACKTRACE_SUPPORT
65 def_bool y 65 def_bool y
66 66
67config LOCKDEP_SUPPORT
68 def_bool y
69
67source "init/Kconfig" 70source "init/Kconfig"
68 71
69source "kernel/Kconfig.freezer" 72source "kernel/Kconfig.freezer"
diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S
index 1b7160c79646..690d55272ba6 100644
--- a/arch/openrisc/kernel/entry.S
+++ b/arch/openrisc/kernel/entry.S
@@ -42,6 +42,61 @@
42 42
43/* =========================================================[ macros ]=== */ 43/* =========================================================[ macros ]=== */
44 44
45#ifdef CONFIG_TRACE_IRQFLAGS
46/*
47 * Trace irq on/off creating a stack frame.
48 */
49#define TRACE_IRQS_OP(trace_op) \
50 l.sw -8(r1),r2 /* store frame pointer */ ;\
51 l.sw -4(r1),r9 /* store return address */ ;\
52 l.addi r2,r1,0 /* move sp to fp */ ;\
53 l.jal trace_op ;\
54 l.addi r1,r1,-8 ;\
55 l.ori r1,r2,0 /* restore sp */ ;\
56 l.lwz r9,-4(r1) /* restore return address */ ;\
57 l.lwz r2,-8(r1) /* restore fp */ ;\
58/*
59 * Trace irq on/off and save registers we need that would otherwise be
60 * clobbered.
61 */
62#define TRACE_IRQS_SAVE(t1,trace_op) \
63 l.sw -12(r1),t1 /* save extra reg */ ;\
64 l.sw -8(r1),r2 /* store frame pointer */ ;\
65 l.sw -4(r1),r9 /* store return address */ ;\
66 l.addi r2,r1,0 /* move sp to fp */ ;\
67 l.jal trace_op ;\
68 l.addi r1,r1,-12 ;\
69 l.ori r1,r2,0 /* restore sp */ ;\
70 l.lwz r9,-4(r1) /* restore return address */ ;\
71 l.lwz r2,-8(r1) /* restore fp */ ;\
72 l.lwz t1,-12(r1) /* restore extra reg */
73
74#define TRACE_IRQS_OFF TRACE_IRQS_OP(trace_hardirqs_off)
75#define TRACE_IRQS_ON TRACE_IRQS_OP(trace_hardirqs_on)
76#define TRACE_IRQS_ON_SYSCALL \
77 TRACE_IRQS_SAVE(r10,trace_hardirqs_on) ;\
78 l.lwz r3,PT_GPR3(r1) ;\
79 l.lwz r4,PT_GPR4(r1) ;\
80 l.lwz r5,PT_GPR5(r1) ;\
81 l.lwz r6,PT_GPR6(r1) ;\
82 l.lwz r7,PT_GPR7(r1) ;\
83 l.lwz r8,PT_GPR8(r1) ;\
84 l.lwz r11,PT_GPR11(r1)
85#define TRACE_IRQS_OFF_ENTRY \
86 l.lwz r5,PT_SR(r1) ;\
87 l.andi r3,r5,(SPR_SR_IEE|SPR_SR_TEE) ;\
88 l.sfeq r5,r0 /* skip trace if irqs were already off */;\
89 l.bf 1f ;\
90 l.nop ;\
91 TRACE_IRQS_SAVE(r4,trace_hardirqs_off) ;\
921:
93#else
94#define TRACE_IRQS_OFF
95#define TRACE_IRQS_ON
96#define TRACE_IRQS_OFF_ENTRY
97#define TRACE_IRQS_ON_SYSCALL
98#endif
99
45/* 100/*
46 * We need to disable interrupts at beginning of RESTORE_ALL 101 * We need to disable interrupts at beginning of RESTORE_ALL
47 * since interrupt might come in after we've loaded EPC return address 102 * since interrupt might come in after we've loaded EPC return address
@@ -124,6 +179,7 @@ handler: ;\
124 /* r30 already save */ ;\ 179 /* r30 already save */ ;\
125/* l.sw PT_GPR30(r1),r30*/ ;\ 180/* l.sw PT_GPR30(r1),r30*/ ;\
126 l.sw PT_GPR31(r1),r31 ;\ 181 l.sw PT_GPR31(r1),r31 ;\
182 TRACE_IRQS_OFF_ENTRY ;\
127 /* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\ 183 /* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\
128 l.addi r30,r0,-1 ;\ 184 l.addi r30,r0,-1 ;\
129 l.sw PT_ORIG_GPR11(r1),r30 185 l.sw PT_ORIG_GPR11(r1),r30
@@ -557,9 +613,6 @@ _string_syscall_return:
557 .align 4 613 .align 4
558 614
559ENTRY(_sys_call_handler) 615ENTRY(_sys_call_handler)
560 /* syscalls run with interrupts enabled */
561 ENABLE_INTERRUPTS(r29) // enable interrupts, r29 is temp
562
563 /* r1, EPCR, ESR a already saved */ 616 /* r1, EPCR, ESR a already saved */
564 l.sw PT_GPR2(r1),r2 617 l.sw PT_GPR2(r1),r2
565 /* r3-r8 must be saved because syscall restart relies 618 /* r3-r8 must be saved because syscall restart relies
@@ -597,6 +650,10 @@ ENTRY(_sys_call_handler)
597/* l.sw PT_GPR30(r1),r30 */ 650/* l.sw PT_GPR30(r1),r30 */
598 651
599_syscall_check_trace_enter: 652_syscall_check_trace_enter:
653 /* syscalls run with interrupts enabled */
654 TRACE_IRQS_ON_SYSCALL
655 ENABLE_INTERRUPTS(r29) // enable interrupts, r29 is temp
656
600 /* If TIF_SYSCALL_TRACE is set, then we want to do syscall tracing */ 657 /* If TIF_SYSCALL_TRACE is set, then we want to do syscall tracing */
601 l.lwz r30,TI_FLAGS(r10) 658 l.lwz r30,TI_FLAGS(r10)
602 l.andi r30,r30,_TIF_SYSCALL_TRACE 659 l.andi r30,r30,_TIF_SYSCALL_TRACE
@@ -657,6 +714,7 @@ _syscall_check_trace_leave:
657_syscall_check_work: 714_syscall_check_work:
658 /* Here we need to disable interrupts */ 715 /* Here we need to disable interrupts */
659 DISABLE_INTERRUPTS(r27,r29) 716 DISABLE_INTERRUPTS(r27,r29)
717 TRACE_IRQS_OFF
660 l.lwz r30,TI_FLAGS(r10) 718 l.lwz r30,TI_FLAGS(r10)
661 l.andi r30,r30,_TIF_WORK_MASK 719 l.andi r30,r30,_TIF_WORK_MASK
662 l.sfne r30,r0 720 l.sfne r30,r0
@@ -871,6 +929,7 @@ UNHANDLED_EXCEPTION(_vector_0x1f00,0x1f00)
871 929
872_resume_userspace: 930_resume_userspace:
873 DISABLE_INTERRUPTS(r3,r4) 931 DISABLE_INTERRUPTS(r3,r4)
932 TRACE_IRQS_OFF
874 l.lwz r4,TI_FLAGS(r10) 933 l.lwz r4,TI_FLAGS(r10)
875 l.andi r13,r4,_TIF_WORK_MASK 934 l.andi r13,r4,_TIF_WORK_MASK
876 l.sfeqi r13,0 935 l.sfeqi r13,0
@@ -909,6 +968,15 @@ _work_pending:
909 l.lwz r8,PT_GPR8(r1) 968 l.lwz r8,PT_GPR8(r1)
910 969
911_restore_all: 970_restore_all:
971#ifdef CONFIG_TRACE_IRQFLAGS
972 l.lwz r4,PT_SR(r1)
973 l.andi r3,r4,(SPR_SR_IEE|SPR_SR_TEE)
974 l.sfeq r3,r0 /* skip trace if irqs were off */
975 l.bf skip_hardirqs_on
976 l.nop
977 TRACE_IRQS_ON
978skip_hardirqs_on:
979#endif
912 RESTORE_ALL 980 RESTORE_ALL
913 /* This returns to userspace code */ 981 /* This returns to userspace code */
914 982