Lines Matching +full:max +full:- +full:rt

1 // SPDX-License-Identifier: GPL-2.0-only
22 #include "trace-events-emulation.h"
26 * following three states -
53 int max; member
80 * Implement emulation of the SWP/SWPB instructions using load-exclusive and
81 * store-exclusive.
83 * Syntax of SWP{B} instruction: SWP{B}<c> <Rt>, <Rt2>, [<Rn>]
84 * Where: Rt = destination
90 * Error-checking SWP macros implemented using ldxr{b}/stxr{b}
93 /* Arbitrary constant to ensure forward-progress of the LL/SC loop */
114 : "r" ((unsigned long)addr), "i" (-EAGAIN), \
139 return -EFAULT; in emulate_swpX()
150 if (likely(res != -EAGAIN) || signal_pending(current)) in emulate_swpX()
170 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, regs->pc); in swp_handler()
174 switch (aarch32_check_condition(instr, regs->pstate)) { in swp_handler()
178 /* Condition failed - return to next instruction */ in swp_handler()
181 /* If unconditional encoding - not a SWP, undef */ in swp_handler()
182 return -EFAULT; in swp_handler()
184 return -EINVAL; in swp_handler()
190 address = (u32)regs->user_regs.regs[rn]; in swp_handler()
191 data = (u32)regs->user_regs.regs[rt2]; in swp_handler()
194 pr_debug("addr in r%d->0x%08x, dest is r%d, source in r%d->0x%08x)\n", in swp_handler()
207 if (res == -EFAULT) in swp_handler()
210 regs->user_regs.regs[destreg] = data; in swp_handler()
214 trace_instruction_emulation("swpb", regs->pc); in swp_handler()
216 trace_instruction_emulation("swp", regs->pc); in swp_handler()
219 current->comm, (unsigned long)current->pid, regs->pc); in swp_handler()
254 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, regs->pc); in cp15barrier_handler()
256 switch (aarch32_check_condition(instr, regs->pstate)) { in cp15barrier_handler()
260 /* Condition failed - return to next instruction */ in cp15barrier_handler()
263 /* If unconditional encoding - not a barrier instruction */ in cp15barrier_handler()
264 return -EFAULT; in cp15barrier_handler()
266 return -EINVAL; in cp15barrier_handler()
272 * dmb - mcr p15, 0, Rt, c7, c10, 5 in cp15barrier_handler()
273 * dsb - mcr p15, 0, Rt, c7, c10, 4 in cp15barrier_handler()
278 "mcr p15, 0, Rt, c7, c10, 5 ; dmb", regs->pc); in cp15barrier_handler()
282 "mcr p15, 0, Rt, c7, c10, 4 ; dsb", regs->pc); in cp15barrier_handler()
287 * isb - mcr p15, 0, Rt, c7, c5, 4 in cp15barrier_handler()
293 "mcr p15, 0, Rt, c7, c5, 4 ; isb", regs->pc); in cp15barrier_handler()
299 current->comm, (unsigned long)current->pid, regs->pc); in cp15barrier_handler()
340 return -EINVAL; in setend_set_hw_mode()
353 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, regs->pc); in compat_setend_handler()
357 regs->pstate |= PSR_AA32_E_BIT; in compat_setend_handler()
360 regs->pstate &= ~PSR_AA32_E_BIT; in compat_setend_handler()
363 trace_instruction_emulation(insn, regs->pc); in compat_setend_handler()
365 current->comm, (unsigned long)current->pid, regs->pc); in compat_setend_handler()
422 if (insn->set_hw_mode) in enable_insn_hw_mode()
423 insn->set_hw_mode(true); in enable_insn_hw_mode()
429 if (insn->set_hw_mode) in disable_insn_hw_mode()
430 insn->set_hw_mode(false); in disable_insn_hw_mode()
436 if (!insn->set_hw_mode) in run_all_cpu_set_hw_mode()
437 return -EINVAL; in run_all_cpu_set_hw_mode()
448 * 0 - If all the hooks ran successfully.
449 * -EINVAL - At least one hook is not supported by the CPU.
464 bool enable = READ_ONCE(insn->current_mode) == INSN_HW; in run_all_insn_set_hw_mode()
465 if (insn->status == INSN_UNAVAILABLE) in run_all_insn_set_hw_mode()
468 if (insn->set_hw_mode && insn->set_hw_mode(enable)) { in run_all_insn_set_hw_mode()
470 cpu, insn->name); in run_all_insn_set_hw_mode()
471 rc = -EINVAL; in run_all_insn_set_hw_mode()
491 pr_notice("Disabled %s support\n", insn->name); in update_insn_emulation_mode()
495 switch (insn->current_mode) { in update_insn_emulation_mode()
503 pr_notice("Enabled %s support\n", insn->name); in update_insn_emulation_mode()
515 struct insn_emulation *insn = container_of(table->data, struct insn_emulation, current_mode); in emulation_proc_handler()
516 enum insn_emulation_mode prev_mode = insn->current_mode; in emulation_proc_handler()
521 if (ret || !write || prev_mode == insn->current_mode) in emulation_proc_handler()
527 WRITE_ONCE(insn->current_mode, prev_mode); in emulation_proc_handler()
539 insn->min = INSN_UNDEF; in register_insn_emulation()
541 switch (insn->status) { in register_insn_emulation()
543 insn->current_mode = INSN_EMULATE; in register_insn_emulation()
546 insn->max = INSN_HW; in register_insn_emulation()
549 insn->current_mode = INSN_UNDEF; in register_insn_emulation()
550 insn->max = INSN_EMULATE; in register_insn_emulation()
553 insn->current_mode = INSN_UNDEF; in register_insn_emulation()
554 insn->max = INSN_UNDEF; in register_insn_emulation()
561 if (insn->status != INSN_UNAVAILABLE) { in register_insn_emulation()
562 sysctl = &insn->sysctl; in register_insn_emulation()
564 sysctl->mode = 0644; in register_insn_emulation()
565 sysctl->maxlen = sizeof(int); in register_insn_emulation()
567 sysctl->procname = insn->name; in register_insn_emulation()
568 sysctl->data = &insn->current_mode; in register_insn_emulation()
569 sysctl->extra1 = &insn->min; in register_insn_emulation()
570 sysctl->extra2 = &insn->max; in register_insn_emulation()
571 sysctl->proc_handler = emulation_proc_handler; in register_insn_emulation()
582 if (ie->status == INSN_UNAVAILABLE) in try_emulate_armv8_deprecated()
587 * INSN_EMULATE<->INSN_HW. Try to emulate the instruction to in try_emulate_armv8_deprecated()
590 if (READ_ONCE(ie->current_mode) == INSN_UNDEF) in try_emulate_armv8_deprecated()
593 if (ie->try_emulate(regs, insn)) in try_emulate_armv8_deprecated()
616 if (ie->status == INSN_UNAVAILABLE) in armv8_deprecated_init()