diff options
author | Vasily Gorbik <gor@linux.ibm.com> | 2019-08-08 13:50:02 +0200 |
---|---|---|
committer | Vasily Gorbik <gor@linux.ibm.com> | 2019-08-21 12:41:43 +0200 |
commit | da9ed30d29c48233cec4a19e2bd794bcaa230341 (patch) | |
tree | 3462d3cdb9d48817dcf7e293e90e51f0c8435c2e /arch/s390 | |
parent | 40e90656c13587c0826e8afeef3cebe585db2d2c (diff) |
s390/startup: add initial pgm check handler
The startup code is getting more complicated with features like kaslr and
secure boot in place. In a potential unexpected startup code crash case
the system would end up in a pgm check loop at address 0, overwriting
pgm check old psw value and just making debugging more complicated. To
avoid that introduce startup program check handler which is active
immediately after kernel start and until early_pgm_check_handler is set
in kernel/early.c. So it covers kernel relocation phase and transition
to it. This pgm check handler simply saves general/control registers and
psw in the save area which should guarantee that we still have something
to look at when standalone dumper is called without saving registers. And
it does disabled wait with a faulty address in the end.
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/boot/head.S | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/arch/s390/boot/head.S b/arch/s390/boot/head.S index 2087bed6e60f..5b79ae7b44f3 100644 --- a/arch/s390/boot/head.S +++ b/arch/s390/boot/head.S @@ -60,8 +60,10 @@ __HEAD .long 0x02000690,0x60000050 .long 0x020006e0,0x20000050 - .org 0x1a0 + .org __LC_RST_NEW_PSW # 0x1a0 .quad 0,iplstart + .org __LC_PGM_NEW_PSW # 0x1d0 + .quad 0x0000000180000000,startup_pgm_check_handler .org 0x200 @@ -352,6 +354,26 @@ ENTRY(startup_kdump) #include "head_kdump.S" # +# This program check is active immediately after kernel start +# and until early_pgm_check_handler is set in kernel/early.c +# It simply saves general/control registers and psw in +# the save area and does disabled wait with a faulty address. +# +ENTRY(startup_pgm_check_handler) + stmg %r0,%r15,__LC_SAVE_AREA_SYNC + la %r1,4095 + stctg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r1) + mvc __LC_GPREGS_SAVE_AREA-4095(128,%r1),__LC_SAVE_AREA_SYNC + mvc __LC_PSW_SAVE_AREA-4095(16,%r1),__LC_PGM_OLD_PSW + lg %r1,__LC_SAVE_AREA_SYNC+8 + mvc __LC_RETURN_PSW(16),__LC_PGM_OLD_PSW + ni __LC_RETURN_PSW,0xfc # remove IO and EX bits + ni __LC_RETURN_PSW+1,0xfb # remove MCHK bit + oi __LC_RETURN_PSW+1,0x2 # set wait state bit + lpswe __LC_RETURN_PSW # disabled wait +ENDPROC(startup_pgm_check_handler) + +# # params at 10400 (setup.h) # Must be keept in sync with struct parmarea in setup.h # |