diff --git a/target/arm/internals.h b/target/arm/internals.h index 8ec2750847..85980f0e69 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -740,7 +740,10 @@ typedef enum ARMGPCF { * @paddr_space: physical address space that caused a fault for gpc * @stage2: True if we faulted at stage 2 * @s1ptw: True if we faulted at stage 2 while doing a stage 1 page-table walk - * @s1ns: True if we faulted on a non-secure IPA while in secure state + * @s1ns: True if we faulted on a non-secure IPA. Note that (unlike the + * HPFAR_EL2.NS bit) this is set for any stage 2 fault for an NS IPA, so + * code must check that this is for a fault taken to Secure EL2 before + * propagating s1ns to HPFAR_EL2.NS. * @ea: True if we should set the EA (external abort type) bit in syndrome */ typedef struct ARMMMUFaultInfo ARMMMUFaultInfo; diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 08a76bd3f1..7b993bb5b3 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -611,12 +611,14 @@ static ARMSecuritySpace S2_security_space(ARMSecuritySpace s1_space, static bool fault_s1ns(ARMSecuritySpace space, ARMMMUIdx s2_mmu_idx) { /* - * For stage 2 faults in Secure EL22, S1NS indicates - * whether the faulting IPA is in the Secure or NonSecure - * IPA space. For all other kinds of fault, it is false. + * For stage 2 faults, S1NS indicates whether the faulting IPA is + * in the Non-Secure (true) or Secure (false) IPA space. For all + * other kinds of fault, it is false. Note that we do not + * distinguish "s2 fault on NS IPA taken to Secure EL2" from + * "s2 fault on NS IPA taken to NS EL2 or Realm EL2" here, but + * instead do that when setting HPFAR_EL2.NS. */ - return space == ARMSS_Secure && regime_is_stage2(s2_mmu_idx) - && s2_mmu_idx == ARMMMUIdx_Stage2_S; + return space == ARMSS_NonSecure && regime_is_stage2(s2_mmu_idx); } /* Translate a S1 pagetable walk through S2 if needed. */