s390/mcck: move storage error checks to assembler
authorAlexander Gordeev <agordeev@linux.ibm.com>
Fri, 18 Jun 2021 06:17:16 +0000 (08:17 +0200)
committerVasily Gorbik <gor@linux.ibm.com>
Mon, 5 Jul 2021 10:44:23 +0000 (12:44 +0200)
The current storage errors tackling is wrong - the DAT is
enabled in assembler code before the actual storage checks
in C half are executed. In case the page tables themselves
are damaged such approach is not going to work.

With this update unrecoverable storage errors are not
passed to C code for handling, but rather the machine
is stopped right away. The only exception to this flow
is when a machine check occurred in KVM guest - in this
case the errors are reinjected by the handler.

Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
arch/s390/include/asm/nmi.h
arch/s390/kernel/entry.S
arch/s390/kernel/nmi.c

index 20e51c9ff2403de4dd43b0064447be26cc9eac3e..5e1307486984f861e1b78052e2977e539e0bdfd9 100644 (file)
 #define MCCK_CODE_EXT_DAMAGE           BIT(63 - 5)
 #define MCCK_CODE_CP                   BIT(63 - 9)
 #define MCCK_CODE_CPU_TIMER_VALID      BIT(63 - 46)
+#define MCCK_CODE_STG_ERROR            BIT(63 - 16)
+#define MCCK_CODE_STG_KEY_ERROR                BIT(63 - 18)
+#define MCCK_CODE_STG_DEGRAD           BIT(63 - 19)
 #define MCCK_CODE_PSW_MWP_VALID                BIT(63 - 20)
 #define MCCK_CODE_PSW_IA_VALID         BIT(63 - 23)
+#define MCCK_CODE_STG_FAIL_ADDR                BIT(63 - 24)
 #define MCCK_CODE_CR_VALID             BIT(63 - 29)
 #define MCCK_CODE_GS_VALID             BIT(63 - 36)
 #define MCCK_CODE_FC_VALID             BIT(63 - 43)
index 6bc8ed80045895aaa0b40ad124e28881d771dc92..8f72a8f9bc333a131b1f1e5e78ec47cb2e579aed 100644 (file)
@@ -129,6 +129,24 @@ _LPP_OFFSET        = __LC_LPP
                    "jnz .+8; .long 0xb2e8d000", 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      oklabel\@
+       TSTMSK  __LC_MCCK_CODE,MCCK_CODE_STG_FAIL_ADDR
+       jnz     \errlabel
+oklabel\@:
+       .endm
+
 #if IS_ENABLED(CONFIG_KVM)
        /*
         * The OUTSIDE macro jumps to the provided label in case the value
@@ -550,23 +568,26 @@ ENTRY(mcck_int_handler)
 3:     TSTMSK  __LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID
        jno     .Lmcck_panic
        tmhh    %r8,0x0001              # interrupting from user ?
-       jnz     4f
+       jnz     6f
        TSTMSK  __LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID
        jno     .Lmcck_panic
-4:     ssm     __LC_PGM_NEW_PSW        # turn dat on, keep irqs off
-       tmhh    %r8,0x0001                      # interrupting from user ?
 #if IS_ENABLED(CONFIG_KVM)
-       jnz     .Lmcck_user
-       OUTSIDE %r9,.Lsie_gmap,.Lsie_done,.Lmcck_stack
-       OUTSIDE %r9,.Lsie_entry,.Lsie_skip,5f
+       OUTSIDE %r9,.Lsie_gmap,.Lsie_done,6f
+       OUTSIDE %r9,.Lsie_entry,.Lsie_skip,4f
        oi      __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
-5:     BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_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)
        SIEEXIT
        j       .Lmcck_stack
-#else
-       jz      .Lmcck_stack
 #endif
-.Lmcck_user:
+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
        BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
 .Lmcck_stack:
        lg      %r15,__LC_MCCK_STACK
@@ -692,7 +713,7 @@ ENDPROC(stack_overflow)
                .align  4
 .Lstop_lock:   .long   0
 .Lthis_cpu:    .short  0
-
+.Lstosm_tmp:   .byte   0
        .section .rodata, "a"
 #define SYSCALL(esame,emu)     .quad __s390x_ ## esame
        .globl  sys_call_table
index a424f6e69b953c499cb1cfaae2e841be0313fc1f..fdb5d23ac995711e7922901f2a7952e3301a9d02 100644 (file)
@@ -399,21 +399,6 @@ int notrace s390_do_machine_check(struct pt_regs *regs)
                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)) {
-               if (mci.se)
-                       /* Storage error uncorrected */
-                       s390_handle_damage();
-               if (mci.ke)
-                       /* Storage key-error uncorrected */
-                       s390_handle_damage();
-               if (mci.ds && mci.fa)
-                       /* Storage degradation */
-                       s390_handle_damage();
-       }
        if (mci.cp) {
                /* Channel report word pending */
                mcck->channel_report = 1;