diff options
| author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-03-14 07:01:08 -0400 |
|---|---|---|
| committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-03-14 07:59:38 -0400 |
| commit | 818a330c4e1be9c39fa7ca9221e044907d92b4bb (patch) | |
| tree | 1341793bde170543839a96a71fd72350c8f04c1d /arch | |
| parent | 443fc8a3e01cef95f2c7c26605457d49e63da6b1 (diff) | |
s390/ptrace: add support for PTRACE_SINGLEBLOCK
The PTRACE_SINGLEBLOCK option is used to get control whenever
the inferior has executed a successful branch. The PER option to
implement block stepping is successful-branching event, bit 32
in the PER-event mask.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/s390/include/asm/ptrace.h | 1 | ||||
| -rw-r--r-- | arch/s390/include/asm/thread_info.h | 1 | ||||
| -rw-r--r-- | arch/s390/include/uapi/asm/ptrace.h | 6 | ||||
| -rw-r--r-- | arch/s390/kernel/ptrace.c | 13 |
4 files changed, 20 insertions, 1 deletions
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h index 9c82cebddabd..f4783c0b7b43 100644 --- a/arch/s390/include/asm/ptrace.h +++ b/arch/s390/include/asm/ptrace.h | |||
| @@ -83,6 +83,7 @@ struct per_struct_kernel { | |||
| 83 | * These are defined as per linux/ptrace.h, which see. | 83 | * These are defined as per linux/ptrace.h, which see. |
| 84 | */ | 84 | */ |
| 85 | #define arch_has_single_step() (1) | 85 | #define arch_has_single_step() (1) |
| 86 | #define arch_has_block_step() (1) | ||
| 86 | 87 | ||
| 87 | #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) | 88 | #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) |
| 88 | #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) | 89 | #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) |
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index d2e53d667a92..3ccd71b90345 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h | |||
| @@ -92,6 +92,7 @@ static inline struct thread_info *current_thread_info(void) | |||
| 92 | #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ | 92 | #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ |
| 93 | #define TIF_RESTORE_SIGMASK 19 /* restore signal mask in do_signal() */ | 93 | #define TIF_RESTORE_SIGMASK 19 /* restore signal mask in do_signal() */ |
| 94 | #define TIF_SINGLE_STEP 20 /* This task is single stepped */ | 94 | #define TIF_SINGLE_STEP 20 /* This task is single stepped */ |
| 95 | #define TIF_BLOCK_STEP 21 /* This task is block stepped */ | ||
| 95 | 96 | ||
| 96 | #define _TIF_SYSCALL (1<<TIF_SYSCALL) | 97 | #define _TIF_SYSCALL (1<<TIF_SYSCALL) |
| 97 | #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) | 98 | #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) |
diff --git a/arch/s390/include/uapi/asm/ptrace.h b/arch/s390/include/uapi/asm/ptrace.h index 7e0b498a2c2b..a150f4fabe43 100644 --- a/arch/s390/include/uapi/asm/ptrace.h +++ b/arch/s390/include/uapi/asm/ptrace.h | |||
| @@ -403,6 +403,12 @@ typedef struct | |||
| 403 | #define PTRACE_TE_ABORT_RAND 0x5011 | 403 | #define PTRACE_TE_ABORT_RAND 0x5011 |
| 404 | 404 | ||
| 405 | /* | 405 | /* |
| 406 | * The numbers chosen here are somewhat arbitrary but absolutely MUST | ||
| 407 | * not overlap with any of the number assigned in <linux/ptrace.h>. | ||
| 408 | */ | ||
| 409 | #define PTRACE_SINGLEBLOCK 12 /* resume execution until next branch */ | ||
| 410 | |||
| 411 | /* | ||
| 406 | * PT_PROT definition is loosely based on hppa bsd definition in | 412 | * PT_PROT definition is loosely based on hppa bsd definition in |
| 407 | * gdb/hppab-nat.c | 413 | * gdb/hppab-nat.c |
| 408 | */ | 414 | */ |
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index f6be6087a0e9..4ac8fafec95f 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
| @@ -85,7 +85,10 @@ void update_cr_regs(struct task_struct *task) | |||
| 85 | 85 | ||
| 86 | /* merge TIF_SINGLE_STEP into user specified PER registers. */ | 86 | /* merge TIF_SINGLE_STEP into user specified PER registers. */ |
| 87 | if (test_tsk_thread_flag(task, TIF_SINGLE_STEP)) { | 87 | if (test_tsk_thread_flag(task, TIF_SINGLE_STEP)) { |
| 88 | new.control |= PER_EVENT_IFETCH; | 88 | if (test_tsk_thread_flag(task, TIF_BLOCK_STEP)) |
| 89 | new.control |= PER_EVENT_BRANCH; | ||
| 90 | else | ||
| 91 | new.control |= PER_EVENT_IFETCH; | ||
| 89 | #ifdef CONFIG_64BIT | 92 | #ifdef CONFIG_64BIT |
| 90 | new.control |= PER_CONTROL_SUSPENSION; | 93 | new.control |= PER_CONTROL_SUSPENSION; |
| 91 | new.control |= PER_EVENT_TRANSACTION_END; | 94 | new.control |= PER_EVENT_TRANSACTION_END; |
| @@ -107,14 +110,22 @@ void update_cr_regs(struct task_struct *task) | |||
| 107 | 110 | ||
| 108 | void user_enable_single_step(struct task_struct *task) | 111 | void user_enable_single_step(struct task_struct *task) |
| 109 | { | 112 | { |
| 113 | clear_tsk_thread_flag(task, TIF_BLOCK_STEP); | ||
| 110 | set_tsk_thread_flag(task, TIF_SINGLE_STEP); | 114 | set_tsk_thread_flag(task, TIF_SINGLE_STEP); |
| 111 | } | 115 | } |
| 112 | 116 | ||
| 113 | void user_disable_single_step(struct task_struct *task) | 117 | void user_disable_single_step(struct task_struct *task) |
| 114 | { | 118 | { |
| 119 | clear_tsk_thread_flag(task, TIF_BLOCK_STEP); | ||
| 115 | clear_tsk_thread_flag(task, TIF_SINGLE_STEP); | 120 | clear_tsk_thread_flag(task, TIF_SINGLE_STEP); |
| 116 | } | 121 | } |
| 117 | 122 | ||
| 123 | void user_enable_block_step(struct task_struct *task) | ||
| 124 | { | ||
| 125 | set_tsk_thread_flag(task, TIF_SINGLE_STEP); | ||
| 126 | set_tsk_thread_flag(task, TIF_BLOCK_STEP); | ||
| 127 | } | ||
| 128 | |||
| 118 | /* | 129 | /* |
| 119 | * Called by kernel/ptrace.c when detaching.. | 130 | * Called by kernel/ptrace.c when detaching.. |
| 120 | * | 131 | * |
