aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/entry.S
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2012-11-21 10:36:27 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2012-11-23 05:14:33 -0500
commit39efd4ec9a2967e9720be7b66d9a4b31a58dbf61 (patch)
tree084c2ba72e4ffaf2dcc3d3c89f7ce32ab93d9827 /arch/s390/kernel/entry.S
parentc68dba202f54a4c9c68a8bb83d426bf8a00c99f8 (diff)
s390/ptrace: race of single stepping vs signal delivery
The current single step code is racy in regard to concurrent delivery of signals. If a signal is delivered after a PER program check occurred but before the TIF_PER_TRAP bit has been checked in entry[64].S the code clears TIF_PER_TRAP and then calls do_signal. This is wrong, if the instruction completed (or has been suppressed) a SIGTRAP should be delivered to the debugger in any case. Only if the instruction has been nullified the SIGTRAP may not be send. The new logic always sets TIF_PER_TRAP if the program check indicates PER tracing but removes it again for all program checks that are nullifying. The effect is that for each change in the PSW address we now get a single SIGTRAP. Reported-by: Andreas Arnez <arnez@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/entry.S')
-rw-r--r--arch/s390/kernel/entry.S7
1 files changed, 3 insertions, 4 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index ef46f66bc0d6..f954b37740c0 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -231,12 +231,12 @@ sysc_work:
231 jo sysc_mcck_pending 231 jo sysc_mcck_pending
232 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED 232 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
233 jo sysc_reschedule 233 jo sysc_reschedule
234 tm __TI_flags+3(%r12),_TIF_PER_TRAP
235 jo sysc_singlestep
234 tm __TI_flags+3(%r12),_TIF_SIGPENDING 236 tm __TI_flags+3(%r12),_TIF_SIGPENDING
235 jo sysc_sigpending 237 jo sysc_sigpending
236 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME 238 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
237 jo sysc_notify_resume 239 jo sysc_notify_resume
238 tm __TI_flags+3(%r12),_TIF_PER_TRAP
239 jo sysc_singlestep
240 j sysc_return # beware of critical section cleanup 240 j sysc_return # beware of critical section cleanup
241 241
242# 242#
@@ -259,7 +259,6 @@ sysc_mcck_pending:
259# _TIF_SIGPENDING is set, call do_signal 259# _TIF_SIGPENDING is set, call do_signal
260# 260#
261sysc_sigpending: 261sysc_sigpending:
262 ni __TI_flags+3(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
263 lr %r2,%r11 # pass pointer to pt_regs 262 lr %r2,%r11 # pass pointer to pt_regs
264 l %r1,BASED(.Ldo_signal) 263 l %r1,BASED(.Ldo_signal)
265 basr %r14,%r1 # call do_signal 264 basr %r14,%r1 # call do_signal
@@ -286,7 +285,7 @@ sysc_notify_resume:
286# _TIF_PER_TRAP is set, call do_per_trap 285# _TIF_PER_TRAP is set, call do_per_trap
287# 286#
288sysc_singlestep: 287sysc_singlestep:
289 ni __TI_flags+3(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP) 288 ni __TI_flags+3(%r12),255-_TIF_PER_TRAP
290 lr %r2,%r11 # pass pointer to pt_regs 289 lr %r2,%r11 # pass pointer to pt_regs
291 l %r1,BASED(.Ldo_per_trap) 290 l %r1,BASED(.Ldo_per_trap)
292 la %r14,BASED(sysc_return) 291 la %r14,BASED(sysc_return)