@samitouri / QOSamiQemu / commits / bb95753047

target/arm: Don't assert if 64-bit EL2 AT insn sees a Domain fault

The Domain fault type can only happen for 32-bit short-format descriptors. This means that it almost never needs to be encoded in a long-format fault status code. However, there is one corner case where we do need to report it as a long-format FSC: if a 64-bit EL2 does an AT insn on an AArch32 EL1&0 translation regime that is using short-descriptors and that translation operation hits a Domain fault, then this is reported in the PAR_EL1 in long-format. The PAR_EL1 register description defines that this should be reported as 0b111101 for a level 1 Domain fault or 0b111110 for a level 2 Domain fault. The Arm ARM pseudocode special cases this in the function AArch64_PARFaultStatus() (because no other "fault to LFSC" code path can be a Domain fault). For QEMU, implement it in arm_fi_to_lfsc(). Cc: qemu-stable@nongnu.org Fixes: 1fa498fe0de97 ("target/arm: Provide fault type enum and FSR conversion functions") Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3512 Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260526174155.2491217-1-peter.maydell@linaro.org

Peter Maydell committed May 28, 2026 at 17:24 UTC bb957530471c792a9a51e822a6c2fa8398cc48f6
1 file changed +10
target/arm/internals.h
+10
@@ -893,6 +893,16 @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
893 assert(fi->level >= 0 && fi->level <= 3);
894 fsc = 0b001100 | fi->level;
895 break;
896 + case ARMFault_Domain:
897 + /*
898 + * This can only happen when doing an AT insn at EL2 for an AArch32
899 + * stage 1 EL1&0 translation regime using short-descriptors, and
900 + * the translation hits a Domain fault. This needs to be reported in
901 + * the long-format PAR. Compare pseudocode AArch64_PARFaultStatus().
902 + */
903 + assert(fi->level == 1 || fi->level == 2);
904 + fsc = 0b111100 | fi->level;
905 + break;
906 case ARMFault_Translation:
907 assert(fi->level >= -1 && fi->level <= 3);
908 if (fi->level < 0) {