Commit 0ac30be4 authored by Roland McGrath's avatar Roland McGrath Committed by Martin Schwidefsky

[S390] single-step cleanup

Signed-off-by: default avatarRoland McGrath <roland@redhat.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent ea29ee16
...@@ -86,13 +86,13 @@ FixPerRegisters(struct task_struct *task) ...@@ -86,13 +86,13 @@ FixPerRegisters(struct task_struct *task)
per_info->control_regs.bits.storage_alt_space_ctl = 0; per_info->control_regs.bits.storage_alt_space_ctl = 0;
} }
static void set_single_step(struct task_struct *task) void user_enable_single_step(struct task_struct *task)
{ {
task->thread.per_info.single_step = 1; task->thread.per_info.single_step = 1;
FixPerRegisters(task); FixPerRegisters(task);
} }
static void clear_single_step(struct task_struct *task) void user_disable_single_step(struct task_struct *task)
{ {
task->thread.per_info.single_step = 0; task->thread.per_info.single_step = 0;
FixPerRegisters(task); FixPerRegisters(task);
...@@ -107,7 +107,7 @@ void ...@@ -107,7 +107,7 @@ void
ptrace_disable(struct task_struct *child) ptrace_disable(struct task_struct *child)
{ {
/* make sure the single step bit is not set. */ /* make sure the single step bit is not set. */
clear_single_step(child); user_disable_single_step(child);
} }
#ifndef CONFIG_64BIT #ifndef CONFIG_64BIT
...@@ -651,7 +651,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -651,7 +651,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->exit_code = data; child->exit_code = data;
/* make sure the single step bit is not set. */ /* make sure the single step bit is not set. */
clear_single_step(child); user_disable_single_step(child);
wake_up_process(child); wake_up_process(child);
return 0; return 0;
...@@ -665,7 +665,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -665,7 +665,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
return 0; return 0;
child->exit_code = SIGKILL; child->exit_code = SIGKILL;
/* make sure the single step bit is not set. */ /* make sure the single step bit is not set. */
clear_single_step(child); user_disable_single_step(child);
wake_up_process(child); wake_up_process(child);
return 0; return 0;
...@@ -675,10 +675,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -675,10 +675,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
return -EIO; return -EIO;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->exit_code = data; child->exit_code = data;
if (data) user_enable_single_step(child);
set_tsk_thread_flag(child, TIF_SINGLE_STEP);
else
set_single_step(child);
/* give it a chance to run. */ /* give it a chance to run. */
wake_up_process(child); wake_up_process(child);
return 0; return 0;
......
...@@ -471,6 +471,7 @@ void do_signal(struct pt_regs *regs) ...@@ -471,6 +471,7 @@ void do_signal(struct pt_regs *regs)
if (signr > 0) { if (signr > 0) {
/* Whee! Actually deliver the signal. */ /* Whee! Actually deliver the signal. */
int ret;
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
if (test_thread_flag(TIF_31BIT)) { if (test_thread_flag(TIF_31BIT)) {
extern int handle_signal32(unsigned long sig, extern int handle_signal32(unsigned long sig,
...@@ -478,15 +479,12 @@ void do_signal(struct pt_regs *regs) ...@@ -478,15 +479,12 @@ void do_signal(struct pt_regs *regs)
siginfo_t *info, siginfo_t *info,
sigset_t *oldset, sigset_t *oldset,
struct pt_regs *regs); struct pt_regs *regs);
if (handle_signal32( ret = handle_signal32(signr, &ka, &info, oldset, regs);
signr, &ka, &info, oldset, regs) == 0) {
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
}
return;
} }
else
#endif #endif
if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { ret = handle_signal(signr, &ka, &info, oldset, regs);
if (!ret) {
/* /*
* A signal was successfully delivered; the saved * A signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame, * sigmask will have been stored in the signal frame,
...@@ -495,6 +493,14 @@ void do_signal(struct pt_regs *regs) ...@@ -495,6 +493,14 @@ void do_signal(struct pt_regs *regs)
*/ */
if (test_thread_flag(TIF_RESTORE_SIGMASK)) if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK); clear_thread_flag(TIF_RESTORE_SIGMASK);
/*
* If we would have taken a single-step trap
* for a normal instruction, act like we took
* one for the handler setup.
*/
if (current->thread.per_info.single_step)
set_thread_flag(TIF_SINGLE_STEP);
} }
return; return;
} }
......
...@@ -465,6 +465,14 @@ struct user_regs_struct ...@@ -465,6 +465,14 @@ struct user_regs_struct
#ifdef __KERNEL__ #ifdef __KERNEL__
#define __ARCH_SYS_PTRACE 1 #define __ARCH_SYS_PTRACE 1
/*
* These are defined as per linux/ptrace.h, which see.
*/
#define arch_has_single_step() (1)
struct task_struct;
extern void user_enable_single_step(struct task_struct *);
extern void user_disable_single_step(struct task_struct *);
#define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
#define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
#define regs_return_value(regs)((regs)->gprs[2]) #define regs_return_value(regs)((regs)->gprs[2])
......
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