aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/entry64.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/entry64.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/entry64.S')
-rw-r--r--arch/s390/kernel/entry64.S7
1 files changed, 3 insertions, 4 deletions
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index e42842a3072b..7a2d22dda9ef 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -262,12 +262,12 @@ sysc_work:
262 jo sysc_mcck_pending 262 jo sysc_mcck_pending
263 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED 263 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED
264 jo sysc_reschedule 264 jo sysc_reschedule
265 tm __TI_flags+7(%r12),_TIF_PER_TRAP
266 jo sysc_singlestep
265 tm __TI_flags+7(%r12),_TIF_SIGPENDING 267 tm __TI_flags+7(%r12),_TIF_SIGPENDING
266 jo sysc_sigpending 268 jo sysc_sigpending
267 tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME 269 tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME
268 jo sysc_notify_resume 270 jo sysc_notify_resume
269 tm __TI_flags+7(%r12),_TIF_PER_TRAP
270 jo sysc_singlestep
271 j sysc_return # beware of critical section cleanup 271 j sysc_return # beware of critical section cleanup
272 272
273# 273#
@@ -288,7 +288,6 @@ sysc_mcck_pending:
288# _TIF_SIGPENDING is set, call do_signal 288# _TIF_SIGPENDING is set, call do_signal
289# 289#
290sysc_sigpending: 290sysc_sigpending:
291 ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
292 lgr %r2,%r11 # pass pointer to pt_regs 291 lgr %r2,%r11 # pass pointer to pt_regs
293 brasl %r14,do_signal 292 brasl %r14,do_signal
294 tm __TI_flags+7(%r12),_TIF_SYSCALL 293 tm __TI_flags+7(%r12),_TIF_SYSCALL
@@ -313,7 +312,7 @@ sysc_notify_resume:
313# _TIF_PER_TRAP is set, call do_per_trap 312# _TIF_PER_TRAP is set, call do_per_trap
314# 313#
315sysc_singlestep: 314sysc_singlestep:
316 ni __TI_flags+7(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP) 315 ni __TI_flags+7(%r12),255-_TIF_PER_TRAP
317 lgr %r2,%r11 # pass pointer to pt_regs 316 lgr %r2,%r11 # pass pointer to pt_regs
318 larl %r14,sysc_return 317 larl %r14,sysc_return
319 jg do_per_trap 318 jg do_per_trap