[S390] ftrace: fix kernel stack backchain walking
With CONFIG_IRQSOFF_TRACER the trace_hardirqs_off() function includes a call to __builtin_return_address(1). But we calltrace_hardirqs_off() from early entry code. There we have just a single stack frame. So this results in a kernel stack backchain walk that would walk beyond the kernel stack. Following the NULL terminated backchain this results in a lowcore read access. To fix this we simply call trace_hardirqs_off_caller() and pass the current instruction pointer. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
committed by
Martin Schwidefsky
parent
632448f650
commit
50bec4ce5d
@@ -61,22 +61,25 @@ STACK_SIZE = 1 << STACK_SHIFT
|
|||||||
|
|
||||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
.macro TRACE_IRQS_ON
|
.macro TRACE_IRQS_ON
|
||||||
l %r1,BASED(.Ltrace_irq_on)
|
basr %r2,%r0
|
||||||
|
l %r1,BASED(.Ltrace_irq_on_caller)
|
||||||
basr %r14,%r1
|
basr %r14,%r1
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro TRACE_IRQS_OFF
|
.macro TRACE_IRQS_OFF
|
||||||
l %r1,BASED(.Ltrace_irq_off)
|
basr %r2,%r0
|
||||||
|
l %r1,BASED(.Ltrace_irq_off_caller)
|
||||||
basr %r14,%r1
|
basr %r14,%r1
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro TRACE_IRQS_CHECK
|
.macro TRACE_IRQS_CHECK
|
||||||
|
basr %r2,%r0
|
||||||
tm SP_PSW(%r15),0x03 # irqs enabled?
|
tm SP_PSW(%r15),0x03 # irqs enabled?
|
||||||
jz 0f
|
jz 0f
|
||||||
l %r1,BASED(.Ltrace_irq_on)
|
l %r1,BASED(.Ltrace_irq_on_caller)
|
||||||
basr %r14,%r1
|
basr %r14,%r1
|
||||||
j 1f
|
j 1f
|
||||||
0: l %r1,BASED(.Ltrace_irq_off)
|
0: l %r1,BASED(.Ltrace_irq_off_caller)
|
||||||
basr %r14,%r1
|
basr %r14,%r1
|
||||||
1:
|
1:
|
||||||
.endm
|
.endm
|
||||||
@@ -1113,9 +1116,10 @@ cleanup_io_leave_insn:
|
|||||||
.Lschedtail: .long schedule_tail
|
.Lschedtail: .long schedule_tail
|
||||||
.Lsysc_table: .long sys_call_table
|
.Lsysc_table: .long sys_call_table
|
||||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
.Ltrace_irq_on: .long trace_hardirqs_on
|
.Ltrace_irq_on_caller:
|
||||||
.Ltrace_irq_off:
|
.long trace_hardirqs_on_caller
|
||||||
.long trace_hardirqs_off
|
.Ltrace_irq_off_caller:
|
||||||
|
.long trace_hardirqs_off_caller
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_LOCKDEP
|
#ifdef CONFIG_LOCKDEP
|
||||||
.Llockdep_sys_exit:
|
.Llockdep_sys_exit:
|
||||||
|
@@ -61,19 +61,22 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
|
|||||||
|
|
||||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
.macro TRACE_IRQS_ON
|
.macro TRACE_IRQS_ON
|
||||||
brasl %r14,trace_hardirqs_on
|
basr %r2,%r0
|
||||||
|
brasl %r14,trace_hardirqs_on_caller
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro TRACE_IRQS_OFF
|
.macro TRACE_IRQS_OFF
|
||||||
brasl %r14,trace_hardirqs_off
|
basr %r2,%r0
|
||||||
|
brasl %r14,trace_hardirqs_off_caller
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro TRACE_IRQS_CHECK
|
.macro TRACE_IRQS_CHECK
|
||||||
|
basr %r2,%r0
|
||||||
tm SP_PSW(%r15),0x03 # irqs enabled?
|
tm SP_PSW(%r15),0x03 # irqs enabled?
|
||||||
jz 0f
|
jz 0f
|
||||||
brasl %r14,trace_hardirqs_on
|
brasl %r14,trace_hardirqs_on_caller
|
||||||
j 1f
|
j 1f
|
||||||
0: brasl %r14,trace_hardirqs_off
|
0: brasl %r14,trace_hardirqs_off_caller
|
||||||
1:
|
1:
|
||||||
.endm
|
.endm
|
||||||
#else
|
#else
|
||||||
|
Reference in New Issue
Block a user