From 818a330c4e1be9c39fa7ca9221e044907d92b4bb Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 14 Mar 2014 12:01:08 +0100 Subject: 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 --- arch/s390/include/asm/ptrace.h | 1 + arch/s390/include/asm/thread_info.h | 1 + arch/s390/include/uapi/asm/ptrace.h | 6 ++++++ arch/s390/kernel/ptrace.c | 13 ++++++++++++- 4 files changed, 20 insertions(+), 1 deletion(-) 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 { * These are defined as per linux/ptrace.h, which see. */ #define arch_has_single_step() (1) +#define arch_has_block_step() (1) #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) #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) #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_RESTORE_SIGMASK 19 /* restore signal mask in do_signal() */ #define TIF_SINGLE_STEP 20 /* This task is single stepped */ +#define TIF_BLOCK_STEP 21 /* This task is block stepped */ #define _TIF_SYSCALL (1<. + */ +#define PTRACE_SINGLEBLOCK 12 /* resume execution until next branch */ + /* * PT_PROT definition is loosely based on hppa bsd definition in * gdb/hppab-nat.c 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) /* merge TIF_SINGLE_STEP into user specified PER registers. */ if (test_tsk_thread_flag(task, TIF_SINGLE_STEP)) { - new.control |= PER_EVENT_IFETCH; + if (test_tsk_thread_flag(task, TIF_BLOCK_STEP)) + new.control |= PER_EVENT_BRANCH; + else + new.control |= PER_EVENT_IFETCH; #ifdef CONFIG_64BIT new.control |= PER_CONTROL_SUSPENSION; new.control |= PER_EVENT_TRANSACTION_END; @@ -107,14 +110,22 @@ void update_cr_regs(struct task_struct *task) void user_enable_single_step(struct task_struct *task) { + clear_tsk_thread_flag(task, TIF_BLOCK_STEP); set_tsk_thread_flag(task, TIF_SINGLE_STEP); } void user_disable_single_step(struct task_struct *task) { + clear_tsk_thread_flag(task, TIF_BLOCK_STEP); clear_tsk_thread_flag(task, TIF_SINGLE_STEP); } +void user_enable_block_step(struct task_struct *task) +{ + set_tsk_thread_flag(task, TIF_SINGLE_STEP); + set_tsk_thread_flag(task, TIF_BLOCK_STEP); +} + /* * Called by kernel/ptrace.c when detaching.. * -- cgit v1.2.3-59-g8ed1b