[S390] improve irq tracing code in entry[64].S
Martin Schwidefsky [Mon, 17 May 2010 08:00:02 +0000 (10:00 +0200)]
The system call path in entry[64].S is run with interrupts enabled.
Remove the irq tracing check from the system call exit code. If a
program check interrupted a context enabled for interrupts do a
call to trace_irq_off_caller in the program check handler before
branching to the system call exit code.
Restructure the system call and io interrupt return code to avoid
avoid the lpsw[e] to disable machine checks.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

arch/s390/include/asm/system.h
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/s390/kernel/setup.c

index 1741c15..cef6621 100644 (file)
@@ -459,11 +459,6 @@ extern void (*_machine_power_off)(void);
 
 #define arch_align_stack(x) (x)
 
-#ifdef CONFIG_TRACE_IRQFLAGS
-extern psw_t sysc_restore_trace_psw;
-extern psw_t io_restore_trace_psw;
-#endif
-
 static inline int tprot(unsigned long addr)
 {
        int rc = -EFAULT;
index ffebfb6..07d8499 100644 (file)
@@ -73,21 +73,24 @@ STACK_SIZE  = 1 << STACK_SHIFT
        basr    %r14,%r1
        .endm
 
-       .macro  TRACE_IRQS_CHECK
-       basr    %r2,%r0
+       .macro  TRACE_IRQS_CHECK_ON
        tm      SP_PSW(%r15),0x03       # irqs enabled?
-       jz      0f
-       l       %r1,BASED(.Ltrace_irq_on_caller)
-       basr    %r14,%r1
-       j       1f
-0:     l       %r1,BASED(.Ltrace_irq_off_caller)
-       basr    %r14,%r1
-1:
+       bz      BASED(0f)
+       TRACE_IRQS_ON
+0:
+       .endm
+
+       .macro  TRACE_IRQS_CHECK_OFF
+       tm      SP_PSW(%r15),0x03       # irqs enabled?
+       bz      BASED(0f)
+       TRACE_IRQS_OFF
+0:
        .endm
 #else
 #define TRACE_IRQS_ON
 #define TRACE_IRQS_OFF
-#define TRACE_IRQS_CHECK
+#define TRACE_IRQS_CHECK_ON
+#define TRACE_IRQS_CHECK_OFF
 #endif
 
 #ifdef CONFIG_LOCKDEP
@@ -273,33 +276,14 @@ sysc_do_restart:
        st      %r2,SP_R2(%r15)   # store return value (change R2 on stack)
 
 sysc_return:
+       LOCKDEP_SYS_EXIT
+sysc_tif:
        tm      __TI_flags+3(%r9),_TIF_WORK_SVC
        bnz     BASED(sysc_work)  # there is work to do (signals etc.)
 sysc_restore:
-#ifdef CONFIG_TRACE_IRQFLAGS
-       la      %r1,BASED(sysc_restore_trace_psw_addr)
-       l       %r1,0(%r1)
-       lpsw    0(%r1)
-sysc_restore_trace:
-       TRACE_IRQS_CHECK
-       LOCKDEP_SYS_EXIT
-#endif
-sysc_leave:
        RESTORE_ALL __LC_RETURN_PSW,1
 sysc_done:
 
-#ifdef CONFIG_TRACE_IRQFLAGS
-sysc_restore_trace_psw_addr:
-       .long sysc_restore_trace_psw
-
-       .section .data,"aw",@progbits
-       .align  8
-       .globl  sysc_restore_trace_psw
-sysc_restore_trace_psw:
-       .long   0, sysc_restore_trace + 0x80000000
-       .previous
-#endif
-
 #
 # There is work to do, but first we need to check if we return to userspace.
 #
@@ -310,7 +294,7 @@ sysc_work:
 #
 # One of the work bits is on. Find out which one.
 #
-sysc_work_loop:
+sysc_work_tif:
        tm      __TI_flags+3(%r9),_TIF_MCCK_PENDING
        bo      BASED(sysc_mcck_pending)
        tm      __TI_flags+3(%r9),_TIF_NEED_RESCHED
@@ -330,7 +314,7 @@ sysc_work_loop:
 #
 sysc_reschedule:
        l       %r1,BASED(.Lschedule)
-       la      %r14,BASED(sysc_work_loop)
+       la      %r14,BASED(sysc_return)
        br      %r1                     # call scheduler
 
 #
@@ -338,7 +322,7 @@ sysc_reschedule:
 #
 sysc_mcck_pending:
        l       %r1,BASED(.Ls390_handle_mcck)
-       la      %r14,BASED(sysc_work_loop)
+       la      %r14,BASED(sysc_return)
        br      %r1                     # TIF bit will be cleared by handler
 
 #
@@ -353,7 +337,7 @@ sysc_sigpending:
        bo      BASED(sysc_restart)
        tm      __TI_flags+3(%r9),_TIF_SINGLE_STEP
        bo      BASED(sysc_singlestep)
-       b       BASED(sysc_work_loop)
+       b       BASED(sysc_return)
 
 #
 # _TIF_NOTIFY_RESUME is set, call do_notify_resume
@@ -361,7 +345,7 @@ sysc_sigpending:
 sysc_notify_resume:
        la      %r2,SP_PTREGS(%r15)     # load pt_regs
        l       %r1,BASED(.Ldo_notify_resume)
-       la      %r14,BASED(sysc_work_loop)
+       la      %r14,BASED(sysc_return)
        br      %r1                     # call do_notify_resume
 
 
@@ -384,7 +368,7 @@ sysc_singlestep:
        mvi     SP_SVCNR+1(%r15),0xff
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
        l       %r1,BASED(.Lhandle_per) # load adr. of per handler
-       la      %r14,BASED(sysc_work_loop)      # load adr. of system return
+       la      %r14,BASED(sysc_return) # load adr. of system return
        br      %r1                     # branch to do_single_step
 
 #
@@ -456,11 +440,13 @@ kernel_execve:
        br      %r14
        # execve succeeded.
 0:     stnsm   __SF_EMPTY(%r15),0xfc   # disable interrupts
+       TRACE_IRQS_OFF
        l       %r15,__LC_KERNEL_STACK  # load ksp
        s       %r15,BASED(.Lc_spsize)  # make room for registers & psw
        l       %r9,__LC_THREAD_INFO
        mvc     SP_PTREGS(__PT_SIZE,%r15),0(%r12)       # copy pt_regs
        xc      __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
+       TRACE_IRQS_ON
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        l       %r1,BASED(.Lexecve_tail)
        basr    %r14,%r1
@@ -497,8 +483,8 @@ pgm_check_handler:
        UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
 pgm_no_vtime:
+       TRACE_IRQS_CHECK_OFF
        l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
-       TRACE_IRQS_OFF
        l       %r3,__LC_PGM_ILC        # load program interruption code
        la      %r8,0x7f
        nr      %r8,%r3
@@ -507,8 +493,10 @@ pgm_do_call:
        sll     %r8,2
        l       %r7,0(%r8,%r7)          # load address of handler routine
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
-       la      %r14,BASED(sysc_return)
-       br      %r7                     # branch to interrupt-handler
+       basr    %r14,%r7                # branch to interrupt-handler
+pgm_exit:
+       TRACE_IRQS_CHECK_ON
+       b       BASED(sysc_return)
 
 #
 # handle per exception
@@ -535,19 +523,19 @@ pgm_per_std:
        UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
 pgm_no_vtime2:
+       TRACE_IRQS_CHECK_OFF
        l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
-       TRACE_IRQS_OFF
        l       %r1,__TI_task(%r9)
+       tm      SP_PSW+1(%r15),0x01     # kernel per event ?
+       bz      BASED(kernel_per)
        mvc     __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
        mvc     __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
        mvc     __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
        oi      __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
-       tm      SP_PSW+1(%r15),0x01     # kernel per event ?
-       bz      BASED(kernel_per)
        l       %r3,__LC_PGM_ILC        # load program interruption code
        la      %r8,0x7f
        nr      %r8,%r3                 # clear per-event-bit and ilc
-       be      BASED(sysc_return)      # only per or per+check ?
+       be      BASED(pgm_exit)         # only per or per+check ?
        b       BASED(pgm_do_call)
 
 #
@@ -568,8 +556,8 @@ pgm_svcper:
        mvc     __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
        oi      __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
        TRACE_IRQS_ON
-       lm      %r2,%r6,SP_R2(%r15)     # load svc arguments
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
+       lm      %r2,%r6,SP_R2(%r15)     # load svc arguments
        b       BASED(sysc_do_svc)
 
 #
@@ -580,8 +568,8 @@ kernel_per:
        mvi     SP_SVCNR+1(%r15),0xff
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
        l       %r1,BASED(.Lhandle_per) # load adr. of per handler
-       la      %r14,BASED(sysc_restore)# load adr. of system return
-       br      %r1                     # branch to do_single_step
+       basr    %r14,%r1                # branch to do_single_step
+       b       BASED(pgm_exit)
 
 /*
  * IO interrupt handler routine
@@ -600,39 +588,21 @@ io_int_handler:
        UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
 io_no_vtime:
-       l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
        TRACE_IRQS_OFF
+       l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
        l       %r1,BASED(.Ldo_IRQ)     # load address of do_IRQ
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
        basr    %r14,%r1                # branch to standard irq handler
 io_return:
+       LOCKDEP_SYS_EXIT
+       TRACE_IRQS_ON
+io_tif:
        tm      __TI_flags+3(%r9),_TIF_WORK_INT
        bnz     BASED(io_work)          # there is work to do (signals etc.)
 io_restore:
-#ifdef CONFIG_TRACE_IRQFLAGS
-       la      %r1,BASED(io_restore_trace_psw_addr)
-       l       %r1,0(%r1)
-       lpsw    0(%r1)
-io_restore_trace:
-       TRACE_IRQS_CHECK
-       LOCKDEP_SYS_EXIT
-#endif
-io_leave:
        RESTORE_ALL __LC_RETURN_PSW,0
 io_done:
 
-#ifdef CONFIG_TRACE_IRQFLAGS
-io_restore_trace_psw_addr:
-       .long io_restore_trace_psw
-
-       .section .data,"aw",@progbits
-       .align  8
-       .globl  io_restore_trace_psw
-io_restore_trace_psw:
-       .long   0, io_restore_trace + 0x80000000
-       .previous
-#endif
-
 #
 # There is work todo, find out in which context we have been interrupted:
 # 1) if we return to user space we can do all _TIF_WORK_INT work
@@ -647,19 +617,23 @@ io_work:
        # check for preemptive scheduling
        icm     %r0,15,__TI_precount(%r9)
        bnz     BASED(io_restore)       # preemption disabled
+       tm      __TI_flags+3(%r9),_TIF_NEED_RESCHED
+       bno     BASED(io_restore)
        # switch to kernel stack
        l       %r1,SP_R15(%r15)
        s       %r1,BASED(.Lc_spsize)
        mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
        xc      __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
        lr      %r15,%r1
-io_resume_loop:
+       # TRACE_IRQS_ON already done at io_return, call
+       # TRACE_IRQS_OFF to keep things symmetrical
+       TRACE_IRQS_OFF
        l       %r1,BASED(.Lpreempt_schedule_irq)
-       la      %r14,BASED(io_resume_loop)
-       tm      __TI_flags+3(%r9),_TIF_NEED_RESCHED
-       bor     %r1                     # call preempt_schedule_irq
-#endif
+       basr    %r14,%r1                # call preempt_schedule_irq
+       b       BASED(io_return)
+#else
        b       BASED(io_restore)
+#endif
 
 #
 # Need to do work before returning to userspace, switch to kernel stack
@@ -670,12 +644,13 @@ io_work_user:
        mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
        xc      __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
        lr      %r15,%r1
+
 #
 # One of the work bits is on. Find out which one.
 # Checked are: _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_NEED_RESCHED
 #              and _TIF_MCCK_PENDING
 #
-io_work_loop:
+io_work_tif:
        tm      __TI_flags+3(%r9),_TIF_MCCK_PENDING
        bo      BASED(io_mcck_pending)
        tm      __TI_flags+3(%r9),_TIF_NEED_RESCHED
@@ -690,47 +665,49 @@ io_work_loop:
 # _TIF_MCCK_PENDING is set, call handler
 #
 io_mcck_pending:
+       # TRACE_IRQS_ON already done at io_return
        l       %r1,BASED(.Ls390_handle_mcck)
        basr    %r14,%r1                # TIF bit will be cleared by handler
-       b       BASED(io_work_loop)
+       TRACE_IRQS_OFF
+       b       BASED(io_return)
 
 #
 # _TIF_NEED_RESCHED is set, call schedule
 #
 io_reschedule:
-       TRACE_IRQS_ON
+       # TRACE_IRQS_ON already done at io_return
        l       %r1,BASED(.Lschedule)
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        basr    %r14,%r1                # call scheduler
        stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
        TRACE_IRQS_OFF
-       b       BASED(io_work_loop)
+       b       BASED(io_return)
 
 #
 # _TIF_SIGPENDING is set, call do_signal
 #
 io_sigpending:
-       TRACE_IRQS_ON
+       # TRACE_IRQS_ON already done at io_return
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        la      %r2,SP_PTREGS(%r15)     # load pt_regs
        l       %r1,BASED(.Ldo_signal)
        basr    %r14,%r1                # call do_signal
        stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
        TRACE_IRQS_OFF
-       b       BASED(io_work_loop)
+       b       BASED(io_return)
 
 #
 # _TIF_SIGPENDING is set, call do_signal
 #
 io_notify_resume:
-       TRACE_IRQS_ON
+       # TRACE_IRQS_ON already done at io_return
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        la      %r2,SP_PTREGS(%r15)     # load pt_regs
        l       %r1,BASED(.Ldo_notify_resume)
        basr    %r14,%r1                # call do_signal
        stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
        TRACE_IRQS_OFF
-       b       BASED(io_work_loop)
+       b       BASED(io_return)
 
 /*
  * External interrupt handler routine
@@ -918,14 +895,14 @@ stack_overflow:
 
 cleanup_table_system_call:
        .long   system_call + 0x80000000, sysc_do_svc + 0x80000000
-cleanup_table_sysc_return:
-       .long   sysc_return + 0x80000000, sysc_leave + 0x80000000
-cleanup_table_sysc_leave:
-       .long   sysc_leave + 0x80000000, sysc_done + 0x80000000
-cleanup_table_io_return:
-       .long   io_return + 0x80000000, io_leave + 0x80000000
-cleanup_table_io_leave:
-       .long   io_leave + 0x80000000, io_done + 0x80000000
+cleanup_table_sysc_tif:
+       .long   sysc_tif + 0x80000000, sysc_restore + 0x80000000
+cleanup_table_sysc_restore:
+       .long   sysc_restore + 0x80000000, sysc_done + 0x80000000
+cleanup_table_io_tif:
+       .long   io_tif + 0x80000000, io_restore + 0x80000000
+cleanup_table_io_restore:
+       .long   io_restore + 0x80000000, io_done + 0x80000000
 
 cleanup_critical:
        clc     4(4,%r12),BASED(cleanup_table_system_call)
@@ -933,25 +910,25 @@ cleanup_critical:
        clc     4(4,%r12),BASED(cleanup_table_system_call+4)
        bl      BASED(cleanup_system_call)
 0:
-       clc     4(4,%r12),BASED(cleanup_table_sysc_return)
+       clc     4(4,%r12),BASED(cleanup_table_sysc_tif)
        bl      BASED(0f)
-       clc     4(4,%r12),BASED(cleanup_table_sysc_return+4)
-       bl      BASED(cleanup_sysc_return)
+       clc     4(4,%r12),BASED(cleanup_table_sysc_tif+4)
+       bl      BASED(cleanup_sysc_tif)
 0:
-       clc     4(4,%r12),BASED(cleanup_table_sysc_leave)
+       clc     4(4,%r12),BASED(cleanup_table_sysc_restore)
        bl      BASED(0f)
-       clc     4(4,%r12),BASED(cleanup_table_sysc_leave+4)
-       bl      BASED(cleanup_sysc_leave)
+       clc     4(4,%r12),BASED(cleanup_table_sysc_restore+4)
+       bl      BASED(cleanup_sysc_restore)
 0:
-       clc     4(4,%r12),BASED(cleanup_table_io_return)
+       clc     4(4,%r12),BASED(cleanup_table_io_tif)
        bl      BASED(0f)
-       clc     4(4,%r12),BASED(cleanup_table_io_return+4)
-       bl      BASED(cleanup_io_return)
+       clc     4(4,%r12),BASED(cleanup_table_io_tif+4)
+       bl      BASED(cleanup_io_tif)
 0:
-       clc     4(4,%r12),BASED(cleanup_table_io_leave)
+       clc     4(4,%r12),BASED(cleanup_table_io_restore)
        bl      BASED(0f)
-       clc     4(4,%r12),BASED(cleanup_table_io_leave+4)
-       bl      BASED(cleanup_io_leave)
+       clc     4(4,%r12),BASED(cleanup_table_io_restore+4)
+       bl      BASED(cleanup_io_restore)
 0:
        br      %r14
 
@@ -998,17 +975,17 @@ cleanup_system_call_insn:
        .long   sysc_stime + 0x80000000
        .long   sysc_update + 0x80000000
 
-cleanup_sysc_return:
+cleanup_sysc_tif:
        mvc     __LC_RETURN_PSW(4),0(%r12)
-       mvc     __LC_RETURN_PSW+4(4),BASED(cleanup_table_sysc_return)
+       mvc     __LC_RETURN_PSW+4(4),BASED(cleanup_table_sysc_tif)
        la      %r12,__LC_RETURN_PSW
        br      %r14
 
-cleanup_sysc_leave:
-       clc     4(4,%r12),BASED(cleanup_sysc_leave_insn)
+cleanup_sysc_restore:
+       clc     4(4,%r12),BASED(cleanup_sysc_restore_insn)
        be      BASED(2f)
        mvc     __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
-       clc     4(4,%r12),BASED(cleanup_sysc_leave_insn+4)
+       clc     4(4,%r12),BASED(cleanup_sysc_restore_insn+4)
        be      BASED(2f)
        mvc     __LC_RETURN_PSW(8),SP_PSW(%r15)
        c       %r12,BASED(.Lmck_old_psw)
@@ -1020,21 +997,21 @@ cleanup_sysc_leave:
        l       %r15,SP_R15(%r15)
 2:     la      %r12,__LC_RETURN_PSW
        br      %r14
-cleanup_sysc_leave_insn:
+cleanup_sysc_restore_insn:
        .long   sysc_done - 4 + 0x80000000
        .long   sysc_done - 8 + 0x80000000
 
-cleanup_io_return:
+cleanup_io_tif:
        mvc     __LC_RETURN_PSW(4),0(%r12)
-       mvc     __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_return)
+       mvc     __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_tif)
        la      %r12,__LC_RETURN_PSW
        br      %r14
 
-cleanup_io_leave:
-       clc     4(4,%r12),BASED(cleanup_io_leave_insn)
+cleanup_io_restore:
+       clc     4(4,%r12),BASED(cleanup_io_restore_insn)
        be      BASED(2f)
        mvc     __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
-       clc     4(4,%r12),BASED(cleanup_io_leave_insn+4)
+       clc     4(4,%r12),BASED(cleanup_io_restore_insn+4)
        be      BASED(2f)
        mvc     __LC_RETURN_PSW(8),SP_PSW(%r15)
        c       %r12,BASED(.Lmck_old_psw)
@@ -1046,7 +1023,7 @@ cleanup_io_leave:
        l       %r15,SP_R15(%r15)
 2:     la      %r12,__LC_RETURN_PSW
        br      %r14
-cleanup_io_leave_insn:
+cleanup_io_restore_insn:
        .long   io_done - 4 + 0x80000000
        .long   io_done - 8 + 0x80000000
 
index ca02b10..860cea1 100644 (file)
@@ -61,28 +61,33 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
 
 #ifdef CONFIG_TRACE_IRQFLAGS
        .macro  TRACE_IRQS_ON
-        basr   %r2,%r0
-        brasl  %r14,trace_hardirqs_on_caller
+       basr    %r2,%r0
+       brasl   %r14,trace_hardirqs_on_caller
        .endm
 
        .macro  TRACE_IRQS_OFF
-        basr   %r2,%r0
-        brasl  %r14,trace_hardirqs_off_caller
+       basr    %r2,%r0
+       brasl   %r14,trace_hardirqs_off_caller
        .endm
 
-       .macro TRACE_IRQS_CHECK
-       basr    %r2,%r0
+       .macro TRACE_IRQS_CHECK_ON
        tm      SP_PSW(%r15),0x03       # irqs enabled?
        jz      0f
-       brasl   %r14,trace_hardirqs_on_caller
-       j       1f
-0:     brasl   %r14,trace_hardirqs_off_caller
-1:
+       TRACE_IRQS_ON
+0:
+       .endm
+
+       .macro TRACE_IRQS_CHECK_OFF
+       tm      SP_PSW(%r15),0x03       # irqs enabled?
+       jz      0f
+       TRACE_IRQS_OFF
+0:
        .endm
 #else
 #define TRACE_IRQS_ON
 #define TRACE_IRQS_OFF
-#define TRACE_IRQS_CHECK
+#define TRACE_IRQS_CHECK_ON
+#define TRACE_IRQS_CHECK_OFF
 #endif
 
 #ifdef CONFIG_LOCKDEP
@@ -267,29 +272,14 @@ sysc_noemu:
        stg     %r2,SP_R2(%r15) # store return value (change R2 on stack)
 
 sysc_return:
+       LOCKDEP_SYS_EXIT
+sysc_tif:
        tm      __TI_flags+7(%r9),_TIF_WORK_SVC
        jnz     sysc_work       # there is work to do (signals etc.)
 sysc_restore:
-#ifdef CONFIG_TRACE_IRQFLAGS
-       larl    %r1,sysc_restore_trace_psw
-       lpswe   0(%r1)
-sysc_restore_trace:
-       TRACE_IRQS_CHECK
-       LOCKDEP_SYS_EXIT
-#endif
-sysc_leave:
        RESTORE_ALL __LC_RETURN_PSW,1
 sysc_done:
 
-#ifdef CONFIG_TRACE_IRQFLAGS
-       .section .data,"aw",@progbits
-       .align  8
-       .globl sysc_restore_trace_psw
-sysc_restore_trace_psw:
-       .quad   0, sysc_restore_trace
-       .previous
-#endif
-
 #
 # There is work to do, but first we need to check if we return to userspace.
 #
@@ -300,7 +290,7 @@ sysc_work:
 #
 # One of the work bits is on. Find out which one.
 #
-sysc_work_loop:
+sysc_work_tif:
        tm      __TI_flags+7(%r9),_TIF_MCCK_PENDING
        jo      sysc_mcck_pending
        tm      __TI_flags+7(%r9),_TIF_NEED_RESCHED
@@ -319,14 +309,14 @@ sysc_work_loop:
 # _TIF_NEED_RESCHED is set, call schedule
 #
 sysc_reschedule:
-       larl    %r14,sysc_work_loop
-       jg      schedule                # return point is sysc_work_loop
+       larl    %r14,sysc_return
+       jg      schedule                # return point is sysc_return
 
 #
 # _TIF_MCCK_PENDING is set, call handler
 #
 sysc_mcck_pending:
-       larl    %r14,sysc_work_loop
+       larl    %r14,sysc_return
        jg      s390_handle_mcck        # TIF bit will be cleared by handler
 
 #
@@ -340,14 +330,14 @@ sysc_sigpending:
        jo      sysc_restart
        tm      __TI_flags+7(%r9),_TIF_SINGLE_STEP
        jo      sysc_singlestep
-       j       sysc_work_loop
+       j       sysc_return
 
 #
 # _TIF_NOTIFY_RESUME is set, call do_notify_resume
 #
 sysc_notify_resume:
        la      %r2,SP_PTREGS(%r15)     # load pt_regs
-       larl    %r14,sysc_work_loop
+       larl    %r14,sysc_return
        jg      do_notify_resume        # call do_notify_resume
 
 #
@@ -367,7 +357,7 @@ sysc_singlestep:
        ni      __TI_flags+7(%r9),255-_TIF_SINGLE_STEP  # clear TIF_SINGLE_STEP
        xc      SP_SVCNR(2,%r15),SP_SVCNR(%r15)         # clear svc number
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
-       larl    %r14,sysc_work_loop     # load adr. of system return
+       larl    %r14,sysc_return        # load adr. of system return
        jg      do_single_step          # branch to do_sigtrap
 
 #
@@ -433,12 +423,14 @@ kernel_execve:
        br      %r14
        # execve succeeded.
 0:     stnsm   __SF_EMPTY(%r15),0xfc   # disable interrupts
+#      TRACE_IRQS_OFF
        lg      %r15,__LC_KERNEL_STACK  # load ksp
        aghi    %r15,-SP_SIZE           # make room for registers & psw
        lg      %r13,__LC_SVC_NEW_PSW+8
        lg      %r9,__LC_THREAD_INFO
        mvc     SP_PTREGS(__PT_SIZE,%r15),0(%r12)       # copy pt_regs
        xc      __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
+#      TRACE_IRQS_ON
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        brasl   %r14,execve_tail
        j       sysc_return
@@ -474,9 +466,9 @@ pgm_check_handler:
        UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
 pgm_no_vtime:
+       TRACE_IRQS_CHECK_OFF
        lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
        mvc     SP_ARGS(8,%r15),__LC_LAST_BREAK
-       TRACE_IRQS_OFF
        lgf     %r3,__LC_PGM_ILC        # load program interruption code
        lghi    %r8,0x7f
        ngr     %r8,%r3
@@ -485,8 +477,10 @@ pgm_do_call:
        larl    %r1,pgm_check_table
        lg      %r1,0(%r8,%r1)          # load address of handler routine
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
-       larl    %r14,sysc_return
-       br      %r1                     # branch to interrupt-handler
+       basr    %r14,%r1                # branch to interrupt-handler
+pgm_exit:
+       TRACE_IRQS_CHECK_ON
+       j       sysc_return
 
 #
 # handle per exception
@@ -513,8 +507,8 @@ pgm_per_std:
        UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
 pgm_no_vtime2:
+       TRACE_IRQS_CHECK_OFF
        lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
-       TRACE_IRQS_OFF
        lg      %r1,__TI_task(%r9)
        tm      SP_PSW+1(%r15),0x01     # kernel per event ?
        jz      kernel_per
@@ -525,7 +519,7 @@ pgm_no_vtime2:
        lgf     %r3,__LC_PGM_ILC        # load program interruption code
        lghi    %r8,0x7f
        ngr     %r8,%r3                 # clear per-event-bit and ilc
-       je      sysc_return
+       je      pgm_exit
        j       pgm_do_call
 
 #
@@ -539,14 +533,15 @@ pgm_svcper:
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
        llgh    %r7,__LC_SVC_INT_CODE   # get svc number from lowcore
        lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
+       TRACE_IRQS_OFF
        lg      %r8,__TI_task(%r9)
        mvc     __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID
        mvc     __THREAD_per+__PER_address(8,%r8),__LC_PER_ADDRESS
        mvc     __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
        oi      __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
        TRACE_IRQS_ON
-       lmg     %r2,%r6,SP_R2(%r15)     # load svc arguments
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
+       lmg     %r2,%r6,SP_R2(%r15)     # load svc arguments
        j       sysc_do_svc
 
 #
@@ -555,8 +550,8 @@ pgm_svcper:
 kernel_per:
        xc      SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
-       larl    %r14,sysc_restore       # load adr. of system ret, no work
-       jg      do_single_step          # branch to do_single_step
+       brasl   %r14,do_single_step
+       j       pgm_exit
 
 /*
  * IO interrupt handler routine
@@ -579,29 +574,15 @@ io_no_vtime:
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
        brasl   %r14,do_IRQ             # call standard irq handler
 io_return:
+       LOCKDEP_SYS_EXIT
+       TRACE_IRQS_ON
+io_tif:
        tm      __TI_flags+7(%r9),_TIF_WORK_INT
        jnz     io_work                 # there is work to do (signals etc.)
 io_restore:
-#ifdef CONFIG_TRACE_IRQFLAGS
-       larl    %r1,io_restore_trace_psw
-       lpswe   0(%r1)
-io_restore_trace:
-       TRACE_IRQS_CHECK
-       LOCKDEP_SYS_EXIT
-#endif
-io_leave:
        RESTORE_ALL __LC_RETURN_PSW,0
 io_done:
 
-#ifdef CONFIG_TRACE_IRQFLAGS
-       .section .data,"aw",@progbits
-       .align  8
-       .globl io_restore_trace_psw
-io_restore_trace_psw:
-       .quad   0, io_restore_trace
-       .previous
-#endif
-
 #
 # There is work todo, find out in which context we have been interrupted:
 # 1) if we return to user space we can do all _TIF_WORK_INT work
@@ -627,18 +608,22 @@ io_work:
        # check for preemptive scheduling
        icm     %r0,15,__TI_precount(%r9)
        jnz     io_restore              # preemption is disabled
+       tm      __TI_flags+7(%r12),_TIF_NEED_RESCHED
+       jno     io_restore
        # switch to kernel stack
        lg      %r1,SP_R15(%r15)
        aghi    %r1,-SP_SIZE
        mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
        xc      __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain
        lgr     %r15,%r1
-io_resume_loop:
-       larl    %r14,io_resume_loop
-       tm      __TI_flags+7(%r12),_TIF_NEED_RESCHED
-       jgo     preempt_schedule_irq
-#endif
+       # TRACE_IRQS_ON already done at io_return, call
+       # TRACE_IRQS_OFF to keep things symmetrical
+       TRACE_IRQS_OFF
+       brasl   %r14,preempt_schedule_irq
+       j       io_return
+#else
        j       io_restore
+#endif
 
 #
 # Need to do work before returning to userspace, switch to kernel stack
@@ -655,7 +640,7 @@ io_work_user:
 # Checked are: _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_NEED_RESCHED
 #             and _TIF_MCCK_PENDING
 #
-io_work_loop:
+io_work_tif:
        tm      __TI_flags+7(%r9),_TIF_MCCK_PENDING
        jo      io_mcck_pending
        tm      __TI_flags+7(%r9),_TIF_NEED_RESCHED
@@ -670,43 +655,45 @@ io_work_loop:
 # _TIF_MCCK_PENDING is set, call handler
 #
 io_mcck_pending:
+       # TRACE_IRQS_ON already done at io_return
        brasl   %r14,s390_handle_mcck   # TIF bit will be cleared by handler
-       j       io_work_loop
+       TRACE_IRQS_OFF
+       j       io_return
 
 #
 # _TIF_NEED_RESCHED is set, call schedule
 #
 io_reschedule:
-       TRACE_IRQS_ON
+       # TRACE_IRQS_ON already done at io_return
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        brasl   %r14,schedule           # call scheduler
        stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
        TRACE_IRQS_OFF
-       j       io_work_loop
+       j       io_return
 
 #
 # _TIF_SIGPENDING or is set, call do_signal
 #
 io_sigpending:
-       TRACE_IRQS_ON
+       # TRACE_IRQS_ON already done at io_return
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        la      %r2,SP_PTREGS(%r15)     # load pt_regs
        brasl   %r14,do_signal          # call do_signal
        stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
        TRACE_IRQS_OFF
-       j       io_work_loop
+       j       io_return
 
 #
 # _TIF_NOTIFY_RESUME or is set, call do_notify_resume
 #
 io_notify_resume:
-       TRACE_IRQS_ON
+       # TRACE_IRQS_ON already done at io_return
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        la      %r2,SP_PTREGS(%r15)     # load pt_regs
        brasl   %r14,do_notify_resume   # call do_notify_resume
        stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
        TRACE_IRQS_OFF
-       j       io_work_loop
+       j       io_return
 
 /*
  * External interrupt handler routine
@@ -883,14 +870,14 @@ stack_overflow:
 
 cleanup_table_system_call:
        .quad   system_call, sysc_do_svc
-cleanup_table_sysc_return:
-       .quad   sysc_return, sysc_leave
-cleanup_table_sysc_leave:
-       .quad   sysc_leave, sysc_done
-cleanup_table_io_return:
-       .quad   io_return, io_leave
-cleanup_table_io_leave:
-       .quad   io_leave, io_done
+cleanup_table_sysc_tif:
+       .quad   sysc_tif, sysc_restore
+cleanup_table_sysc_restore:
+       .quad   sysc_restore, sysc_done
+cleanup_table_io_tif:
+       .quad   io_tif, io_restore
+cleanup_table_io_restore:
+       .quad   io_restore, io_done
 
 cleanup_critical:
        clc     8(8,%r12),BASED(cleanup_table_system_call)
@@ -898,25 +885,25 @@ cleanup_critical:
        clc     8(8,%r12),BASED(cleanup_table_system_call+8)
        jl      cleanup_system_call
 0:
-       clc     8(8,%r12),BASED(cleanup_table_sysc_return)
+       clc     8(8,%r12),BASED(cleanup_table_sysc_tif)
        jl      0f
-       clc     8(8,%r12),BASED(cleanup_table_sysc_return+8)
-       jl      cleanup_sysc_return
+       clc     8(8,%r12),BASED(cleanup_table_sysc_tif+8)
+       jl      cleanup_sysc_tif
 0:
-       clc     8(8,%r12),BASED(cleanup_table_sysc_leave)
+       clc     8(8,%r12),BASED(cleanup_table_sysc_restore)
        jl      0f
-       clc     8(8,%r12),BASED(cleanup_table_sysc_leave+8)
-       jl      cleanup_sysc_leave
+       clc     8(8,%r12),BASED(cleanup_table_sysc_restore+8)
+       jl      cleanup_sysc_restore
 0:
-       clc     8(8,%r12),BASED(cleanup_table_io_return)
+       clc     8(8,%r12),BASED(cleanup_table_io_tif)
        jl      0f
-       clc     8(8,%r12),BASED(cleanup_table_io_return+8)
-       jl      cleanup_io_return
+       clc     8(8,%r12),BASED(cleanup_table_io_tif+8)
+       jl      cleanup_io_tif
 0:
-       clc     8(8,%r12),BASED(cleanup_table_io_leave)
+       clc     8(8,%r12),BASED(cleanup_table_io_restore)
        jl      0f
-       clc     8(8,%r12),BASED(cleanup_table_io_leave+8)
-       jl      cleanup_io_leave
+       clc     8(8,%r12),BASED(cleanup_table_io_restore+8)
+       jl      cleanup_io_restore
 0:
        br      %r14
 
@@ -963,16 +950,16 @@ cleanup_system_call_insn:
        .quad   sysc_stime
        .quad   sysc_update
 
-cleanup_sysc_return:
+cleanup_sysc_tif:
        mvc     __LC_RETURN_PSW(8),0(%r12)
-       mvc     __LC_RETURN_PSW+8(8),BASED(cleanup_table_sysc_return)
+       mvc     __LC_RETURN_PSW+8(8),BASED(cleanup_table_sysc_tif)
        la      %r12,__LC_RETURN_PSW
        br      %r14
 
-cleanup_sysc_leave:
-       clc     8(8,%r12),BASED(cleanup_sysc_leave_insn)
+cleanup_sysc_restore:
+       clc     8(8,%r12),BASED(cleanup_sysc_restore_insn)
        je      3f
-       clc     8(8,%r12),BASED(cleanup_sysc_leave_insn+8)
+       clc     8(8,%r12),BASED(cleanup_sysc_restore_insn+8)
        jhe     0f
        mvc     __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
 0:     mvc     __LC_RETURN_PSW(16),SP_PSW(%r15)
@@ -985,20 +972,20 @@ cleanup_sysc_leave:
        lg      %r15,SP_R15(%r15)
 3:     la      %r12,__LC_RETURN_PSW
        br      %r14
-cleanup_sysc_leave_insn:
+cleanup_sysc_restore_insn:
        .quad   sysc_done - 4
        .quad   sysc_done - 16
 
-cleanup_io_return:
+cleanup_io_tif:
        mvc     __LC_RETURN_PSW(8),0(%r12)
-       mvc     __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_return)
+       mvc     __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_tif)
        la      %r12,__LC_RETURN_PSW
        br      %r14
 
-cleanup_io_leave:
-       clc     8(8,%r12),BASED(cleanup_io_leave_insn)
+cleanup_io_restore:
+       clc     8(8,%r12),BASED(cleanup_io_restore_insn)
        je      3f
-       clc     8(8,%r12),BASED(cleanup_io_leave_insn+8)
+       clc     8(8,%r12),BASED(cleanup_io_restore_insn+8)
        jhe     0f
        mvc     __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
 0:     mvc     __LC_RETURN_PSW(16),SP_PSW(%r15)
@@ -1011,7 +998,7 @@ cleanup_io_leave:
        lg      %r15,SP_R15(%r15)
 3:     la      %r12,__LC_RETURN_PSW
        br      %r14
-cleanup_io_leave_insn:
+cleanup_io_restore_insn:
        .quad   io_done - 4
        .quad   io_done - 16
 
index 6309276..5987524 100644 (file)
@@ -369,10 +369,6 @@ static void setup_addressing_mode(void)
                        pr_info("Address spaces switched, "
                                "mvcos not available\n");
        }
-#ifdef CONFIG_TRACE_IRQFLAGS
-       sysc_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
-       io_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
-#endif
 }
 
 static void __init