hexagon-softmmu had no enforcement of alignment for scalar loads and stores: the MO_ALIGN flag added by the previous two commits triggers TLB_INVALID_MASK/alignment faults in cputlb.c, but Hexagon's TCGCPUOps did not implement do_unaligned_access, so the fault was never delivered to the guest.
Add hexagon_cpu_do_unaligned_access(), which raises HEX_CAUSE_MISALIGNED_LOAD/_STORE via the existing HEX_EVENT_PRECISE path, mirroring raise_tlbmiss_exception()/raise_perm_exception(). Also add a linux-user cpu_loop handler for these two cause codes for consistency with hexswi.c's sysemu handling, even though linux-user's own alignment check in accel/tcg/user-exec.c currently raises SIGBUS before Hexagon's cause-code machinery is reached. Signed-off-by: Brian Cain <[email protected]> --- linux-user/hexagon/cpu_loop.c | 5 +++++ target/hexagon/cpu.c | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c index 0958c51fbb3..d7f73439dbc 100644 --- a/linux-user/hexagon/cpu_loop.c +++ b/linux-user/hexagon/cpu_loop.c @@ -76,6 +76,11 @@ void cpu_loop(CPUHexagonState *env) force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->gpr[HEX_REG_PC]); break; + case HEX_CAUSE_MISALIGNED_LOAD: + case HEX_CAUSE_MISALIGNED_STORE: + force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, + env->gpr[HEX_REG_PC]); + break; default: EXCP_DUMP(env, "\nqemu: unhandled CPU precise exception " "cause code 0x%x - aborting\n", diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index 42d93e5da47..e2af736a99d 100644 --- a/target/hexagon/cpu.c +++ b/target/hexagon/cpu.c @@ -637,6 +637,18 @@ static void raise_perm_exception(CPUState *cs, uint32_t VA, int slot, cs->exception_index = excp; } +static void raise_misaligned_exception(CPUState *cs, uint32_t VA, int slot, + MMUAccessType access_type) +{ + CPUHexagonState *env = cpu_env(cs); + int32_t excp = (access_type == MMU_DATA_STORE) ? + HEX_CAUSE_MISALIGNED_STORE : HEX_CAUSE_MISALIGNED_LOAD; + + set_badva_regs(env, VA, slot, access_type); + cs->exception_index = HEX_EVENT_PRECISE; + env->cause_code = excp; +} + static const char *access_type_names[] = { "MMU_DATA_LOAD ", "MMU_DATA_STORE", "MMU_INST_FETCH" }; @@ -715,6 +727,18 @@ static vaddr hexagon_pointer_wrap(CPUState *cs, int mmu_idx, return result; } +static G_NORETURN +void hexagon_cpu_do_unaligned_access(CPUState *cs, vaddr addr, + MMUAccessType access_type, int mmu_idx, + uintptr_t retaddr) +{ + CPUHexagonState *env = cpu_env(cs); + + raise_misaligned_exception(cs, addr, 0, access_type); + do_raise_exception(env, cs->exception_index, env->gpr[HEX_REG_PC], + retaddr); +} + #endif static const TCGCPUOps hexagon_tcg_ops = { @@ -732,6 +756,7 @@ static const TCGCPUOps hexagon_tcg_ops = { .pointer_wrap = hexagon_pointer_wrap, .cpu_exec_reset = cpu_reset, .tlb_fill = hexagon_tlb_fill, + .do_unaligned_access = hexagon_cpu_do_unaligned_access, .cpu_exec_halt = hexagon_cpu_has_work, .do_interrupt = hexagon_cpu_do_interrupt, #endif /* !CONFIG_USER_ONLY */ -- 2.34.1
