Commit 742aed05 authored by Heiko Carstens's avatar Heiko Carstens Committed by Alexander Gordeev

s390/nmi: move storage error checking back to C, enter with DAT on

Checking for storage errors in machine check entry code was done in order
to handle also storage errors on kernel page tables. However this is
extremely unlikely and some basic assumptions what works on machine check
entry are necessary anyway. In order to simplify machine check handling
delay checking for storage errors to C code.
With this also change the machine check new PSW to have DAT on, which
simplifies the entry code even further.
Reviewed-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
parent 506faa5b
...@@ -122,24 +122,6 @@ _LPP_OFFSET = __LC_LPP ...@@ -122,24 +122,6 @@ _LPP_OFFSET = __LC_LPP
"jnz .+8; .insn rrf,0xb2e80000,0,0,13,0", 82 "jnz .+8; .insn rrf,0xb2e80000,0,0,13,0", 82
.endm .endm
/*
* The CHKSTG macro jumps to the provided label in case the
* machine check interruption code reports one of unrecoverable
* storage errors:
* - Storage error uncorrected
* - Storage key error uncorrected
* - Storage degradation with Failing-storage-address validity
*/
.macro CHKSTG errlabel
TSTMSK __LC_MCCK_CODE,(MCCK_CODE_STG_ERROR|MCCK_CODE_STG_KEY_ERROR)
jnz \errlabel
TSTMSK __LC_MCCK_CODE,MCCK_CODE_STG_DEGRAD
jz .Loklabel\@
TSTMSK __LC_MCCK_CODE,MCCK_CODE_STG_FAIL_ADDR
jnz \errlabel
.Loklabel\@:
.endm
#if IS_ENABLED(CONFIG_KVM) #if IS_ENABLED(CONFIG_KVM)
/* /*
* The OUTSIDE macro jumps to the provided label in case the value * The OUTSIDE macro jumps to the provided label in case the value
...@@ -546,26 +528,18 @@ ENTRY(mcck_int_handler) ...@@ -546,26 +528,18 @@ ENTRY(mcck_int_handler)
3: TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID 3: TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID
jno .Lmcck_panic jno .Lmcck_panic
tmhh %r8,0x0001 # interrupting from user ? tmhh %r8,0x0001 # interrupting from user ?
jnz 6f jnz .Lmcck_user
TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID
jno .Lmcck_panic jno .Lmcck_panic
#if IS_ENABLED(CONFIG_KVM) #if IS_ENABLED(CONFIG_KVM)
OUTSIDE %r9,.Lsie_gmap,.Lsie_done,6f OUTSIDE %r9,.Lsie_gmap,.Lsie_done,.Lmcck_stack
OUTSIDE %r9,.Lsie_entry,.Lsie_leave,4f OUTSIDE %r9,.Lsie_entry,.Lsie_leave,4f
oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
j 5f 4: BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
4: CHKSTG .Lmcck_panic
5: larl %r14,.Lstosm_tmp
stosm 0(%r14),0x04 # turn dat on, keep irqs off
BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
SIEEXIT SIEEXIT
j .Lmcck_stack j .Lmcck_stack
#endif #endif
6: CHKSTG .Lmcck_panic .Lmcck_user:
larl %r14,.Lstosm_tmp
stosm 0(%r14),0x04 # turn dat on, keep irqs off
tmhh %r8,0x0001 # interrupting from user ?
jz .Lmcck_stack
BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
.Lmcck_stack: .Lmcck_stack:
lg %r15,__LC_MCCK_STACK lg %r15,__LC_MCCK_STACK
......
...@@ -487,7 +487,21 @@ int notrace s390_do_machine_check(struct pt_regs *regs) ...@@ -487,7 +487,21 @@ int notrace s390_do_machine_check(struct pt_regs *regs)
mcck->stp_queue |= stp_island_check(); mcck->stp_queue |= stp_island_check();
mcck_pending = 1; mcck_pending = 1;
} }
/*
* Reinject storage related machine checks into the guest if they
* happen when the guest is running.
*/
if (!test_cpu_flag(CIF_MCCK_GUEST)) {
/* Storage error uncorrected */
if (mci.se)
s390_handle_damage();
/* Storage key-error uncorrected */
if (mci.ke)
s390_handle_damage();
/* Storage degradation */
if (mci.ds && mci.fa)
s390_handle_damage();
}
if (mci.cp) { if (mci.cp) {
/* Channel report word pending */ /* Channel report word pending */
mcck->channel_report = 1; mcck->channel_report = 1;
......
...@@ -437,7 +437,7 @@ static void __init setup_lowcore_dat_off(void) ...@@ -437,7 +437,7 @@ static void __init setup_lowcore_dat_off(void)
lc->svc_new_psw.addr = (unsigned long) system_call; lc->svc_new_psw.addr = (unsigned long) system_call;
lc->program_new_psw.mask = int_psw_mask | PSW_MASK_MCHECK; lc->program_new_psw.mask = int_psw_mask | PSW_MASK_MCHECK;
lc->program_new_psw.addr = (unsigned long) pgm_check_handler; lc->program_new_psw.addr = (unsigned long) pgm_check_handler;
lc->mcck_new_psw.mask = PSW_KERNEL_BITS; lc->mcck_new_psw.mask = int_psw_mask;
lc->mcck_new_psw.addr = (unsigned long) mcck_int_handler; lc->mcck_new_psw.addr = (unsigned long) mcck_int_handler;
lc->io_new_psw.mask = int_psw_mask | PSW_MASK_MCHECK; lc->io_new_psw.mask = int_psw_mask | PSW_MASK_MCHECK;
lc->io_new_psw.addr = (unsigned long) io_int_handler; lc->io_new_psw.addr = (unsigned long) io_int_handler;
...@@ -512,6 +512,7 @@ static void __init setup_lowcore_dat_on(void) ...@@ -512,6 +512,7 @@ static void __init setup_lowcore_dat_on(void)
S390_lowcore.external_new_psw.mask |= PSW_MASK_DAT; S390_lowcore.external_new_psw.mask |= PSW_MASK_DAT;
S390_lowcore.svc_new_psw.mask |= PSW_MASK_DAT; S390_lowcore.svc_new_psw.mask |= PSW_MASK_DAT;
S390_lowcore.program_new_psw.mask |= PSW_MASK_DAT; S390_lowcore.program_new_psw.mask |= PSW_MASK_DAT;
S390_lowcore.mcck_new_psw.mask |= PSW_MASK_DAT;
S390_lowcore.io_new_psw.mask |= PSW_MASK_DAT; S390_lowcore.io_new_psw.mask |= PSW_MASK_DAT;
__ctl_set_bit(0, 28); __ctl_set_bit(0, 28);
__ctl_store(S390_lowcore.cregs_save_area, 0, 15); __ctl_store(S390_lowcore.cregs_save_area, 0, 15);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment