Index: sys/arch/aarch64/aarch64/trap.c =================================================================== RCS file: /home/netbsd/src/sys/arch/aarch64/aarch64/trap.c,v retrieving revision 1.25 diff -p -u -r1.25 trap.c --- sys/arch/aarch64/aarch64/trap.c 31 Jan 2020 09:23:58 -0000 1.25 +++ sys/arch/aarch64/aarch64/trap.c 5 Feb 2020 02:52:57 -0000 @@ -362,30 +362,36 @@ fetch_arm_insn(struct trapframe *tf, uin uint16_t *pc = (uint16_t *)(tf->tf_pc & ~1UL); /* XXX */ uint16_t hi, lo; - hi = *pc; + if (ufetch_16(pc, &hi)) + return -1; + if (!THUMB_32BIT(hi)) { /* 16-bit Thumb instruction */ *insn = hi; return 2; } - /* - * 32-bit Thumb instruction: - * We can safely retrieve the lower-half word without - * consideration of a page fault; If present, it must - * have occurred already in the decode stage. - */ - lo = *(pc + 1); + /* 32-bit Thumb instruction */ + if (ufetch_16(pc + 1, &lo)) + return -1; *insn = ((uint32_t)hi << 16) | lo; return 4; } - *insn = *(uint32_t *)tf->tf_pc; + if (ufetch_32((uint32_t *)tf->tf_pc, insn)) + return -1; + return 4; } -static int +enum emul_arm_result { + EMUL_ARM_SUCCESS = 0, + EMUL_ARM_UNKNOWN, + EMUL_ARM_FAULT, +}; + +static enum emul_arm_result emul_arm_insn(struct trapframe *tf) { uint32_t insn; @@ -432,14 +438,16 @@ emul_arm_insn(struct trapframe *tf) break; } break; + default: + return EMUL_ARM_FAULT; } /* unknown, or unsupported instruction */ - return 1; + return EMUL_ARM_UNKNOWN; emulated: tf->tf_pc += insn_size; - return 0; + return EMUL_ARM_SUCCESS; } #endif /* COMPAT_NETBSD32 */ @@ -494,8 +502,16 @@ trap_el0_32sync(struct trapframe *tf) break; case ESR_EC_UNKNOWN: - if (emul_arm_insn(tf)) + switch (emul_arm_insn(tf)) { + case EMUL_ARM_SUCCESS: + break; + case EMUL_ARM_UNKNOWN: goto unknown; + case EMUL_ARM_FAULT: + do_trapsignal(l, SIGSEGV, SEGV_MAPERR, + (void *)tf->tf_pc, esr); + break; + } userret(l); break;