Commit 9945e93ea5 for qemu.org
commit 9945e93ea5f4f2dcba1fb60b6a28f60b48e377db
Author: Bibo Mao <maobibo@loongson.cn>
Date: Fri Oct 30 11:16:55 2026 +0800
target/loongarch: Support unaligned access for atomic instructions
For atomic instructions and LL/SC instruction pairs, the accessed
address must be aligned to the access size. Otherwise, an EXCCODE_ALE
exception is raised.
Add support for unaligned address accesses for these instructions.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Xianglai Li <lixianglai@loongson.cn>
diff --git a/target/loongarch/tcg/tcg_cpu.c b/target/loongarch/tcg/tcg_cpu.c
index cbf0e12c81..0549506035 100644
--- a/target/loongarch/tcg/tcg_cpu.c
+++ b/target/loongarch/tcg/tcg_cpu.c
@@ -92,6 +92,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
case EXCCODE_PME:
case EXCCODE_PNR:
case EXCCODE_PPI:
+ case EXCCODE_ALE:
cause = cs->exception_index;
break;
default:
@@ -289,5 +290,6 @@ const TCGCPUOps loongarch_tcg_ops = {
.cpu_exec_reset = cpu_reset,
.do_interrupt = loongarch_cpu_do_interrupt,
.do_transaction_failed = loongarch_cpu_do_transaction_failed,
+ .do_unaligned_access = loongarch_cpu_do_unaligned_access,
#endif
};
diff --git a/target/loongarch/tcg/tcg_loongarch.h b/target/loongarch/tcg/tcg_loongarch.h
index 7fb627f2d6..9c8627972f 100644
--- a/target/loongarch/tcg/tcg_loongarch.h
+++ b/target/loongarch/tcg/tcg_loongarch.h
@@ -15,6 +15,10 @@ void loongarch_csr_translate_init(void);
bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr);
+G_NORETURN void loongarch_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
+ MMUAccessType access_type,
+ int mmu_idx,
+ uintptr_t retaddr);
TLBRet loongarch_get_addr_from_tlb(CPULoongArchState *env,
MMUContext *context,
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index a707de9876..5662b2c49a 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -706,6 +706,22 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
cpu_loop_exit_restore(cs, retaddr);
}
+G_NORETURN void loongarch_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
+ MMUAccessType access_type,
+ int mmu_idx,
+ uintptr_t retaddr)
+{
+ CPULoongArchState *env = cpu_env(cs);
+ CPUSysState *sys = env_sys(env);
+
+ /*
+ * Unaligned accesses are currently triggered by atomic instructions
+ * that impose alignment requirements on memory operands.
+ */
+ sys->CSR_BADV = vaddr;
+ do_raise_exception(env, EXCCODE_ALE, retaddr);
+}
+
static inline uint64_t loongarch_sanitize_hw_pte(CPULoongArchState *env,
uint64_t pte)
{