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

Peter Maydell posted 1 patch 3 days, 23 hours ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260526174155.2491217-1-peter.maydell@linaro.org
Maintainers: Peter Maydell <peter.maydell@linaro.org>
target/arm/internals.h | 10 ++++++++++
1 file changed, 10 insertions(+)
[PATCH] target/arm: Don't assert if 64-bit EL2 AT insn sees a Domain fault
Posted by Peter Maydell 3 days, 23 hours ago
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>
---
 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().
+         */
+        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) {
-- 
2.43.0
Re: [PATCH] target/arm: Don't assert if 64-bit EL2 AT insn sees a Domain fault
Posted by Richard Henderson 3 days, 19 hours ago
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: 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>
> ---
>   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 <richard.henderson@linaro.org>


r~
Re: [PATCH] target/arm: Don't assert if 64-bit EL2 AT insn sees a Domain fault
Posted by Peter Maydell 3 days, 21 hours ago
On Tue, 26 May 2026 at 18:41, Peter Maydell <peter.maydell@linaro.org> wrote:
> +    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().
> +         */

The "in in" here should just be "in".

-- PMM