armv8 不支持的指令造成的异常会在kernel中通过其他指令替换

来源:互联网 发布:洛天依软件如何解压 编辑:程序博客网 时间:2024/06/05 15:21
armv8 hw对某些指令不支持,这样在用户态调用的时候就会陷入异常,这样kernel会为通过软件的方式来执行这些指令,这样用户态由于某些指令异常陷入kernel中,kernel通过软件的方式执行后,会成功返回用户态.具体可以看下面的函数static void __init register_insn_emulation(struct insn_emulation_ops *ops){unsigned long flags;struct insn_emulation *insn;insn = kzalloc(sizeof(*insn), GFP_KERNEL);insn->ops = ops;insn->min = INSN_UNDEF;switch (ops->status) {case INSN_DEPRECATED://如果是armv8 不支持的执行,会为这个指令注册一个回调函数insn->current_mode = INSN_EMULATE;/* Disable the HW mode if it was turned on at early boot time */run_all_cpu_set_hw_mode(insn, false);insn->max = INSN_HW;break;}那些指令armv8 不支持呢?static struct undef_hook cp15_barrier_hooks[] = {{.instr_mask= 0x0fff0fdf,.instr_val= 0x0e070f9a,.pstate_mask= COMPAT_PSR_MODE_MASK,.pstate_val= COMPAT_PSR_MODE_USR,.fn= cp15barrier_handler,},{.instr_mask= 0x0fff0fff,.instr_val= 0x0e070f95,.pstate_mask= COMPAT_PSR_MODE_MASK,.pstate_val= COMPAT_PSR_MODE_USR,.fn= cp15barrier_handler,},{ }};static struct insn_emulation_ops cp15_barrier_ops = {.name = "cp15_barrier",.status = INSN_DEPRECATED,.hooks = cp15_barrier_hooks,.set_hw_mode = cp15_barrier_set_hw_mode,};可见.instr_val= 0x0e070f9a和.instr_val= 0x0e070f95, 这两条指令armv8不支持,如果用户态是由于这两个指令异常的话,kernel会调用cp15barrier_handler 执行这两个指令,最终用户态可以正确执行static int cp15barrier_handler(struct pt_regs *regs, u32 instr){switch (aarch32_insn_mcr_extract_crm(instr)) {case 10:所以0x0e070f9a 这条指令就有下面的两条执行替换,执行后的效果是完全相同的/* * dmb - mcr p15, 0, Rt, c7, c10, 5 * dsb - mcr p15, 0, Rt, c7, c10, 4 */if (aarch32_insn_mcr_extract_opc2(instr) == 5) {dmb(sy);trace_instruction_emulation("mcr p15, 0, Rt, c7, c10, 5 ; dmb", regs->pc);} else {dsb(sy);trace_instruction_emulation("mcr p15, 0, Rt, c7, c10, 4 ; dsb", regs->pc);}break;case 5:/* * isb - mcr p15, 0, Rt, c7, c5, 4 * * Taking an exception or returning from one acts as an * instruction barrier. So no explicit barrier needed here. */trace_instruction_emulation("mcr p15, 0, Rt, c7, c5, 4 ; isb", regs->pc);break;}ret:pr_warn_ratelimited("\"%s\" (%ld) uses deprecated CP15 Barrier instruction at 0x%llx\n",current->comm, (unsigned long)current->pid, regs->pc);regs->pc += 4;return 0;}

阅读全文
0 0
原创粉丝点击