1 // SPDX-License-Identifier: GPL-2.0-or-later
3 #include <linux/regset.h>
4 #include <linux/hw_breakpoint.h>
8 #include "ptrace-decl.h"
10 void user_enable_single_step(struct task_struct
*task
)
12 struct pt_regs
*regs
= task
->thread
.regs
;
18 set_tsk_thread_flag(task
, TIF_SINGLESTEP
);
21 void user_enable_block_step(struct task_struct
*task
)
23 struct pt_regs
*regs
= task
->thread
.regs
;
29 set_tsk_thread_flag(task
, TIF_SINGLESTEP
);
32 void user_disable_single_step(struct task_struct
*task
)
34 struct pt_regs
*regs
= task
->thread
.regs
;
37 regs
->msr
&= ~(MSR_SE
| MSR_BE
);
39 clear_tsk_thread_flag(task
, TIF_SINGLESTEP
);
42 void ppc_gethwdinfo(struct ppc_debug_info
*dbginfo
)
45 dbginfo
->num_instruction_bps
= 0;
46 if (ppc_breakpoint_available())
47 dbginfo
->num_data_bps
= nr_wp_slots();
49 dbginfo
->num_data_bps
= 0;
50 dbginfo
->num_condition_regs
= 0;
51 dbginfo
->data_bp_alignment
= sizeof(long);
52 dbginfo
->sizeof_condition
= 0;
53 if (IS_ENABLED(CONFIG_HAVE_HW_BREAKPOINT
)) {
54 dbginfo
->features
= PPC_DEBUG_FEATURE_DATA_BP_RANGE
;
56 dbginfo
->features
|= PPC_DEBUG_FEATURE_DATA_BP_DAWR
;
58 dbginfo
->features
= 0;
60 if (cpu_has_feature(CPU_FTR_ARCH_31
))
61 dbginfo
->features
|= PPC_DEBUG_FEATURE_DATA_BP_ARCH_31
;
64 int ptrace_get_debugreg(struct task_struct
*child
, unsigned long addr
,
65 unsigned long __user
*datalp
)
67 unsigned long dabr_fake
;
69 /* We only support one DABR and no IABRS at the moment */
72 dabr_fake
= ((child
->thread
.hw_brk
[0].address
& (~HW_BRK_TYPE_DABR
)) |
73 (child
->thread
.hw_brk
[0].type
& HW_BRK_TYPE_DABR
));
74 return put_user(dabr_fake
, datalp
);
78 * ptrace_set_debugreg() fakes DABR and DABR is only one. So even if
79 * internal hw supports more than one watchpoint, we support only one
80 * watchpoint with this interface.
82 int ptrace_set_debugreg(struct task_struct
*task
, unsigned long addr
, unsigned long data
)
84 #ifdef CONFIG_HAVE_HW_BREAKPOINT
86 struct thread_struct
*thread
= &task
->thread
;
87 struct perf_event
*bp
;
88 struct perf_event_attr attr
;
89 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
91 struct arch_hw_breakpoint hw_brk
;
93 /* For ppc64 we support one DABR and no IABR's at the moment (ppc64).
94 * For embedded processors we support one DAC and no IAC's at the
100 /* The bottom 3 bits in dabr are flags */
101 if ((data
& ~0x7UL
) >= TASK_SIZE
)
104 /* For processors using DABR (i.e. 970), the bottom 3 bits are flags.
105 * It was assumed, on previous implementations, that 3 bits were
106 * passed together with the data address, fitting the design of the
107 * DABR register, as follows:
111 * bit 2: Breakpoint translation
113 * Thus, we use them here as so.
116 /* Ensure breakpoint translation bit is set */
117 if (data
&& !(data
& HW_BRK_TYPE_TRANSLATE
))
119 hw_brk
.address
= data
& (~HW_BRK_TYPE_DABR
);
120 hw_brk
.type
= (data
& HW_BRK_TYPE_DABR
) | HW_BRK_TYPE_PRIV_ALL
;
121 hw_brk
.len
= DABR_MAX_LEN
;
122 hw_brk
.hw_len
= DABR_MAX_LEN
;
123 set_bp
= (data
) && (hw_brk
.type
& HW_BRK_TYPE_RDWR
);
124 #ifdef CONFIG_HAVE_HW_BREAKPOINT
125 bp
= thread
->ptrace_bps
[0];
128 unregister_hw_breakpoint(bp
);
129 thread
->ptrace_bps
[0] = NULL
;
135 attr
.bp_addr
= hw_brk
.address
;
136 attr
.bp_len
= DABR_MAX_LEN
;
137 arch_bp_generic_fields(hw_brk
.type
, &attr
.bp_type
);
139 /* Enable breakpoint */
140 attr
.disabled
= false;
142 ret
= modify_user_hw_breakpoint(bp
, &attr
);
146 thread
->ptrace_bps
[0] = bp
;
147 thread
->hw_brk
[0] = hw_brk
;
151 /* Create a new breakpoint request if one doesn't exist already */
152 hw_breakpoint_init(&attr
);
153 attr
.bp_addr
= hw_brk
.address
;
154 attr
.bp_len
= DABR_MAX_LEN
;
155 arch_bp_generic_fields(hw_brk
.type
,
158 thread
->ptrace_bps
[0] = bp
= register_user_hw_breakpoint(&attr
,
159 ptrace_triggered
, NULL
, task
);
161 thread
->ptrace_bps
[0] = NULL
;
165 #else /* !CONFIG_HAVE_HW_BREAKPOINT */
166 if (set_bp
&& (!ppc_breakpoint_available()))
168 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
169 task
->thread
.hw_brk
[0] = hw_brk
;
173 #ifdef CONFIG_HAVE_HW_BREAKPOINT
174 static int find_empty_ptrace_bp(struct thread_struct
*thread
)
178 for (i
= 0; i
< nr_wp_slots(); i
++) {
179 if (!thread
->ptrace_bps
[i
])
186 static int find_empty_hw_brk(struct thread_struct
*thread
)
190 for (i
= 0; i
< nr_wp_slots(); i
++) {
191 if (!thread
->hw_brk
[i
].address
)
197 long ppc_set_hwdebug(struct task_struct
*child
, struct ppc_hw_breakpoint
*bp_info
)
200 #ifdef CONFIG_HAVE_HW_BREAKPOINT
202 struct thread_struct
*thread
= &child
->thread
;
203 struct perf_event
*bp
;
204 struct perf_event_attr attr
;
205 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
206 struct arch_hw_breakpoint brk
;
208 if (bp_info
->version
!= 1)
211 * We only support one data breakpoint
213 if ((bp_info
->trigger_type
& PPC_BREAKPOINT_TRIGGER_RW
) == 0 ||
214 (bp_info
->trigger_type
& ~PPC_BREAKPOINT_TRIGGER_RW
) != 0 ||
215 bp_info
->condition_mode
!= PPC_BREAKPOINT_CONDITION_NONE
)
218 if ((unsigned long)bp_info
->addr
>= TASK_SIZE
)
221 brk
.address
= ALIGN_DOWN(bp_info
->addr
, HW_BREAKPOINT_SIZE
);
222 brk
.type
= HW_BRK_TYPE_TRANSLATE
| HW_BRK_TYPE_PRIV_ALL
;
223 brk
.len
= DABR_MAX_LEN
;
224 brk
.hw_len
= DABR_MAX_LEN
;
225 if (bp_info
->trigger_type
& PPC_BREAKPOINT_TRIGGER_READ
)
226 brk
.type
|= HW_BRK_TYPE_READ
;
227 if (bp_info
->trigger_type
& PPC_BREAKPOINT_TRIGGER_WRITE
)
228 brk
.type
|= HW_BRK_TYPE_WRITE
;
229 #ifdef CONFIG_HAVE_HW_BREAKPOINT
230 if (bp_info
->addr_mode
== PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE
)
231 len
= bp_info
->addr2
- bp_info
->addr
;
232 else if (bp_info
->addr_mode
== PPC_BREAKPOINT_MODE_EXACT
)
237 i
= find_empty_ptrace_bp(thread
);
241 /* Create a new breakpoint request if one doesn't exist already */
242 hw_breakpoint_init(&attr
);
243 attr
.bp_addr
= (unsigned long)bp_info
->addr
;
245 arch_bp_generic_fields(brk
.type
, &attr
.bp_type
);
247 bp
= register_user_hw_breakpoint(&attr
, ptrace_triggered
, NULL
, child
);
248 thread
->ptrace_bps
[i
] = bp
;
250 thread
->ptrace_bps
[i
] = NULL
;
255 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
257 if (bp_info
->addr_mode
!= PPC_BREAKPOINT_MODE_EXACT
)
260 i
= find_empty_hw_brk(&child
->thread
);
264 if (!ppc_breakpoint_available())
267 child
->thread
.hw_brk
[i
] = brk
;
272 long ppc_del_hwdebug(struct task_struct
*child
, long data
)
274 #ifdef CONFIG_HAVE_HW_BREAKPOINT
276 struct thread_struct
*thread
= &child
->thread
;
277 struct perf_event
*bp
;
278 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
279 if (data
< 1 || data
> nr_wp_slots())
282 #ifdef CONFIG_HAVE_HW_BREAKPOINT
283 bp
= thread
->ptrace_bps
[data
- 1];
285 unregister_hw_breakpoint(bp
);
286 thread
->ptrace_bps
[data
- 1] = NULL
;
291 #else /* CONFIG_HAVE_HW_BREAKPOINT */
292 if (!(child
->thread
.hw_brk
[data
- 1].flags
& HW_BRK_FLAG_DISABLED
) &&
293 child
->thread
.hw_brk
[data
- 1].address
== 0)
296 child
->thread
.hw_brk
[data
- 1].address
= 0;
297 child
->thread
.hw_brk
[data
- 1].type
= 0;
298 child
->thread
.hw_brk
[data
- 1].flags
= 0;
299 #endif /* CONFIG_HAVE_HW_BREAKPOINT */