ptrace-noadv.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. #include <linux/regset.h>
  3. #include <linux/hw_breakpoint.h>
  4. #include <asm/debug.h>
  5. #include "ptrace-decl.h"
  6. void user_enable_single_step(struct task_struct *task)
  7. {
  8. struct pt_regs *regs = task->thread.regs;
  9. if (regs != NULL)
  10. regs_set_return_msr(regs, (regs->msr & ~MSR_BE) | MSR_SE);
  11. set_tsk_thread_flag(task, TIF_SINGLESTEP);
  12. }
  13. void user_enable_block_step(struct task_struct *task)
  14. {
  15. struct pt_regs *regs = task->thread.regs;
  16. if (regs != NULL)
  17. regs_set_return_msr(regs, (regs->msr & ~MSR_SE) | MSR_BE);
  18. set_tsk_thread_flag(task, TIF_SINGLESTEP);
  19. }
  20. void user_disable_single_step(struct task_struct *task)
  21. {
  22. struct pt_regs *regs = task->thread.regs;
  23. if (regs != NULL)
  24. regs_set_return_msr(regs, regs->msr & ~(MSR_SE | MSR_BE));
  25. clear_tsk_thread_flag(task, TIF_SINGLESTEP);
  26. }
  27. void ppc_gethwdinfo(struct ppc_debug_info *dbginfo)
  28. {
  29. dbginfo->version = 1;
  30. dbginfo->num_instruction_bps = 0;
  31. if (ppc_breakpoint_available())
  32. dbginfo->num_data_bps = nr_wp_slots();
  33. else
  34. dbginfo->num_data_bps = 0;
  35. dbginfo->num_condition_regs = 0;
  36. dbginfo->data_bp_alignment = sizeof(long);
  37. dbginfo->sizeof_condition = 0;
  38. if (IS_ENABLED(CONFIG_HAVE_HW_BREAKPOINT)) {
  39. dbginfo->features = PPC_DEBUG_FEATURE_DATA_BP_RANGE;
  40. if (dawr_enabled())
  41. dbginfo->features |= PPC_DEBUG_FEATURE_DATA_BP_DAWR;
  42. } else {
  43. dbginfo->features = 0;
  44. }
  45. if (cpu_has_feature(CPU_FTR_ARCH_31))
  46. dbginfo->features |= PPC_DEBUG_FEATURE_DATA_BP_ARCH_31;
  47. }
  48. int ptrace_get_debugreg(struct task_struct *child, unsigned long addr,
  49. unsigned long __user *datalp)
  50. {
  51. unsigned long dabr_fake;
  52. /* We only support one DABR and no IABRS at the moment */
  53. if (addr > 0)
  54. return -EINVAL;
  55. dabr_fake = ((child->thread.hw_brk[0].address & (~HW_BRK_TYPE_DABR)) |
  56. (child->thread.hw_brk[0].type & HW_BRK_TYPE_DABR));
  57. return put_user(dabr_fake, datalp);
  58. }
  59. /*
  60. * ptrace_set_debugreg() fakes DABR and DABR is only one. So even if
  61. * internal hw supports more than one watchpoint, we support only one
  62. * watchpoint with this interface.
  63. */
  64. int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, unsigned long data)
  65. {
  66. #ifdef CONFIG_HAVE_HW_BREAKPOINT
  67. int ret;
  68. struct thread_struct *thread = &task->thread;
  69. struct perf_event *bp;
  70. struct perf_event_attr attr;
  71. #endif /* CONFIG_HAVE_HW_BREAKPOINT */
  72. bool set_bp = true;
  73. struct arch_hw_breakpoint hw_brk;
  74. /* For ppc64 we support one DABR and no IABR's at the moment (ppc64).
  75. * For embedded processors we support one DAC and no IAC's at the
  76. * moment.
  77. */
  78. if (addr > 0)
  79. return -EINVAL;
  80. /* The bottom 3 bits in dabr are flags */
  81. if ((data & ~0x7UL) >= TASK_SIZE)
  82. return -EIO;
  83. /* For processors using DABR (i.e. 970), the bottom 3 bits are flags.
  84. * It was assumed, on previous implementations, that 3 bits were
  85. * passed together with the data address, fitting the design of the
  86. * DABR register, as follows:
  87. *
  88. * bit 0: Read flag
  89. * bit 1: Write flag
  90. * bit 2: Breakpoint translation
  91. *
  92. * Thus, we use them here as so.
  93. */
  94. /* Ensure breakpoint translation bit is set */
  95. if (data && !(data & HW_BRK_TYPE_TRANSLATE))
  96. return -EIO;
  97. hw_brk.address = data & (~HW_BRK_TYPE_DABR);
  98. hw_brk.type = (data & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
  99. hw_brk.len = DABR_MAX_LEN;
  100. hw_brk.hw_len = DABR_MAX_LEN;
  101. set_bp = (data) && (hw_brk.type & HW_BRK_TYPE_RDWR);
  102. #ifdef CONFIG_HAVE_HW_BREAKPOINT
  103. bp = thread->ptrace_bps[0];
  104. if (!set_bp) {
  105. if (bp) {
  106. unregister_hw_breakpoint(bp);
  107. thread->ptrace_bps[0] = NULL;
  108. }
  109. return 0;
  110. }
  111. if (bp) {
  112. attr = bp->attr;
  113. attr.bp_addr = hw_brk.address;
  114. attr.bp_len = DABR_MAX_LEN;
  115. arch_bp_generic_fields(hw_brk.type, &attr.bp_type);
  116. /* Enable breakpoint */
  117. attr.disabled = false;
  118. ret = modify_user_hw_breakpoint(bp, &attr);
  119. if (ret)
  120. return ret;
  121. thread->ptrace_bps[0] = bp;
  122. thread->hw_brk[0] = hw_brk;
  123. return 0;
  124. }
  125. /* Create a new breakpoint request if one doesn't exist already */
  126. hw_breakpoint_init(&attr);
  127. attr.bp_addr = hw_brk.address;
  128. attr.bp_len = DABR_MAX_LEN;
  129. arch_bp_generic_fields(hw_brk.type,
  130. &attr.bp_type);
  131. thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr,
  132. ptrace_triggered, NULL, task);
  133. if (IS_ERR(bp)) {
  134. thread->ptrace_bps[0] = NULL;
  135. return PTR_ERR(bp);
  136. }
  137. #else /* !CONFIG_HAVE_HW_BREAKPOINT */
  138. if (set_bp && (!ppc_breakpoint_available()))
  139. return -ENODEV;
  140. #endif /* CONFIG_HAVE_HW_BREAKPOINT */
  141. task->thread.hw_brk[0] = hw_brk;
  142. return 0;
  143. }
  144. #ifdef CONFIG_HAVE_HW_BREAKPOINT
  145. static int find_empty_ptrace_bp(struct thread_struct *thread)
  146. {
  147. int i;
  148. for (i = 0; i < nr_wp_slots(); i++) {
  149. if (!thread->ptrace_bps[i])
  150. return i;
  151. }
  152. return -1;
  153. }
  154. #endif
  155. static int find_empty_hw_brk(struct thread_struct *thread)
  156. {
  157. int i;
  158. for (i = 0; i < nr_wp_slots(); i++) {
  159. if (!thread->hw_brk[i].address)
  160. return i;
  161. }
  162. return -1;
  163. }
  164. long ppc_set_hwdebug(struct task_struct *child, struct ppc_hw_breakpoint *bp_info)
  165. {
  166. int i;
  167. #ifdef CONFIG_HAVE_HW_BREAKPOINT
  168. int len = 0;
  169. struct thread_struct *thread = &child->thread;
  170. struct perf_event *bp;
  171. struct perf_event_attr attr;
  172. #endif /* CONFIG_HAVE_HW_BREAKPOINT */
  173. struct arch_hw_breakpoint brk;
  174. if (bp_info->version != 1)
  175. return -ENOTSUPP;
  176. /*
  177. * We only support one data breakpoint
  178. */
  179. if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 ||
  180. (bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 ||
  181. bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)
  182. return -EINVAL;
  183. if ((unsigned long)bp_info->addr >= TASK_SIZE)
  184. return -EIO;
  185. brk.address = ALIGN_DOWN(bp_info->addr, HW_BREAKPOINT_SIZE);
  186. brk.type = HW_BRK_TYPE_TRANSLATE | HW_BRK_TYPE_PRIV_ALL;
  187. brk.len = DABR_MAX_LEN;
  188. brk.hw_len = DABR_MAX_LEN;
  189. if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
  190. brk.type |= HW_BRK_TYPE_READ;
  191. if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
  192. brk.type |= HW_BRK_TYPE_WRITE;
  193. #ifdef CONFIG_HAVE_HW_BREAKPOINT
  194. if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE)
  195. len = bp_info->addr2 - bp_info->addr;
  196. else if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT)
  197. len = 1;
  198. else
  199. return -EINVAL;
  200. i = find_empty_ptrace_bp(thread);
  201. if (i < 0)
  202. return -ENOSPC;
  203. /* Create a new breakpoint request if one doesn't exist already */
  204. hw_breakpoint_init(&attr);
  205. attr.bp_addr = (unsigned long)bp_info->addr;
  206. attr.bp_len = len;
  207. arch_bp_generic_fields(brk.type, &attr.bp_type);
  208. bp = register_user_hw_breakpoint(&attr, ptrace_triggered, NULL, child);
  209. thread->ptrace_bps[i] = bp;
  210. if (IS_ERR(bp)) {
  211. thread->ptrace_bps[i] = NULL;
  212. return PTR_ERR(bp);
  213. }
  214. return i + 1;
  215. #endif /* CONFIG_HAVE_HW_BREAKPOINT */
  216. if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT)
  217. return -EINVAL;
  218. i = find_empty_hw_brk(&child->thread);
  219. if (i < 0)
  220. return -ENOSPC;
  221. if (!ppc_breakpoint_available())
  222. return -ENODEV;
  223. child->thread.hw_brk[i] = brk;
  224. return i + 1;
  225. }
  226. long ppc_del_hwdebug(struct task_struct *child, long data)
  227. {
  228. #ifdef CONFIG_HAVE_HW_BREAKPOINT
  229. int ret = 0;
  230. struct thread_struct *thread = &child->thread;
  231. struct perf_event *bp;
  232. #endif /* CONFIG_HAVE_HW_BREAKPOINT */
  233. if (data < 1 || data > nr_wp_slots())
  234. return -EINVAL;
  235. #ifdef CONFIG_HAVE_HW_BREAKPOINT
  236. bp = thread->ptrace_bps[data - 1];
  237. if (bp) {
  238. unregister_hw_breakpoint(bp);
  239. thread->ptrace_bps[data - 1] = NULL;
  240. } else {
  241. ret = -ENOENT;
  242. }
  243. return ret;
  244. #else /* CONFIG_HAVE_HW_BREAKPOINT */
  245. if (!(child->thread.hw_brk[data - 1].flags & HW_BRK_FLAG_DISABLED) &&
  246. child->thread.hw_brk[data - 1].address == 0)
  247. return -ENOENT;
  248. child->thread.hw_brk[data - 1].address = 0;
  249. child->thread.hw_brk[data - 1].type = 0;
  250. child->thread.hw_brk[data - 1].flags = 0;
  251. #endif /* CONFIG_HAVE_HW_BREAKPOINT */
  252. return 0;
  253. }