diff mbox series

[02/14] target/arm/ptw: Don't report GPC faults on stage 1 ptw as stage2 faults

Message ID 20230714154648.327466-3-peter.maydell@linaro.org
State Superseded
Headers show
Series target/arm/ptw: Cleanups and a few bugfixes | expand

Commit Message

Peter Maydell July 14, 2023, 3:46 p.m. UTC
In S1_ptw_translate() we set up the ARMMMUFaultInfo if the attempt to
translate the page descriptor address into a physical address fails.
This used to only be possible if we are doing a stage 2 ptw for that
descriptor address, and so the code always sets fi->stage2 and
fi->s1ptw to true.  However, with FEAT_RME it is also possible for
the lookup of the page descriptor address to fail because of a
Granule Protection Check fault.  These should not be reported as
stage 2, otherwise arm_deliver_fault() will incorrectly set
HPFAR_EL2.  Similarly the s1ptw bit should only be set for stage 2
faults on stage 1 translation table walks, i.e.  not for GPC faults.

Add a comment to the the other place where we might detect a
stage2-fault-on-stage-1-ptw, in arm_casq_ptw(), noting why we know in
that case that it must really be a stage 2 fault and not a GPC fault.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/ptw.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

Comments

Richard Henderson July 23, 2023, 9:34 a.m. UTC | #1
On 7/14/23 16:46, Peter Maydell wrote:
> In S1_ptw_translate() we set up the ARMMMUFaultInfo if the attempt to
> translate the page descriptor address into a physical address fails.
> This used to only be possible if we are doing a stage 2 ptw for that
> descriptor address, and so the code always sets fi->stage2 and
> fi->s1ptw to true.  However, with FEAT_RME it is also possible for
> the lookup of the page descriptor address to fail because of a
> Granule Protection Check fault.  These should not be reported as
> stage 2, otherwise arm_deliver_fault() will incorrectly set
> HPFAR_EL2.  Similarly the s1ptw bit should only be set for stage 2
> faults on stage 1 translation table walks, i.e.  not for GPC faults.
> 
> Add a comment to the the other place where we might detect a
> stage2-fault-on-stage-1-ptw, in arm_casq_ptw(), noting why we know in
> that case that it must really be a stage 2 fault and not a GPC fault.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---
>   target/arm/ptw.c | 10 ++++++++--
>   1 file changed, 8 insertions(+), 2 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~
diff mbox series

Patch

diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index bafeb876ad7..eb57ebd897b 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -600,8 +600,8 @@  static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
         fi->type = ARMFault_GPCFOnWalk;
     }
     fi->s2addr = addr;
-    fi->stage2 = true;
-    fi->s1ptw = true;
+    fi->stage2 = regime_is_stage2(s2_mmu_idx);
+    fi->s1ptw = fi->stage2;
     fi->s1ns = !is_secure;
     return false;
 }
@@ -719,6 +719,12 @@  static uint64_t arm_casq_ptw(CPUARMState *env, uint64_t old_val,
         env->tlb_fi = NULL;
 
         if (unlikely(flags & TLB_INVALID_MASK)) {
+            /*
+             * We know this must be a stage 2 fault because the granule
+             * protection table does not separately track read and write
+             * permission, so all GPC faults are caught in S1_ptw_translate():
+             * we only get here for "readable but not writeable".
+             */
             assert(fi->type != ARMFault_None);
             fi->s2addr = ptw->out_virt;
             fi->stage2 = true;