static bool __kprobes aarch64_insn_is_steppable(u32 insn) { if (aarch64_get_insn_class(insn) == AARCH64_INSN_CLS_BR_SYS) { if (aarch64_insn_is_branch(insn)) return false; /* modification of daif creates issues */ if (aarch64_insn_is_daif_access(insn)) return false; if (aarch64_insn_is_exception(insn)) return false; if (aarch64_insn_is_hint(insn)) return aarch64_insn_is_nop(insn); return true; } if (aarch64_insn_uses_literal(insn)) return false; if (aarch64_insn_is_exclusive(insn)) return false; return true; }
static bool __kprobes __aarch64_insn_hotpatch_safe(u32 insn) { if (aarch64_get_insn_class(insn) != AARCH64_INSN_CLS_BR_SYS) return false; return aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn) || aarch64_insn_is_svc(insn) || aarch64_insn_is_hvc(insn) || aarch64_insn_is_smc(insn) || aarch64_insn_is_brk(insn) || aarch64_insn_is_nop(insn); }
static bool __kprobes aarch64_insn_is_steppable(u32 insn) { /* * Branch instructions will write a new value into the PC which is * likely to be relative to the XOL address and therefore invalid. * Deliberate generation of an exception during stepping is also not * currently safe. Lastly, MSR instructions can do any number of nasty * things we can't handle during single-stepping. */ if (aarch64_get_insn_class(insn) == AARCH64_INSN_CLS_BR_SYS) { if (aarch64_insn_is_branch(insn) || aarch64_insn_is_msr_imm(insn) || aarch64_insn_is_msr_reg(insn) || aarch64_insn_is_exception(insn) || aarch64_insn_is_eret(insn)) return false; /* * The MRS instruction may not return a correct value when * executing in the single-stepping environment. We do make one * exception, for reading the DAIF bits. */ if (aarch64_insn_is_mrs(insn)) return aarch64_insn_extract_system_reg(insn) != AARCH64_INSN_SPCLREG_DAIF; /* * The HINT instruction is is problematic when single-stepping, * except for the NOP case. */ if (aarch64_insn_is_hint(insn)) return aarch64_insn_is_nop(insn); return true; } /* * Instructions which load PC relative literals are not going to work * when executed from an XOL slot. Instructions doing an exclusive * load/store are not going to complete successfully when single-step * exception handling happens in the middle of the sequence. */ if (aarch64_insn_uses_literal(insn) || aarch64_insn_is_exclusive(insn)) return false; return true; }