On 5/26/26 10:41, Peter Maydell wrote:
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: [email protected]
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 <[email protected]>
---
target/arm/internals.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 00830b1724..bb15b149f9 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -880,6 +880,16 @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
assert(fi->level >= 0 && fi->level <= 3);
fsc = 0b001100 | fi->level;
break;
+ case ARMFault_Domain:
+ /*
+ * This can only happen when doing an AT insn at EL2 for an AArch32
+ * stage 1 EL1&0 translation regime using short-descriptors, and
+ * the translation hits a Domain fault. This needs to be reported in
+ * in the long-format PAR. Compare pseudocode
AArch64_PARFault_Status().
PARFaultStatus.
+ */
+ assert(fi->level == 1 || fi->level == 2);
+ fsc = 0b111100 | fi->level;
+ break;
case ARMFault_Translation:
assert(fi->level >= -1 && fi->level <= 3);
if (fi->level < 0) {
Reviewed-by: Richard Henderson <[email protected]>
r~