Merge tag 's390-5.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[linux-2.6-microblaze.git] / arch / s390 / kernel / entry.S
index e84f495..3e8c666 100644 (file)
@@ -129,6 +129,27 @@ _LPP_OFFSET        = __LC_LPP
                    "jnz .+8; .long 0xb2e8d000", 82
        .endm
 
+#if IS_ENABLED(CONFIG_KVM)
+       /*
+        * The OUTSIDE macro jumps to the provided label in case the value
+        * in the provided register is outside of the provided range. The
+        * macro is useful for checking whether a PSW stored in a register
+        * pair points inside or outside of a block of instructions.
+        * @reg: register to check
+        * @start: start of the range
+        * @end: end of the range
+        * @outside_label: jump here if @reg is outside of [@start..@end)
+        */
+       .macro OUTSIDE reg,start,end,outside_label
+       lgr     %r14,\reg
+       larl    %r13,\start
+       slgr    %r14,%r13
+       lghi    %r13,\end - \start
+       clgr    %r14,%r13
+       jhe     \outside_label
+       .endm
+#endif
+
        GEN_BR_THUNK %r14
        GEN_BR_THUNK %r14,%r13
 
@@ -214,7 +235,7 @@ ENTRY(sie64a)
 # are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable.
 # Other instructions between sie64a and .Lsie_done should not cause program
 # interrupts. So lets use 3 nops as a landing pad for all possible rewinds.
-# See also .Lcleanup_sie_mcck/.Lcleanup_sie_int
+# See also .Lcleanup_sie
 .Lrewind_pad6:
        nopr    7
 .Lrewind_pad4:
@@ -276,6 +297,7 @@ ENTRY(system_call)
        xgr     %r10,%r10
        xgr     %r11,%r11
        la      %r2,STACK_FRAME_OVERHEAD(%r15)  # pointer to pt_regs
+       mvc     __PT_R8(64,%r2),__LC_SAVE_AREA_SYNC
        lgr     %r3,%r14
        brasl   %r14,__do_syscall
        lctlg   %c1,%c1,__LC_USER_ASCE
@@ -318,12 +340,7 @@ ENTRY(pgm_check_handler)
 .Lpgm_skip_asce:
 #if IS_ENABLED(CONFIG_KVM)
        # cleanup critical section for program checks in sie64a
-       lgr     %r14,%r9
-       larl    %r13,.Lsie_gmap
-       slgr    %r14,%r13
-       lghi    %r13,.Lsie_done - .Lsie_gmap
-       clgr    %r14,%r13
-       jhe     1f
+       OUTSIDE %r9,.Lsie_gmap,.Lsie_done,1f
        lg      %r14,__SF_SIE_CONTROL(%r15)     # get control block pointer
        ni      __SIE_PROG0C+3(%r14),0xfe       # no longer in SIE
        lctlg   %c1,%c1,__LC_KERNEL_ASCE        # load primary asce
@@ -392,13 +409,8 @@ ENTRY(\name)
        tmhh    %r8,0x0001                      # interrupting from user ?
        jnz     1f
 #if IS_ENABLED(CONFIG_KVM)
-       lgr     %r14,%r9
-       larl    %r13,.Lsie_gmap
-       slgr    %r14,%r13
-       lghi    %r13,.Lsie_done - .Lsie_gmap
-       clgr    %r14,%r13
-       jhe     0f
-       brasl   %r14,.Lcleanup_sie_int
+       OUTSIDE %r9,.Lsie_gmap,.Lsie_done,0f
+       brasl   %r14,.Lcleanup_sie
 #endif
 0:     CHECK_STACK __LC_SAVE_AREA_ASYNC
        aghi    %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
@@ -541,13 +553,10 @@ ENTRY(mcck_int_handler)
        tmhh    %r8,0x0001                      # interrupting from user ?
        jnz     .Lmcck_user
 #if IS_ENABLED(CONFIG_KVM)
-       lgr     %r14,%r9
-       larl    %r13,.Lsie_gmap
-       slgr    %r14,%r13
-       lghi    %r13,.Lsie_done - .Lsie_gmap
-       clgr    %r14,%r13
-       jhe     .Lmcck_stack
-       brasl   %r14,.Lcleanup_sie_mcck
+       OUTSIDE %r9,.Lsie_gmap,.Lsie_done,.Lmcck_stack
+       OUTSIDE %r9,.Lsie_entry,.Lsie_skip,5f
+       oi      __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
+5:     brasl   %r14,.Lcleanup_sie
 #endif
        j       .Lmcck_stack
 .Lmcck_user:
@@ -649,21 +658,13 @@ ENDPROC(stack_overflow)
 #endif
 
 #if IS_ENABLED(CONFIG_KVM)
-.Lcleanup_sie_mcck:
-       larl    %r13,.Lsie_entry
-       slgr    %r9,%r13
-       lghi    %r13,.Lsie_skip - .Lsie_entry
-       clgr    %r9,%r13
-       jhe     .Lcleanup_sie_int
-       oi      __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
-.Lcleanup_sie_int:
+.Lcleanup_sie:
        BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
        lg      %r9,__SF_SIE_CONTROL(%r15)      # get control block pointer
        ni      __SIE_PROG0C+3(%r9),0xfe        # no longer in SIE
        lctlg   %c1,%c1,__LC_KERNEL_ASCE
        larl    %r9,sie_exit                    # skip forward to sie_exit
        BR_EX   %r14,%r13
-
 #endif
        .section .rodata, "a"
 #define SYSCALL(esame,emu)     .quad __s390x_ ## esame