Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[S390] kernel: Initialize register 14 when starting new CPU

When starting a new CPU we currently jump to start_secondary() without
setting register 14 (the return address) correctly. Therefore on the stack
frame for start_secondary an invalid return address is stored. This leads
to wrong stack back traces in kernel dumps.

Example:

#00 [1f33fe48] cpu_idle at 10614a
#01 [1f33fe90] start_secondary at 54fa88
#02 [1f33feb8] (null) at 0 <--- invalid

To fix this start_secondary() is called now with basr/brasl that sets
register 14 correctly. The output of the stack backtrace looks then
like the following:

#00 [1f33fe48] cpu_idle at 10614a
#01 [1f33fe90] start_secondary at 54fa88
#02 [1f33feb8] restart_base at 54f41e <--- correct

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by

Michael Holzheu and committed by
Martin Schwidefsky
8eb4bd66 aade6c0d

+2 -2
+1 -1
arch/s390/kernel/entry.S
··· 836 836 stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on 837 837 basr %r14,0 838 838 l %r14,restart_addr-.(%r14) 839 - br %r14 # branch to start_secondary 839 + basr %r14,%r14 # branch to start_secondary 840 840 restart_addr: 841 841 .long start_secondary 842 842 .align 8
+1 -1
arch/s390/kernel/entry64.S
··· 841 841 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1) 842 842 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER 843 843 stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on 844 - jg start_secondary 844 + brasl %r14,start_secondary 845 845 .align 8 846 846 restart_vtime: 847 847 .long 0x7fffffff,0xffffffff