aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/powerpc/ptrace.txt134
-rw-r--r--arch/powerpc/include/asm/ptrace.h77
-rw-r--r--arch/powerpc/kernel/ptrace.c90
3 files changed, 301 insertions, 0 deletions
diff --git a/Documentation/powerpc/ptrace.txt b/Documentation/powerpc/ptrace.txt
new file mode 100644
index 000000000000..f4a5499b7bc6
--- /dev/null
+++ b/Documentation/powerpc/ptrace.txt
@@ -0,0 +1,134 @@
1GDB intends to support the following hardware debug features of BookE
2processors:
3
44 hardware breakpoints (IAC)
52 hardware watchpoints (read, write and read-write) (DAC)
62 value conditions for the hardware watchpoints (DVC)
7
8For that, we need to extend ptrace so that GDB can query and set these
9resources. Since we're extending, we're trying to create an interface
10that's extendable and that covers both BookE and server processors, so
11that GDB doesn't need to special-case each of them. We added the
12following 3 new ptrace requests.
13
141. PTRACE_PPC_GETHWDEBUGINFO
15
16Query for GDB to discover the hardware debug features. The main info to
17be returned here is the minimum alignment for the hardware watchpoints.
18BookE processors don't have restrictions here, but server processors have
19an 8-byte alignment restriction for hardware watchpoints. We'd like to avoid
20adding special cases to GDB based on what it sees in AUXV.
21
22Since we're at it, we added other useful info that the kernel can return to
23GDB: this query will return the number of hardware breakpoints, hardware
24watchpoints and whether it supports a range of addresses and a condition.
25The query will fill the following structure provided by the requesting process:
26
27struct ppc_debug_info {
28 unit32_t version;
29 unit32_t num_instruction_bps;
30 unit32_t num_data_bps;
31 unit32_t num_condition_regs;
32 unit32_t data_bp_alignment;
33 unit32_t sizeof_condition; /* size of the DVC register */
34 uint64_t features; /* bitmask of the individual flags */
35};
36
37features will have bits indicating whether there is support for:
38
39#define PPC_DEBUG_FEATURE_INSN_BP_RANGE 0x1
40#define PPC_DEBUG_FEATURE_INSN_BP_MASK 0x2
41#define PPC_DEBUG_FEATURE_DATA_BP_RANGE 0x4
42#define PPC_DEBUG_FEATURE_DATA_BP_MASK 0x8
43
442. PTRACE_SETHWDEBUG
45
46Sets a hardware breakpoint or watchpoint, according to the provided structure:
47
48struct ppc_hw_breakpoint {
49 uint32_t version;
50#define PPC_BREAKPOINT_TRIGGER_EXECUTE 0x1
51#define PPC_BREAKPOINT_TRIGGER_READ 0x2
52#define PPC_BREAKPOINT_TRIGGER_WRITE 0x4
53 uint32_t trigger_type; /* only some combinations allowed */
54#define PPC_BREAKPOINT_MODE_EXACT 0x0
55#define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE 0x1
56#define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE 0x2
57#define PPC_BREAKPOINT_MODE_MASK 0x3
58 uint32_t addr_mode; /* address match mode */
59
60#define PPC_BREAKPOINT_CONDITION_MODE 0x3
61#define PPC_BREAKPOINT_CONDITION_NONE 0x0
62#define PPC_BREAKPOINT_CONDITION_AND 0x1
63#define PPC_BREAKPOINT_CONDITION_EXACT 0x1 /* different name for the same thing as above */
64#define PPC_BREAKPOINT_CONDITION_OR 0x2
65#define PPC_BREAKPOINT_CONDITION_AND_OR 0x3
66#define PPC_BREAKPOINT_CONDITION_BE_ALL 0x00ff0000 /* byte enable bits */
67#define PPC_BREAKPOINT_CONDITION_BE(n) (1<<((n)+16))
68 uint32_t condition_mode; /* break/watchpoint condition flags */
69
70 uint64_t addr;
71 uint64_t addr2;
72 uint64_t condition_value;
73};
74
75A request specifies one event, not necessarily just one register to be set.
76For instance, if the request is for a watchpoint with a condition, both the
77DAC and DVC registers will be set in the same request.
78
79With this GDB can ask for all kinds of hardware breakpoints and watchpoints
80that the BookE supports. COMEFROM breakpoints available in server processors
81are not contemplated, but that is out of the scope of this work.
82
83ptrace will return an integer (handle) uniquely identifying the breakpoint or
84watchpoint just created. This integer will be used in the PTRACE_DELHWDEBUG
85request to ask for its removal. Return -ENOSPC if the requested breakpoint
86can't be allocated on the registers.
87
88Some examples of using the structure to:
89
90- set a breakpoint in the first breakpoint register
91
92 p.version = PPC_DEBUG_CURRENT_VERSION;
93 p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE;
94 p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
95 p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
96 p.addr = (uint64_t) address;
97 p.addr2 = 0;
98 p.condition_value = 0;
99
100- set a watchpoint which triggers on reads in the second watchpoint register
101
102 p.version = PPC_DEBUG_CURRENT_VERSION;
103 p.trigger_type = PPC_BREAKPOINT_TRIGGER_READ;
104 p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
105 p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
106 p.addr = (uint64_t) address;
107 p.addr2 = 0;
108 p.condition_value = 0;
109
110- set a watchpoint which triggers only with a specific value
111
112 p.version = PPC_DEBUG_CURRENT_VERSION;
113 p.trigger_type = PPC_BREAKPOINT_TRIGGER_READ;
114 p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
115 p.condition_mode = PPC_BREAKPOINT_CONDITION_AND | PPC_BREAKPOINT_CONDITION_BE_ALL;
116 p.addr = (uint64_t) address;
117 p.addr2 = 0;
118 p.condition_value = (uint64_t) condition;
119
120- set a ranged hardware breakpoint
121
122 p.version = PPC_DEBUG_CURRENT_VERSION;
123 p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE;
124 p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
125 p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
126 p.addr = (uint64_t) begin_range;
127 p.addr2 = (uint64_t) end_range;
128 p.condition_value = 0;
129
1303. PTRACE_DELHWDEBUG
131
132Takes an integer which identifies an existing breakpoint or watchpoint
133(i.e., the value returned from PTRACE_SETHWDEBUG), and deletes the
134corresponding breakpoint or watchpoint..
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index cbd759e3cd78..b45108126562 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -24,6 +24,12 @@
24 * 2 of the License, or (at your option) any later version. 24 * 2 of the License, or (at your option) any later version.
25 */ 25 */
26 26
27#ifdef __KERNEL__
28#include <linux/types.h>
29#else
30#include <stdint.h>
31#endif
32
27#ifndef __ASSEMBLY__ 33#ifndef __ASSEMBLY__
28 34
29struct pt_regs { 35struct pt_regs {
@@ -294,4 +300,75 @@ extern void user_disable_single_step(struct task_struct *);
294 300
295#define PTRACE_SINGLEBLOCK 0x100 /* resume execution until next branch */ 301#define PTRACE_SINGLEBLOCK 0x100 /* resume execution until next branch */
296 302
303#define PPC_PTRACE_GETHWDBGINFO 0x89
304#define PPC_PTRACE_SETHWDEBUG 0x88
305#define PPC_PTRACE_DELHWDEBUG 0x87
306
307#ifndef __ASSEMBLY__
308
309struct ppc_debug_info {
310 uint32_t version; /* Only version 1 exists to date */
311 uint32_t num_instruction_bps;
312 uint32_t num_data_bps;
313 uint32_t num_condition_regs;
314 uint32_t data_bp_alignment;
315 uint32_t sizeof_condition; /* size of the DVC register */
316 uint64_t features;
317};
318
319#endif /* __ASSEMBLY__ */
320
321/*
322 * features will have bits indication whether there is support for:
323 */
324#define PPC_DEBUG_FEATURE_INSN_BP_RANGE 0x0000000000000001
325#define PPC_DEBUG_FEATURE_INSN_BP_MASK 0x0000000000000002
326#define PPC_DEBUG_FEATURE_DATA_BP_RANGE 0x0000000000000004
327#define PPC_DEBUG_FEATURE_DATA_BP_MASK 0x0000000000000008
328
329#ifndef __ASSEMBLY__
330
331struct ppc_hw_breakpoint {
332 uint32_t version; /* currently, version must be 1 */
333 uint32_t trigger_type; /* only some combinations allowed */
334 uint32_t addr_mode; /* address match mode */
335 uint32_t condition_mode; /* break/watchpoint condition flags */
336 uint64_t addr; /* break/watchpoint address */
337 uint64_t addr2; /* range end or mask */
338 uint64_t condition_value; /* contents of the DVC register */
339};
340
341#endif /* __ASSEMBLY__ */
342
343/*
344 * Trigger Type
345 */
346#define PPC_BREAKPOINT_TRIGGER_EXECUTE 0x00000001
347#define PPC_BREAKPOINT_TRIGGER_READ 0x00000002
348#define PPC_BREAKPOINT_TRIGGER_WRITE 0x00000004
349#define PPC_BREAKPOINT_TRIGGER_RW \
350 (PPC_BREAKPOINT_TRIGGER_READ | PPC_BREAKPOINT_TRIGGER_WRITE)
351
352/*
353 * Address Mode
354 */
355#define PPC_BREAKPOINT_MODE_EXACT 0x00000000
356#define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE 0x00000001
357#define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE 0x00000002
358#define PPC_BREAKPOINT_MODE_MASK 0x00000003
359
360/*
361 * Condition Mode
362 */
363#define PPC_BREAKPOINT_CONDITION_MODE 0x00000003
364#define PPC_BREAKPOINT_CONDITION_NONE 0x00000000
365#define PPC_BREAKPOINT_CONDITION_AND 0x00000001
366#define PPC_BREAKPOINT_CONDITION_EXACT PPC_BREAKPOINT_CONDITION_AND
367#define PPC_BREAKPOINT_CONDITION_OR 0x00000002
368#define PPC_BREAKPOINT_CONDITION_AND_OR 0x00000003
369#define PPC_BREAKPOINT_CONDITION_BE_ALL 0x00ff0000
370#define PPC_BREAKPOINT_CONDITION_BE_SHIFT 16
371#define PPC_BREAKPOINT_CONDITION_BE(n) \
372 (1<<((n)+PPC_BREAKPOINT_CONDITION_BE_SHIFT))
373
297#endif /* _ASM_POWERPC_PTRACE_H */ 374#endif /* _ASM_POWERPC_PTRACE_H */
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 292c81432014..8847bd618cec 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -835,6 +835,52 @@ void ptrace_disable(struct task_struct *child)
835 user_disable_single_step(child); 835 user_disable_single_step(child);
836} 836}
837 837
838static long ppc_set_hwdebug(struct task_struct *child,
839 struct ppc_hw_breakpoint *bp_info)
840{
841 /*
842 * We currently support one data breakpoint
843 */
844 if (((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0) ||
845 ((bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0) ||
846 (bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_WRITE) ||
847 (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) ||
848 (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE))
849 return -EINVAL;
850
851 if (child->thread.dabr)
852 return -ENOSPC;
853
854 if ((unsigned long)bp_info->addr >= TASK_SIZE)
855 return -EIO;
856
857 child->thread.dabr = (unsigned long)bp_info->addr;
858#ifdef CONFIG_PPC_ADV_DEBUG_REGS
859 child->thread.dbcr0 = DBCR0_IDM;
860 if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
861 child->thread.dbcr0 |= DBSR_DAC1R;
862 if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
863 child->thread.dbcr0 |= DBSR_DAC1W;
864 child->thread.regs->msr |= MSR_DE;
865#endif
866 return 1;
867}
868
869static long ppc_del_hwdebug(struct task_struct *child, long addr, long data)
870{
871 if (data != 1)
872 return -EINVAL;
873 if (child->thread.dabr == 0)
874 return -ENOENT;
875
876 child->thread.dabr = 0;
877#ifdef CONFIG_PPC_ADV_DEBUG_REGS
878 child->thread.dbcr0 &= ~(DBSR_DAC1R | DBSR_DAC1W | DBCR0_IDM);
879 child->thread.regs->msr &= ~MSR_DE;
880#endif
881 return 0;
882}
883
838/* 884/*
839 * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls, 885 * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls,
840 * we mark them as obsolete now, they will be removed in a future version 886 * we mark them as obsolete now, they will be removed in a future version
@@ -928,6 +974,50 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
928 break; 974 break;
929 } 975 }
930 976
977 case PPC_PTRACE_GETHWDBGINFO: {
978 struct ppc_debug_info dbginfo;
979
980 dbginfo.version = 1;
981 dbginfo.num_instruction_bps = 0;
982 dbginfo.num_data_bps = 1;
983 dbginfo.num_condition_regs = 0;
984#ifdef CONFIG_PPC64
985 dbginfo.data_bp_alignment = 8;
986#else
987 dbginfo.data_bp_alignment = 4;
988#endif
989 dbginfo.sizeof_condition = 0;
990 dbginfo.features = 0;
991
992 if (!access_ok(VERIFY_WRITE, data,
993 sizeof(struct ppc_debug_info)))
994 return -EFAULT;
995 ret = __copy_to_user((struct ppc_debug_info __user *)data,
996 &dbginfo, sizeof(struct ppc_debug_info)) ?
997 -EFAULT : 0;
998 break;
999 }
1000
1001 case PPC_PTRACE_SETHWDEBUG: {
1002 struct ppc_hw_breakpoint bp_info;
1003
1004 if (!access_ok(VERIFY_READ, data,
1005 sizeof(struct ppc_hw_breakpoint)))
1006 return -EFAULT;
1007 ret = __copy_from_user(&bp_info,
1008 (struct ppc_hw_breakpoint __user *)data,
1009 sizeof(struct ppc_hw_breakpoint)) ?
1010 -EFAULT : 0;
1011 if (!ret)
1012 ret = ppc_set_hwdebug(child, &bp_info);
1013 break;
1014 }
1015
1016 case PPC_PTRACE_DELHWDEBUG: {
1017 ret = ppc_del_hwdebug(child, addr, data);
1018 break;
1019 }
1020
931 case PTRACE_GET_DEBUGREG: { 1021 case PTRACE_GET_DEBUGREG: {
932 ret = -EINVAL; 1022 ret = -EINVAL;
933 /* We only support one DABR and no IABRS at the moment */ 1023 /* We only support one DABR and no IABRS at the moment */