s390/ptrace: add support for PTRACE_SINGLEBLOCK
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Fri, 14 Mar 2014 11:01:08 +0000 (12:01 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Fri, 14 Mar 2014 11:59:38 +0000 (12:59 +0100)
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>
arch/s390/include/asm/ptrace.h
arch/s390/include/asm/thread_info.h
arch/s390/include/uapi/asm/ptrace.h
arch/s390/kernel/ptrace.c

index 9c82ceb..f4783c0 100644 (file)
@@ -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)
index d2e53d6..3ccd71b 100644 (file)
@@ -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<<TIF_SYSCALL)
 #define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
index 7e0b498..a150f4f 100644 (file)
@@ -402,6 +402,12 @@ typedef struct
 #define PTRACE_DISABLE_TE            0x5010
 #define PTRACE_TE_ABORT_RAND         0x5011
 
+/*
+ * The numbers chosen here are somewhat arbitrary but absolutely MUST
+ * not overlap with any of the number assigned in <linux/ptrace.h>.
+ */
+#define PTRACE_SINGLEBLOCK     12      /* resume execution until next branch */
+
 /*
  * PT_PROT definition is loosely based on hppa bsd definition in
  * gdb/hppab-nat.c
index f6be608..4ac8faf 100644 (file)
@@ -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..
  *