dsemul.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. #include <linux/err.h>
  2. #include <linux/slab.h>
  3. #include <linux/mm_types.h>
  4. #include <linux/sched/task.h>
  5. #include <asm/branch.h>
  6. #include <asm/cacheflush.h>
  7. #include <asm/fpu_emulator.h>
  8. #include <asm/inst.h>
  9. #include <asm/mipsregs.h>
  10. #include <linux/uaccess.h>
  11. /**
  12. * struct emuframe - The 'emulation' frame structure
  13. * @emul: The instruction to 'emulate'.
  14. * @badinst: A break instruction to cause a return to the kernel.
  15. *
  16. * This structure defines the frames placed within the delay slot emulation
  17. * page in response to a call to mips_dsemul(). Each thread may be allocated
  18. * only one frame at any given time. The kernel stores within it the
  19. * instruction to be 'emulated' followed by a break instruction, then
  20. * executes the frame in user mode. The break causes a trap to the kernel
  21. * which leads to do_dsemulret() being called unless the instruction in
  22. * @emul causes a trap itself, is a branch, or a signal is delivered to
  23. * the thread. In these cases the allocated frame will either be reused by
  24. * a subsequent delay slot 'emulation', or be freed during signal delivery or
  25. * upon thread exit.
  26. *
  27. * This approach is used because:
  28. *
  29. * - Actually emulating all instructions isn't feasible. We would need to
  30. * be able to handle instructions from all revisions of the MIPS ISA,
  31. * all ASEs & all vendor instruction set extensions. This would be a
  32. * whole lot of work & continual maintenance burden as new instructions
  33. * are introduced, and in the case of some vendor extensions may not
  34. * even be possible. Thus we need to take the approach of actually
  35. * executing the instruction.
  36. *
  37. * - We must execute the instruction within user context. If we were to
  38. * execute the instruction in kernel mode then it would have access to
  39. * kernel resources without very careful checks, leaving us with a
  40. * high potential for security or stability issues to arise.
  41. *
  42. * - We used to place the frame on the users stack, but this requires
  43. * that the stack be executable. This is bad for security so the
  44. * per-process page is now used instead.
  45. *
  46. * - The instruction in @emul may be something entirely invalid for a
  47. * delay slot. The user may (intentionally or otherwise) place a branch
  48. * in a delay slot, or a kernel mode instruction, or something else
  49. * which generates an exception. Thus we can't rely upon the break in
  50. * @badinst always being hit. For this reason we track the index of the
  51. * frame allocated to each thread, allowing us to clean it up at later
  52. * points such as signal delivery or thread exit.
  53. *
  54. * - The user may generate a fake struct emuframe if they wish, invoking
  55. * the BRK_MEMU break instruction themselves. We must therefore not
  56. * trust that BRK_MEMU means there's actually a valid frame allocated
  57. * to the thread, and must not allow the user to do anything they
  58. * couldn't already.
  59. */
  60. struct emuframe {
  61. mips_instruction emul;
  62. mips_instruction badinst;
  63. };
  64. static const int emupage_frame_count = PAGE_SIZE / sizeof(struct emuframe);
  65. static inline __user struct emuframe *dsemul_page(void)
  66. {
  67. return (__user struct emuframe *)STACK_TOP;
  68. }
  69. static int alloc_emuframe(void)
  70. {
  71. mm_context_t *mm_ctx = &current->mm->context;
  72. int idx;
  73. retry:
  74. spin_lock(&mm_ctx->bd_emupage_lock);
  75. /* Ensure we have an allocation bitmap */
  76. if (!mm_ctx->bd_emupage_allocmap) {
  77. mm_ctx->bd_emupage_allocmap =
  78. kcalloc(BITS_TO_LONGS(emupage_frame_count),
  79. sizeof(unsigned long),
  80. GFP_ATOMIC);
  81. if (!mm_ctx->bd_emupage_allocmap) {
  82. idx = BD_EMUFRAME_NONE;
  83. goto out_unlock;
  84. }
  85. }
  86. /* Attempt to allocate a single bit/frame */
  87. idx = bitmap_find_free_region(mm_ctx->bd_emupage_allocmap,
  88. emupage_frame_count, 0);
  89. if (idx < 0) {
  90. /*
  91. * Failed to allocate a frame. We'll wait until one becomes
  92. * available. We unlock the page so that other threads actually
  93. * get the opportunity to free their frames, which means
  94. * technically the result of bitmap_full may be incorrect.
  95. * However the worst case is that we repeat all this and end up
  96. * back here again.
  97. */
  98. spin_unlock(&mm_ctx->bd_emupage_lock);
  99. if (!wait_event_killable(mm_ctx->bd_emupage_queue,
  100. !bitmap_full(mm_ctx->bd_emupage_allocmap,
  101. emupage_frame_count)))
  102. goto retry;
  103. /* Received a fatal signal - just give in */
  104. return BD_EMUFRAME_NONE;
  105. }
  106. /* Success! */
  107. pr_debug("allocate emuframe %d to %d\n", idx, current->pid);
  108. out_unlock:
  109. spin_unlock(&mm_ctx->bd_emupage_lock);
  110. return idx;
  111. }
  112. static void free_emuframe(int idx, struct mm_struct *mm)
  113. {
  114. mm_context_t *mm_ctx = &mm->context;
  115. spin_lock(&mm_ctx->bd_emupage_lock);
  116. pr_debug("free emuframe %d from %d\n", idx, current->pid);
  117. bitmap_clear(mm_ctx->bd_emupage_allocmap, idx, 1);
  118. /* If some thread is waiting for a frame, now's its chance */
  119. wake_up(&mm_ctx->bd_emupage_queue);
  120. spin_unlock(&mm_ctx->bd_emupage_lock);
  121. }
  122. static bool within_emuframe(struct pt_regs *regs)
  123. {
  124. unsigned long base = (unsigned long)dsemul_page();
  125. if (regs->cp0_epc < base)
  126. return false;
  127. if (regs->cp0_epc >= (base + PAGE_SIZE))
  128. return false;
  129. return true;
  130. }
  131. bool dsemul_thread_cleanup(struct task_struct *tsk)
  132. {
  133. int fr_idx;
  134. /* Clear any allocated frame, retrieving its index */
  135. fr_idx = atomic_xchg(&tsk->thread.bd_emu_frame, BD_EMUFRAME_NONE);
  136. /* If no frame was allocated, we're done */
  137. if (fr_idx == BD_EMUFRAME_NONE)
  138. return false;
  139. task_lock(tsk);
  140. /* Free the frame that this thread had allocated */
  141. if (tsk->mm)
  142. free_emuframe(fr_idx, tsk->mm);
  143. task_unlock(tsk);
  144. return true;
  145. }
  146. bool dsemul_thread_rollback(struct pt_regs *regs)
  147. {
  148. struct emuframe __user *fr;
  149. int fr_idx;
  150. /* Do nothing if we're not executing from a frame */
  151. if (!within_emuframe(regs))
  152. return false;
  153. /* Find the frame being executed */
  154. fr_idx = atomic_read(&current->thread.bd_emu_frame);
  155. if (fr_idx == BD_EMUFRAME_NONE)
  156. return false;
  157. fr = &dsemul_page()[fr_idx];
  158. /*
  159. * If the PC is at the emul instruction, roll back to the branch. If
  160. * PC is at the badinst (break) instruction, we've already emulated the
  161. * instruction so progress to the continue PC. If it's anything else
  162. * then something is amiss & the user has branched into some other area
  163. * of the emupage - we'll free the allocated frame anyway.
  164. */
  165. if (msk_isa16_mode(regs->cp0_epc) == (unsigned long)&fr->emul)
  166. regs->cp0_epc = current->thread.bd_emu_branch_pc;
  167. else if (msk_isa16_mode(regs->cp0_epc) == (unsigned long)&fr->badinst)
  168. regs->cp0_epc = current->thread.bd_emu_cont_pc;
  169. atomic_set(&current->thread.bd_emu_frame, BD_EMUFRAME_NONE);
  170. free_emuframe(fr_idx, current->mm);
  171. return true;
  172. }
  173. void dsemul_mm_cleanup(struct mm_struct *mm)
  174. {
  175. mm_context_t *mm_ctx = &mm->context;
  176. kfree(mm_ctx->bd_emupage_allocmap);
  177. }
  178. int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
  179. unsigned long branch_pc, unsigned long cont_pc)
  180. {
  181. int isa16 = get_isa16_mode(regs->cp0_epc);
  182. mips_instruction break_math;
  183. struct emuframe __user *fr;
  184. int err, fr_idx;
  185. /* NOP is easy */
  186. if (ir == 0)
  187. return -1;
  188. /* microMIPS instructions */
  189. if (isa16) {
  190. union mips_instruction insn = { .word = ir };
  191. /* NOP16 aka MOVE16 $0, $0 */
  192. if ((ir >> 16) == MM_NOP16)
  193. return -1;
  194. /* ADDIUPC */
  195. if (insn.mm_a_format.opcode == mm_addiupc_op) {
  196. unsigned int rs;
  197. s32 v;
  198. rs = (((insn.mm_a_format.rs + 0xe) & 0xf) + 2);
  199. v = regs->cp0_epc & ~3;
  200. v += insn.mm_a_format.simmediate << 2;
  201. regs->regs[rs] = (long)v;
  202. return -1;
  203. }
  204. }
  205. pr_debug("dsemul 0x%08lx cont at 0x%08lx\n", regs->cp0_epc, cont_pc);
  206. /* Allocate a frame if we don't already have one */
  207. fr_idx = atomic_read(&current->thread.bd_emu_frame);
  208. if (fr_idx == BD_EMUFRAME_NONE)
  209. fr_idx = alloc_emuframe();
  210. if (fr_idx == BD_EMUFRAME_NONE)
  211. return SIGBUS;
  212. fr = &dsemul_page()[fr_idx];
  213. /* Retrieve the appropriately encoded break instruction */
  214. break_math = BREAK_MATH(isa16);
  215. /* Write the instructions to the frame */
  216. if (isa16) {
  217. err = __put_user(ir >> 16,
  218. (u16 __user *)(&fr->emul));
  219. err |= __put_user(ir & 0xffff,
  220. (u16 __user *)((long)(&fr->emul) + 2));
  221. err |= __put_user(break_math >> 16,
  222. (u16 __user *)(&fr->badinst));
  223. err |= __put_user(break_math & 0xffff,
  224. (u16 __user *)((long)(&fr->badinst) + 2));
  225. } else {
  226. err = __put_user(ir, &fr->emul);
  227. err |= __put_user(break_math, &fr->badinst);
  228. }
  229. if (unlikely(err)) {
  230. MIPS_FPU_EMU_INC_STATS(errors);
  231. free_emuframe(fr_idx, current->mm);
  232. return SIGBUS;
  233. }
  234. /* Record the PC of the branch, PC to continue from & frame index */
  235. current->thread.bd_emu_branch_pc = branch_pc;
  236. current->thread.bd_emu_cont_pc = cont_pc;
  237. atomic_set(&current->thread.bd_emu_frame, fr_idx);
  238. /* Change user register context to execute the frame */
  239. regs->cp0_epc = (unsigned long)&fr->emul | isa16;
  240. /* Ensure the icache observes our newly written frame */
  241. flush_cache_sigtramp((unsigned long)&fr->emul);
  242. return 0;
  243. }
  244. bool do_dsemulret(struct pt_regs *xcp)
  245. {
  246. /* Cleanup the allocated frame, returning if there wasn't one */
  247. if (!dsemul_thread_cleanup(current)) {
  248. MIPS_FPU_EMU_INC_STATS(errors);
  249. return false;
  250. }
  251. /* Set EPC to return to post-branch instruction */
  252. xcp->cp0_epc = current->thread.bd_emu_cont_pc;
  253. pr_debug("dsemulret to 0x%08lx\n", xcp->cp0_epc);
  254. MIPS_FPU_EMU_INC_STATS(ds_emul);
  255. return true;
  256. }