actions-arm.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * arch/arm/probes/kprobes/actions-arm.c
  4. *
  5. * Copyright (C) 2006, 2007 Motorola Inc.
  6. */
  7. /*
  8. * We do not have hardware single-stepping on ARM, This
  9. * effort is further complicated by the ARM not having a
  10. * "next PC" register. Instructions that change the PC
  11. * can't be safely single-stepped in a MP environment, so
  12. * we have a lot of work to do:
  13. *
  14. * In the prepare phase:
  15. * *) If it is an instruction that does anything
  16. * with the CPU mode, we reject it for a kprobe.
  17. * (This is out of laziness rather than need. The
  18. * instructions could be simulated.)
  19. *
  20. * *) Otherwise, decode the instruction rewriting its
  21. * registers to take fixed, ordered registers and
  22. * setting a handler for it to run the instruction.
  23. *
  24. * In the execution phase by an instruction's handler:
  25. *
  26. * *) If the PC is written to by the instruction, the
  27. * instruction must be fully simulated in software.
  28. *
  29. * *) Otherwise, a modified form of the instruction is
  30. * directly executed. Its handler calls the
  31. * instruction in insn[0]. In insn[1] is a
  32. * "mov pc, lr" to return.
  33. *
  34. * Before calling, load up the reordered registers
  35. * from the original instruction's registers. If one
  36. * of the original input registers is the PC, compute
  37. * and adjust the appropriate input register.
  38. *
  39. * After call completes, copy the output registers to
  40. * the original instruction's original registers.
  41. *
  42. * We don't use a real breakpoint instruction since that
  43. * would have us in the kernel go from SVC mode to SVC
  44. * mode losing the link register. Instead we use an
  45. * undefined instruction. To simplify processing, the
  46. * undefined instruction used for kprobes must be reserved
  47. * exclusively for kprobes use.
  48. *
  49. * TODO: ifdef out some instruction decoding based on architecture.
  50. */
  51. #include <linux/kernel.h>
  52. #include <linux/kprobes.h>
  53. #include <linux/ptrace.h>
  54. #include "../decode-arm.h"
  55. #include "core.h"
  56. #include "checkers.h"
  57. #if __LINUX_ARM_ARCH__ >= 6
  58. #define BLX(reg) "blx "reg" \n\t"
  59. #else
  60. #define BLX(reg) "mov lr, pc \n\t" \
  61. "mov pc, "reg" \n\t"
  62. #endif
  63. static void __kprobes
  64. emulate_ldrdstrd(probes_opcode_t insn,
  65. struct arch_probes_insn *asi, struct pt_regs *regs)
  66. {
  67. unsigned long pc = regs->ARM_pc + 4;
  68. int rt = (insn >> 12) & 0xf;
  69. int rn = (insn >> 16) & 0xf;
  70. int rm = insn & 0xf;
  71. register unsigned long rtv asm("r0") = regs->uregs[rt];
  72. register unsigned long rt2v asm("r1") = regs->uregs[rt+1];
  73. register unsigned long rnv asm("r2") = (rn == 15) ? pc
  74. : regs->uregs[rn];
  75. register unsigned long rmv asm("r3") = regs->uregs[rm];
  76. __asm__ __volatile__ (
  77. BLX("%[fn]")
  78. : "=r" (rtv), "=r" (rt2v), "=r" (rnv)
  79. : "0" (rtv), "1" (rt2v), "2" (rnv), "r" (rmv),
  80. [fn] "r" (asi->insn_fn)
  81. : "lr", "memory", "cc"
  82. );
  83. regs->uregs[rt] = rtv;
  84. regs->uregs[rt+1] = rt2v;
  85. if (is_writeback(insn))
  86. regs->uregs[rn] = rnv;
  87. }
  88. static void __kprobes
  89. emulate_ldr(probes_opcode_t insn,
  90. struct arch_probes_insn *asi, struct pt_regs *regs)
  91. {
  92. unsigned long pc = regs->ARM_pc + 4;
  93. int rt = (insn >> 12) & 0xf;
  94. int rn = (insn >> 16) & 0xf;
  95. int rm = insn & 0xf;
  96. register unsigned long rtv asm("r0");
  97. register unsigned long rnv asm("r2") = (rn == 15) ? pc
  98. : regs->uregs[rn];
  99. register unsigned long rmv asm("r3") = regs->uregs[rm];
  100. __asm__ __volatile__ (
  101. BLX("%[fn]")
  102. : "=r" (rtv), "=r" (rnv)
  103. : "1" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
  104. : "lr", "memory", "cc"
  105. );
  106. if (rt == 15)
  107. load_write_pc(rtv, regs);
  108. else
  109. regs->uregs[rt] = rtv;
  110. if (is_writeback(insn))
  111. regs->uregs[rn] = rnv;
  112. }
  113. static void __kprobes
  114. emulate_str(probes_opcode_t insn,
  115. struct arch_probes_insn *asi, struct pt_regs *regs)
  116. {
  117. unsigned long rtpc = regs->ARM_pc - 4 + str_pc_offset;
  118. unsigned long rnpc = regs->ARM_pc + 4;
  119. int rt = (insn >> 12) & 0xf;
  120. int rn = (insn >> 16) & 0xf;
  121. int rm = insn & 0xf;
  122. register unsigned long rtv asm("r0") = (rt == 15) ? rtpc
  123. : regs->uregs[rt];
  124. register unsigned long rnv asm("r2") = (rn == 15) ? rnpc
  125. : regs->uregs[rn];
  126. register unsigned long rmv asm("r3") = regs->uregs[rm];
  127. __asm__ __volatile__ (
  128. BLX("%[fn]")
  129. : "=r" (rnv)
  130. : "r" (rtv), "0" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
  131. : "lr", "memory", "cc"
  132. );
  133. if (is_writeback(insn))
  134. regs->uregs[rn] = rnv;
  135. }
  136. static void __kprobes
  137. emulate_rd12rn16rm0rs8_rwflags(probes_opcode_t insn,
  138. struct arch_probes_insn *asi, struct pt_regs *regs)
  139. {
  140. unsigned long pc = regs->ARM_pc + 4;
  141. int rd = (insn >> 12) & 0xf;
  142. int rn = (insn >> 16) & 0xf;
  143. int rm = insn & 0xf;
  144. int rs = (insn >> 8) & 0xf;
  145. register unsigned long rdv asm("r0") = regs->uregs[rd];
  146. register unsigned long rnv asm("r2") = (rn == 15) ? pc
  147. : regs->uregs[rn];
  148. register unsigned long rmv asm("r3") = (rm == 15) ? pc
  149. : regs->uregs[rm];
  150. register unsigned long rsv asm("r1") = regs->uregs[rs];
  151. unsigned long cpsr = regs->ARM_cpsr;
  152. __asm__ __volatile__ (
  153. "msr cpsr_fs, %[cpsr] \n\t"
  154. BLX("%[fn]")
  155. "mrs %[cpsr], cpsr \n\t"
  156. : "=r" (rdv), [cpsr] "=r" (cpsr)
  157. : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
  158. "1" (cpsr), [fn] "r" (asi->insn_fn)
  159. : "lr", "memory", "cc"
  160. );
  161. if (rd == 15)
  162. alu_write_pc(rdv, regs);
  163. else
  164. regs->uregs[rd] = rdv;
  165. regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
  166. }
  167. static void __kprobes
  168. emulate_rd12rn16rm0_rwflags_nopc(probes_opcode_t insn,
  169. struct arch_probes_insn *asi, struct pt_regs *regs)
  170. {
  171. int rd = (insn >> 12) & 0xf;
  172. int rn = (insn >> 16) & 0xf;
  173. int rm = insn & 0xf;
  174. register unsigned long rdv asm("r0") = regs->uregs[rd];
  175. register unsigned long rnv asm("r2") = regs->uregs[rn];
  176. register unsigned long rmv asm("r3") = regs->uregs[rm];
  177. unsigned long cpsr = regs->ARM_cpsr;
  178. __asm__ __volatile__ (
  179. "msr cpsr_fs, %[cpsr] \n\t"
  180. BLX("%[fn]")
  181. "mrs %[cpsr], cpsr \n\t"
  182. : "=r" (rdv), [cpsr] "=r" (cpsr)
  183. : "0" (rdv), "r" (rnv), "r" (rmv),
  184. "1" (cpsr), [fn] "r" (asi->insn_fn)
  185. : "lr", "memory", "cc"
  186. );
  187. regs->uregs[rd] = rdv;
  188. regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
  189. }
  190. static void __kprobes
  191. emulate_rd16rn12rm0rs8_rwflags_nopc(probes_opcode_t insn,
  192. struct arch_probes_insn *asi,
  193. struct pt_regs *regs)
  194. {
  195. int rd = (insn >> 16) & 0xf;
  196. int rn = (insn >> 12) & 0xf;
  197. int rm = insn & 0xf;
  198. int rs = (insn >> 8) & 0xf;
  199. register unsigned long rdv asm("r2") = regs->uregs[rd];
  200. register unsigned long rnv asm("r0") = regs->uregs[rn];
  201. register unsigned long rmv asm("r3") = regs->uregs[rm];
  202. register unsigned long rsv asm("r1") = regs->uregs[rs];
  203. unsigned long cpsr = regs->ARM_cpsr;
  204. __asm__ __volatile__ (
  205. "msr cpsr_fs, %[cpsr] \n\t"
  206. BLX("%[fn]")
  207. "mrs %[cpsr], cpsr \n\t"
  208. : "=r" (rdv), [cpsr] "=r" (cpsr)
  209. : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
  210. "1" (cpsr), [fn] "r" (asi->insn_fn)
  211. : "lr", "memory", "cc"
  212. );
  213. regs->uregs[rd] = rdv;
  214. regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
  215. }
  216. static void __kprobes
  217. emulate_rd12rm0_noflags_nopc(probes_opcode_t insn,
  218. struct arch_probes_insn *asi, struct pt_regs *regs)
  219. {
  220. int rd = (insn >> 12) & 0xf;
  221. int rm = insn & 0xf;
  222. register unsigned long rdv asm("r0") = regs->uregs[rd];
  223. register unsigned long rmv asm("r3") = regs->uregs[rm];
  224. __asm__ __volatile__ (
  225. BLX("%[fn]")
  226. : "=r" (rdv)
  227. : "0" (rdv), "r" (rmv), [fn] "r" (asi->insn_fn)
  228. : "lr", "memory", "cc"
  229. );
  230. regs->uregs[rd] = rdv;
  231. }
  232. static void __kprobes
  233. emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(probes_opcode_t insn,
  234. struct arch_probes_insn *asi,
  235. struct pt_regs *regs)
  236. {
  237. int rdlo = (insn >> 12) & 0xf;
  238. int rdhi = (insn >> 16) & 0xf;
  239. int rn = insn & 0xf;
  240. int rm = (insn >> 8) & 0xf;
  241. register unsigned long rdlov asm("r0") = regs->uregs[rdlo];
  242. register unsigned long rdhiv asm("r2") = regs->uregs[rdhi];
  243. register unsigned long rnv asm("r3") = regs->uregs[rn];
  244. register unsigned long rmv asm("r1") = regs->uregs[rm];
  245. unsigned long cpsr = regs->ARM_cpsr;
  246. __asm__ __volatile__ (
  247. "msr cpsr_fs, %[cpsr] \n\t"
  248. BLX("%[fn]")
  249. "mrs %[cpsr], cpsr \n\t"
  250. : "=r" (rdlov), "=r" (rdhiv), [cpsr] "=r" (cpsr)
  251. : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv),
  252. "2" (cpsr), [fn] "r" (asi->insn_fn)
  253. : "lr", "memory", "cc"
  254. );
  255. regs->uregs[rdlo] = rdlov;
  256. regs->uregs[rdhi] = rdhiv;
  257. regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
  258. }
  259. const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = {
  260. [PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop},
  261. [PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop},
  262. [PROBES_BRANCH_IMM] = {.handler = simulate_blx1},
  263. [PROBES_MRS] = {.handler = simulate_mrs},
  264. [PROBES_BRANCH_REG] = {.handler = simulate_blx2bx},
  265. [PROBES_CLZ] = {.handler = emulate_rd12rm0_noflags_nopc},
  266. [PROBES_SATURATING_ARITHMETIC] = {
  267. .handler = emulate_rd12rn16rm0_rwflags_nopc},
  268. [PROBES_MUL1] = {.handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc},
  269. [PROBES_MUL2] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc},
  270. [PROBES_SWP] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
  271. [PROBES_LDRSTRD] = {.handler = emulate_ldrdstrd},
  272. [PROBES_LOAD_EXTRA] = {.handler = emulate_ldr},
  273. [PROBES_LOAD] = {.handler = emulate_ldr},
  274. [PROBES_STORE_EXTRA] = {.handler = emulate_str},
  275. [PROBES_STORE] = {.handler = emulate_str},
  276. [PROBES_MOV_IP_SP] = {.handler = simulate_mov_ipsp},
  277. [PROBES_DATA_PROCESSING_REG] = {
  278. .handler = emulate_rd12rn16rm0rs8_rwflags},
  279. [PROBES_DATA_PROCESSING_IMM] = {
  280. .handler = emulate_rd12rn16rm0rs8_rwflags},
  281. [PROBES_MOV_HALFWORD] = {.handler = emulate_rd12rm0_noflags_nopc},
  282. [PROBES_SEV] = {.handler = probes_emulate_none},
  283. [PROBES_WFE] = {.handler = probes_simulate_nop},
  284. [PROBES_SATURATE] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
  285. [PROBES_REV] = {.handler = emulate_rd12rm0_noflags_nopc},
  286. [PROBES_MMI] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
  287. [PROBES_PACK] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
  288. [PROBES_EXTEND] = {.handler = emulate_rd12rm0_noflags_nopc},
  289. [PROBES_EXTEND_ADD] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
  290. [PROBES_MUL_ADD_LONG] = {
  291. .handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc},
  292. [PROBES_MUL_ADD] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc},
  293. [PROBES_BITFIELD] = {.handler = emulate_rd12rm0_noflags_nopc},
  294. [PROBES_BRANCH] = {.handler = simulate_bbl},
  295. [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm}
  296. };
  297. const struct decode_checker *kprobes_arm_checkers[] = {arm_stack_checker, arm_regs_checker, NULL};