Lines Matching +full:- +full:- +full:retry +full:- +full:all +full:- +full:errors
1 // SPDX-License-Identifier: GPL-2.0
15 * struct emuframe - The 'emulation' frame structure
32 * - Actually emulating all instructions isn't feasible. We would need to
33 * be able to handle instructions from all revisions of the MIPS ISA,
34 * all ASEs & all vendor instruction set extensions. This would be a
40 * - We must execute the instruction within user context. If we were to
45 * - We used to place the frame on the users stack, but this requires
47 * per-process page is now used instead.
49 * - The instruction in @emul may be something entirely invalid for a
57 * - The user may generate a fake struct emuframe if they wish, invoking
77 mm_context_t *mm_ctx = ¤t->mm->context; in alloc_emuframe()
80 retry: in alloc_emuframe()
81 spin_lock(&mm_ctx->bd_emupage_lock); in alloc_emuframe()
84 if (!mm_ctx->bd_emupage_allocmap) { in alloc_emuframe()
85 mm_ctx->bd_emupage_allocmap = bitmap_zalloc(emupage_frame_count, in alloc_emuframe()
87 if (!mm_ctx->bd_emupage_allocmap) { in alloc_emuframe()
94 idx = bitmap_find_free_region(mm_ctx->bd_emupage_allocmap, in alloc_emuframe()
102 * However the worst case is that we repeat all this and end up in alloc_emuframe()
105 spin_unlock(&mm_ctx->bd_emupage_lock); in alloc_emuframe()
106 if (!wait_event_killable(mm_ctx->bd_emupage_queue, in alloc_emuframe()
107 !bitmap_full(mm_ctx->bd_emupage_allocmap, in alloc_emuframe()
109 goto retry; in alloc_emuframe()
111 /* Received a fatal signal - just give in */ in alloc_emuframe()
116 pr_debug("allocate emuframe %d to %d\n", idx, current->pid); in alloc_emuframe()
118 spin_unlock(&mm_ctx->bd_emupage_lock); in alloc_emuframe()
124 mm_context_t *mm_ctx = &mm->context; in free_emuframe()
126 spin_lock(&mm_ctx->bd_emupage_lock); in free_emuframe()
128 pr_debug("free emuframe %d from %d\n", idx, current->pid); in free_emuframe()
129 bitmap_clear(mm_ctx->bd_emupage_allocmap, idx, 1); in free_emuframe()
132 wake_up(&mm_ctx->bd_emupage_queue); in free_emuframe()
134 spin_unlock(&mm_ctx->bd_emupage_lock); in free_emuframe()
141 if (regs->cp0_epc < base) in within_emuframe()
143 if (regs->cp0_epc >= (base + PAGE_SIZE)) in within_emuframe()
154 fr_idx = atomic_xchg(&tsk->thread.bd_emu_frame, BD_EMUFRAME_NONE); in dsemul_thread_cleanup()
163 if (tsk->mm) in dsemul_thread_cleanup()
164 free_emuframe(fr_idx, tsk->mm); in dsemul_thread_cleanup()
180 fr_idx = atomic_read(¤t->thread.bd_emu_frame); in dsemul_thread_rollback()
190 * of the emupage - we'll free the allocated frame anyway. in dsemul_thread_rollback()
192 if (msk_isa16_mode(regs->cp0_epc) == (unsigned long)&fr->emul) in dsemul_thread_rollback()
193 regs->cp0_epc = current->thread.bd_emu_branch_pc; in dsemul_thread_rollback()
194 else if (msk_isa16_mode(regs->cp0_epc) == (unsigned long)&fr->badinst) in dsemul_thread_rollback()
195 regs->cp0_epc = current->thread.bd_emu_cont_pc; in dsemul_thread_rollback()
197 atomic_set(¤t->thread.bd_emu_frame, BD_EMUFRAME_NONE); in dsemul_thread_rollback()
198 free_emuframe(fr_idx, current->mm); in dsemul_thread_rollback()
204 mm_context_t *mm_ctx = &mm->context; in dsemul_mm_cleanup()
206 bitmap_free(mm_ctx->bd_emupage_allocmap); in dsemul_mm_cleanup()
212 int isa16 = get_isa16_mode(regs->cp0_epc); in mips_dsemul()
220 return -1; in mips_dsemul()
228 return -1; in mips_dsemul()
236 v = regs->cp0_epc & ~3; in mips_dsemul()
238 regs->regs[rs] = (long)v; in mips_dsemul()
239 return -1; in mips_dsemul()
243 pr_debug("dsemul 0x%08lx cont at 0x%08lx\n", regs->cp0_epc, cont_pc); in mips_dsemul()
246 fr_idx = atomic_read(¤t->thread.bd_emu_frame); in mips_dsemul()
276 MIPS_FPU_EMU_INC_STATS(errors); in mips_dsemul()
277 free_emuframe(fr_idx, current->mm); in mips_dsemul()
282 current->thread.bd_emu_branch_pc = branch_pc; in mips_dsemul()
283 current->thread.bd_emu_cont_pc = cont_pc; in mips_dsemul()
284 atomic_set(¤t->thread.bd_emu_frame, fr_idx); in mips_dsemul()
287 regs->cp0_epc = fr_uaddr | isa16; in mips_dsemul()
296 MIPS_FPU_EMU_INC_STATS(errors); in do_dsemulret()
300 /* Set EPC to return to post-branch instruction */ in do_dsemulret()
301 xcp->cp0_epc = current->thread.bd_emu_cont_pc; in do_dsemulret()
302 pr_debug("dsemulret to 0x%08lx\n", xcp->cp0_epc); in do_dsemulret()