s390/nmi: move storage error checking back to C, enter with DAT on
authorHeiko Carstens <hca@linux.ibm.com>
Tue, 29 Nov 2022 16:22:14 +0000 (17:22 +0100)
committerAlexander Gordeev <agordeev@linux.ibm.com>
Tue, 6 Dec 2022 15:18:25 +0000 (16:18 +0100)
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: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
arch/s390/kernel/entry.S
arch/s390/kernel/nmi.c
arch/s390/kernel/setup.c

index d2a1f2f4f5b883edac8d4ae4d5c4afa6107bf80d..e0d11f3adfccd05dfec8fef7dc2b920eef67cf62 100644 (file)
@@ -122,24 +122,6 @@ _LPP_OFFSET        = __LC_LPP
                    "jnz .+8; .insn rrf,0xb2e80000,0,0,13,0", 82
        .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)
        /*
         * The OUTSIDE macro jumps to the provided label in case the value
@@ -546,26 +528,18 @@ ENTRY(mcck_int_handler)
 3:     TSTMSK  __LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID
        jno     .Lmcck_panic
        tmhh    %r8,0x0001              # interrupting from user ?
-       jnz     6f
+       jnz     .Lmcck_user
        TSTMSK  __LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID
        jno     .Lmcck_panic
 #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
        oi      __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
-       j       5f
-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)
+4:     BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
        SIEEXIT
        j       .Lmcck_stack
 #endif
-6:     CHKSTG  .Lmcck_panic
-       larl    %r14,.Lstosm_tmp
-       stosm   0(%r14),0x04            # turn dat on, keep irqs off
-       tmhh    %r8,0x0001              # interrupting from user ?
-       jz      .Lmcck_stack
+.Lmcck_user:
        BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
 .Lmcck_stack:
        lg      %r15,__LC_MCCK_STACK
index b1579c85b8692e94ceb204d0757884db2f5bed17..b54d4aa3385144da8761fb195e2bb42ccf188984 100644 (file)
@@ -487,7 +487,21 @@ int notrace s390_do_machine_check(struct pt_regs *regs)
                        mcck->stp_queue |= stp_island_check();
                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) {
                /* Channel report word pending */
                mcck->channel_report = 1;
index ab19ddb09d65eda37b7214760fd9d549ef9d063e..2094f575c5329470ac3fc57adee3136faa99f8cd 100644 (file)
@@ -437,7 +437,7 @@ static void __init setup_lowcore_dat_off(void)
        lc->svc_new_psw.addr = (unsigned long) system_call;
        lc->program_new_psw.mask = int_psw_mask | PSW_MASK_MCHECK;
        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->io_new_psw.mask = int_psw_mask | PSW_MASK_MCHECK;
        lc->io_new_psw.addr = (unsigned long) io_int_handler;
@@ -512,6 +512,7 @@ static void __init setup_lowcore_dat_on(void)
        S390_lowcore.external_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.mcck_new_psw.mask |= PSW_MASK_DAT;
        S390_lowcore.io_new_psw.mask |= PSW_MASK_DAT;
        __ctl_set_bit(0, 28);
        __ctl_store(S390_lowcore.cregs_save_area, 0, 15);