@samitouri / QOSamiQemu / commits / 65ab8772c0

target/arm: Don't enforce alignment faults on Device memory for SCTLR.U == 0

We enforce that we take alignment faults for unaligned accesses when the MMU is disabled or the access is to Device memory. This is correct for the new-style unaligned accesses rules that were introduced in ARMv6 when SCTLR.U == 1 and then became the only option from ARMv7 (where SCTLR.U is RES1). However, it isn't right for the old ARMv4 and ARMv5 setup (and ARMv6 when SCTLR.U = 0). We don't emulate the v4/v5 alignment rules (which notably include "for unaligned LDR, do an aligned load and rotate"); but taking an alignment fault is definitely wrong and isn't what QEMU has traditionally done. Restrict this behaviour to when SCTLR.U is 1. (The other place we enable alignment checks on Device memory is in ptw.c, but we only set TLB_CHECK_ALIGNED for LPAE translations, which are guaranteed to be v7 or later.) Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260819190015.3555218-1-peter.maydell@linaro.org

Peter Maydell committed Aug 19, 2026 at 20:00 UTC 65ab8772c0904fa43cf8b7f6405d79aa96b08c5f
1 file changed +12
target/arm/tcg/hflags.c
+12
@@ -47,6 +47,18 @@ static bool aprofile_require_alignment(CPUARMState *env, int el, uint64_t sctlr)
47 return false;
48 }
49
50 + /*
51 + * Pre-v6 had a completely different model for unaligned accesses,
52 + * which doesn't include taking unaligned faults for Device memory.
53 + * v6 has the new model only when SCTLR.U is set. Later architecture
54 + * versions repurpose the SCTLR bit for something else, so we mustn't
55 + * test it except for actual v6 CPUs.
56 + */
57 + if (!arm_feature(env, ARM_FEATURE_V6) ||
58 + (!arm_feature(env, ARM_FEATURE_V7) && !(sctlr & SCTLR_U))) {
59 + return false;
60 + }
61 +
62 /*
63 * With VMSA, if translation is disabled, then the default memory type
64 * is Device(-nGnRnE) instead of Normal, which requires that alignment