]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
s390/entry: Remove __GMAP_ASCE and use _PIF_GUEST_FAULT again
authorClaudio Imbrenda <imbrenda@linux.ibm.com>
Tue, 22 Oct 2024 12:05:51 +0000 (14:05 +0200)
committerHeiko Carstens <hca@linux.ibm.com>
Tue, 29 Oct 2024 10:49:18 +0000 (11:49 +0100)
Now that the guest ASCE is passed as a parameter to __sie64a(),
_PIF_GUEST_FAULT can be used again to determine whether the fault was a
guest or host fault.

Since the guest ASCE will not be taken from the gmap pointer in lowcore
anymore, __GMAP_ASCE can be removed. For the same reason the guest
ASCE needs now to be saved into the cr1 save area unconditionally.

Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Acked-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Link: https://lore.kernel.org/r/20241022120601.167009-2-imbrenda@linux.ibm.com
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
arch/s390/include/asm/ptrace.h
arch/s390/kernel/asm-offsets.c
arch/s390/kernel/entry.S
arch/s390/mm/fault.c

index 2ad9324f633876d84d22025419256aa0ba251dc5..788bc4467445c9da9471cf5037bcf2887f1303e8 100644 (file)
 #define PIF_SYSCALL                    0       /* inside a system call */
 #define PIF_EXECVE_PGSTE_RESTART       1       /* restart execve for PGSTE binaries */
 #define PIF_SYSCALL_RET_SET            2       /* return value was set via ptrace */
+#define PIF_GUEST_FAULT                        3       /* indicates program check in sie64a */
 #define PIF_FTRACE_FULL_REGS           4       /* all register contents valid (ftrace) */
 
 #define _PIF_SYSCALL                   BIT(PIF_SYSCALL)
 #define _PIF_EXECVE_PGSTE_RESTART      BIT(PIF_EXECVE_PGSTE_RESTART)
 #define _PIF_SYSCALL_RET_SET           BIT(PIF_SYSCALL_RET_SET)
+#define _PIF_GUEST_FAULT               BIT(PIF_GUEST_FAULT)
 #define _PIF_FTRACE_FULL_REGS          BIT(PIF_FTRACE_FULL_REGS)
 
 #define PSW32_MASK_PER         _AC(0x40000000, UL)
index 5529248d84fb8729887d8cae5788f06d6f9bb23f..3a6ee5043761488c6a166c415a4bd6d4745fc03d 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/purgatory.h>
 #include <linux/pgtable.h>
 #include <linux/ftrace.h>
-#include <asm/gmap.h>
 #include <asm/stacktrace.h>
 
 int main(void)
@@ -161,7 +160,6 @@ int main(void)
        OFFSET(__LC_PGM_TDB, lowcore, pgm_tdb);
        BLANK();
        /* gmap/sie offsets */
-       OFFSET(__GMAP_ASCE, gmap, asce);
        OFFSET(__SIE_PROG0C, kvm_s390_sie_block, prog0c);
        OFFSET(__SIE_PROG20, kvm_s390_sie_block, prog20);
        /* kexec_sha_region */
index d6d5317f768e82d8cb7b8f64ac9359938eb51dfe..b10175bc2faa5d1de1faa90032f5a8d9694c0719 100644 (file)
@@ -327,13 +327,23 @@ SYM_CODE_START(pgm_check_handler)
        GET_LC  %r13
        stpt    __LC_SYS_ENTER_TIMER(%r13)
        BPOFF
-       lgr     %r10,%r15
        lmg     %r8,%r9,__LC_PGM_OLD_PSW(%r13)
+       xgr     %r10,%r10
+       xgr     %r12,%r12
        tmhh    %r8,0x0001              # coming from user space?
        jno     .Lpgm_skip_asce
        lctlg   %c1,%c1,__LC_KERNEL_ASCE(%r13)
        j       3f                      # -> fault in user space
 .Lpgm_skip_asce:
+#if IS_ENABLED(CONFIG_KVM)
+       lg      %r11,__LC_CURRENT(%r13)
+       tm      __TI_sie(%r11),0xff
+       jz      1f
+       BPENTER __SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
+       SIEEXIT __SF_SIE_CONTROL(%r15),%r13
+       lg      %r12,__SF_SIE_GUEST_ASCE(%r15)
+       lghi    %r10,_PIF_GUEST_FAULT
+#endif
 1:     tmhh    %r8,0x4000              # PER bit set in old PSW ?
        jnz     2f                      # -> enabled, can't be a double fault
        tm      __LC_PGM_ILC+3(%r13),0x80       # check for per exception
@@ -344,21 +354,13 @@ SYM_CODE_START(pgm_check_handler)
        CHECK_VMAP_STACK __LC_SAVE_AREA,%r13,4f
 3:     lg      %r15,__LC_KERNEL_STACK(%r13)
 4:     la      %r11,STACK_FRAME_OVERHEAD(%r15)
-       xc      __PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
+       stg     %r10,__PT_FLAGS(%r11)
+       stg     %r12,__PT_CR1(%r11)
        xc      __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
        stmg    %r0,%r7,__PT_R0(%r11)
        mvc     __PT_R8(64,%r11),__LC_SAVE_AREA(%r13)
        mvc     __PT_LAST_BREAK(8,%r11),__LC_PGM_LAST_BREAK(%r13)
-       stctg   %c1,%c1,__PT_CR1(%r11)
-#if IS_ENABLED(CONFIG_KVM)
-       ltg     %r12,__LC_GMAP(%r13)
-       jz      5f
-       clc     __GMAP_ASCE(8,%r12), __PT_CR1(%r11)
-       jne     5f
-       BPENTER __SF_SIE_FLAGS(%r10),_TIF_ISOLATE_BP_GUEST
-       SIEEXIT __SF_SIE_CONTROL(%r10),%r13
-#endif
-5:     stmg    %r8,%r9,__PT_PSW(%r11)
+       stmg    %r8,%r9,__PT_PSW(%r11)
        # clear user controlled registers to prevent speculative use
        xgr     %r0,%r0
        xgr     %r1,%r1
index ad8b0d6b77ea16a6e6f7a8beec405ecca77022fe..a6cf33b0f339091a66926093cec9709f60c9f3b7 100644 (file)
@@ -68,15 +68,13 @@ early_initcall(fault_init);
 static enum fault_type get_fault_type(struct pt_regs *regs)
 {
        union teid teid = { .val = regs->int_parm_long };
-       struct gmap *gmap;
 
        if (likely(teid.as == PSW_BITS_AS_PRIMARY)) {
                if (user_mode(regs))
                        return USER_FAULT;
                if (!IS_ENABLED(CONFIG_PGSTE))
                        return KERNEL_FAULT;
-               gmap = (struct gmap *)get_lowcore()->gmap;
-               if (gmap && gmap->asce == regs->cr1)
+               if (test_pt_regs_flag(regs, PIF_GUEST_FAULT))
                        return GMAP_FAULT;
                return KERNEL_FAULT;
        }
@@ -187,7 +185,7 @@ static void dump_fault_info(struct pt_regs *regs)
                pr_cont("user ");
                break;
        case GMAP_FAULT:
-               asce = ((struct gmap *)get_lowcore()->gmap)->asce;
+               asce = regs->cr1;
                pr_cont("gmap ");
                break;
        case KERNEL_FAULT: