Commit 6a2df3a8 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Martin Schwidefsky

[S390] improve irq tracing code in entry[64].S

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