aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2014-03-14 07:01:08 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2014-03-14 07:59:38 -0400
commit818a330c4e1be9c39fa7ca9221e044907d92b4bb (patch)
tree1341793bde170543839a96a71fd72350c8f04c1d
parent443fc8a3e01cef95f2c7c26605457d49e63da6b1 (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>
-rw-r--r--arch/s390/include/asm/ptrace.h1
-rw-r--r--arch/s390/include/asm/thread_info.h1
-rw-r--r--arch/s390/include/uapi/asm/ptrace.h6
-rw-r--r--arch/s390/kernel/ptrace.c13
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
108void user_enable_single_step(struct task_struct *task) 111void 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
113void user_disable_single_step(struct task_struct *task) 117void 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
123void 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 *