[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: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
committed by
Martin Schwidefsky
parent
43d399d2ab
commit
6a2df3a872
@ -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
|
|||||||
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:
|
|||||||
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:
|
|||||||
#
|
#
|
||||||
# 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:
|
|||||||
#
|
#
|
||||||
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:
|
|||||||
#
|
#
|
||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
# 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:
|
|||||||
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:
|
|||||||
# _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:
|
|||||||
|
|
||||||
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:
|
|||||||
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:
|
|||||||
.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:
|
|||||||
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:
|
|||||||
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
|
||||||
|
|
||||||
|
@ -61,28 +61,33 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
|
|||||||
|
|
||||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
.macro TRACE_IRQS_ON
|
.macro TRACE_IRQS_ON
|
||||||
basr %r2,%r0
|
basr %r2,%r0
|
||||||
brasl %r14,trace_hardirqs_on_caller
|
brasl %r14,trace_hardirqs_on_caller
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro TRACE_IRQS_OFF
|
.macro TRACE_IRQS_OFF
|
||||||
basr %r2,%r0
|
basr %r2,%r0
|
||||||
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:
|
|||||||
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:
|
|||||||
#
|
#
|
||||||
# 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:
|
|||||||
# _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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
# 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:
|
|||||||
# 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:
|
|||||||
# _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:
|
|||||||
|
|
||||||
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:
|
|||||||
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:
|
|||||||
.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:
|
|||||||
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:
|
|||||||
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)
|
|||||||
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
|
||||||
|
Reference in New Issue
Block a user