diff options
| author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2008-11-14 12:18:05 -0500 |
|---|---|---|
| committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-11-14 12:18:53 -0500 |
| commit | 50bec4ce5d36ebf96189dcc54e20c7fce4bf61bf (patch) | |
| tree | 5f04e012e882ed15f9c7f1f45b0e9a27dd2656f5 | |
| parent | 632448f65001c4935ed0d3bb362017d773da2eca (diff) | |
[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>
| -rw-r--r-- | arch/s390/kernel/entry.S | 18 | ||||
| -rw-r--r-- | arch/s390/kernel/entry64.S | 11 |
2 files changed, 18 insertions, 11 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 5f0c4fba87c..08844fc24a2 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
| @@ -61,22 +61,25 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
| 61 | 61 | ||
| 62 | #ifdef CONFIG_TRACE_IRQFLAGS | 62 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 63 | .macro TRACE_IRQS_ON | 63 | .macro TRACE_IRQS_ON |
| 64 | l %r1,BASED(.Ltrace_irq_on) | 64 | basr %r2,%r0 |
| 65 | l %r1,BASED(.Ltrace_irq_on_caller) | ||
| 65 | basr %r14,%r1 | 66 | basr %r14,%r1 |
| 66 | .endm | 67 | .endm |
| 67 | 68 | ||
| 68 | .macro TRACE_IRQS_OFF | 69 | .macro TRACE_IRQS_OFF |
| 69 | l %r1,BASED(.Ltrace_irq_off) | 70 | basr %r2,%r0 |
| 71 | l %r1,BASED(.Ltrace_irq_off_caller) | ||
| 70 | basr %r14,%r1 | 72 | basr %r14,%r1 |
| 71 | .endm | 73 | .endm |
| 72 | 74 | ||
| 73 | .macro TRACE_IRQS_CHECK | 75 | .macro TRACE_IRQS_CHECK |
| 76 | basr %r2,%r0 | ||
| 74 | tm SP_PSW(%r15),0x03 # irqs enabled? | 77 | tm SP_PSW(%r15),0x03 # irqs enabled? |
| 75 | jz 0f | 78 | jz 0f |
| 76 | l %r1,BASED(.Ltrace_irq_on) | 79 | l %r1,BASED(.Ltrace_irq_on_caller) |
| 77 | basr %r14,%r1 | 80 | basr %r14,%r1 |
| 78 | j 1f | 81 | j 1f |
| 79 | 0: l %r1,BASED(.Ltrace_irq_off) | 82 | 0: l %r1,BASED(.Ltrace_irq_off_caller) |
| 80 | basr %r14,%r1 | 83 | basr %r14,%r1 |
| 81 | 1: | 84 | 1: |
| 82 | .endm | 85 | .endm |
| @@ -1113,9 +1116,10 @@ cleanup_io_leave_insn: | |||
| 1113 | .Lschedtail: .long schedule_tail | 1116 | .Lschedtail: .long schedule_tail |
| 1114 | .Lsysc_table: .long sys_call_table | 1117 | .Lsysc_table: .long sys_call_table |
| 1115 | #ifdef CONFIG_TRACE_IRQFLAGS | 1118 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 1116 | .Ltrace_irq_on: .long trace_hardirqs_on | 1119 | .Ltrace_irq_on_caller: |
| 1117 | .Ltrace_irq_off: | 1120 | .long trace_hardirqs_on_caller |
| 1118 | .long trace_hardirqs_off | 1121 | .Ltrace_irq_off_caller: |
| 1122 | .long trace_hardirqs_off_caller | ||
| 1119 | #endif | 1123 | #endif |
| 1120 | #ifdef CONFIG_LOCKDEP | 1124 | #ifdef CONFIG_LOCKDEP |
| 1121 | .Llockdep_sys_exit: | 1125 | .Llockdep_sys_exit: |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index d7ce150453f..41aca06682a 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
| @@ -61,19 +61,22 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ | |||
| 61 | 61 | ||
| 62 | #ifdef CONFIG_TRACE_IRQFLAGS | 62 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 63 | .macro TRACE_IRQS_ON | 63 | .macro TRACE_IRQS_ON |
| 64 | brasl %r14,trace_hardirqs_on | 64 | basr %r2,%r0 |
| 65 | brasl %r14,trace_hardirqs_on_caller | ||
| 65 | .endm | 66 | .endm |
| 66 | 67 | ||
| 67 | .macro TRACE_IRQS_OFF | 68 | .macro TRACE_IRQS_OFF |
| 68 | brasl %r14,trace_hardirqs_off | 69 | basr %r2,%r0 |
| 70 | brasl %r14,trace_hardirqs_off_caller | ||
| 69 | .endm | 71 | .endm |
| 70 | 72 | ||
| 71 | .macro TRACE_IRQS_CHECK | 73 | .macro TRACE_IRQS_CHECK |
| 74 | basr %r2,%r0 | ||
| 72 | tm SP_PSW(%r15),0x03 # irqs enabled? | 75 | tm SP_PSW(%r15),0x03 # irqs enabled? |
| 73 | jz 0f | 76 | jz 0f |
| 74 | brasl %r14,trace_hardirqs_on | 77 | brasl %r14,trace_hardirqs_on_caller |
| 75 | j 1f | 78 | j 1f |
| 76 | 0: brasl %r14,trace_hardirqs_off | 79 | 0: brasl %r14,trace_hardirqs_off_caller |
| 77 | 1: | 80 | 1: |
| 78 | .endm | 81 | .endm |
| 79 | #else | 82 | #else |
