summaryrefslogtreecommitdiff
path: root/arch/s390/kernel/entry.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/entry.S')
-rw-r--r--arch/s390/kernel/entry.S50
1 files changed, 40 insertions, 10 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 708cf9cf9a3..ed500ef799b 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -49,9 +49,9 @@ SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC
SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP
SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
-_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
-_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_MCCK_PENDING)
STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
@@ -318,6 +318,8 @@ sysc_work:
bo BASED(sysc_reschedule)
tm __TI_flags+3(%r9),_TIF_SIGPENDING
bnz BASED(sysc_sigpending)
+ tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME
+ bnz BASED(sysc_notify_resume)
tm __TI_flags+3(%r9),_TIF_RESTART_SVC
bo BASED(sysc_restart)
tm __TI_flags+3(%r9),_TIF_SINGLE_STEP
@@ -356,6 +358,16 @@ sysc_sigpending:
b BASED(sysc_work_loop)
#
+# _TIF_NOTIFY_RESUME is set, call do_notify_resume
+#
+sysc_notify_resume:
+ la %r2,SP_PTREGS(%r15) # load pt_regs
+ l %r1,BASED(.Ldo_notify_resume)
+ la %r14,BASED(sysc_work_loop)
+ br %r1 # call do_notify_resume
+
+
+#
# _TIF_RESTART_SVC is set, set up registers and restart svc
#
sysc_restart:
@@ -378,20 +390,21 @@ sysc_singlestep:
br %r1 # branch to do_single_step
#
-# call trace before and after sys_call
+# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
+# and after the system call
#
sysc_tracesys:
- l %r1,BASED(.Ltrace)
+ l %r1,BASED(.Ltrace_entry)
la %r2,SP_PTREGS(%r15) # load pt_regs
la %r3,0
srl %r7,2
st %r7,SP_R2(%r15)
basr %r14,%r1
- clc SP_R2(4,%r15),BASED(.Lnr_syscalls)
+ cl %r2,BASED(.Lnr_syscalls)
bnl BASED(sysc_tracenogo)
l %r8,BASED(.Lsysc_table)
- l %r7,SP_R2(%r15) # strace might have changed the
- sll %r7,2 # system call
+ lr %r7,%r2
+ sll %r7,2 # *4
l %r8,0(%r7,%r8)
sysc_tracego:
lm %r3,%r6,SP_R3(%r15)
@@ -401,9 +414,8 @@ sysc_tracego:
sysc_tracenogo:
tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
bz BASED(sysc_return)
- l %r1,BASED(.Ltrace)
+ l %r1,BASED(.Ltrace_exit)
la %r2,SP_PTREGS(%r15) # load pt_regs
- la %r3,1
la %r14,BASED(sysc_return)
br %r1
@@ -666,6 +678,8 @@ io_work_loop:
bo BASED(io_reschedule)
tm __TI_flags+3(%r9),_TIF_SIGPENDING
bnz BASED(io_sigpending)
+ tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME
+ bnz BASED(io_notify_resume)
b BASED(io_restore)
io_work_done:
@@ -704,6 +718,19 @@ io_sigpending:
TRACE_IRQS_OFF
b BASED(io_work_loop)
+#
+# _TIF_SIGPENDING is set, call do_signal
+#
+io_notify_resume:
+ TRACE_IRQS_ON
+ 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)
+
/*
* External interrupt handler routine
*/
@@ -1070,6 +1097,8 @@ cleanup_io_leave_insn:
.Ldo_IRQ: .long do_IRQ
.Ldo_extint: .long do_extint
.Ldo_signal: .long do_signal
+.Ldo_notify_resume:
+ .long do_notify_resume
.Lhandle_per: .long do_single_step
.Ldo_execve: .long do_execve
.Lexecve_tail: .long execve_tail
@@ -1079,7 +1108,8 @@ cleanup_io_leave_insn:
.Lpreempt_schedule_irq:
.long preempt_schedule_irq
#endif
-.Ltrace: .long syscall_trace
+.Ltrace_entry: .long do_syscall_trace_enter
+.Ltrace_exit: .long do_syscall_trace_exit
.Lschedtail: .long schedule_tail
.Lsysc_table: .long sys_call_table
#ifdef CONFIG_TRACE_IRQFLAGS