Просмотр исходного кода

[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>
Heiko Carstens 16 лет назад
Родитель
Сommit
50bec4ce5d
2 измененных файлов с 18 добавлено и 11 удалено
  1. 11 7
      arch/s390/kernel/entry.S
  2. 7 4
      arch/s390/kernel/entry64.S

+ 11 - 7
arch/s390/kernel/entry.S

@@ -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_off:
-		.long	trace_hardirqs_off
+.Ltrace_irq_on_caller:
+		.long	trace_hardirqs_on_caller
+.Ltrace_irq_off_caller:
+		.long	trace_hardirqs_off_caller
 #endif
 #endif
 #ifdef CONFIG_LOCKDEP
 #ifdef CONFIG_LOCKDEP
 .Llockdep_sys_exit:
 .Llockdep_sys_exit:

+ 7 - 4
arch/s390/kernel/entry64.S

@@ -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