target/arm: set HPFAR_EL2.NS on secure stage 2 faults
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20210112104511.36576-15-remi.denis.courmont@huawei.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
b1a10c868f
commit
9861248f63
|
@ -1484,6 +1484,8 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
|
||||||
#define HCR_TWEDEN (1ULL << 59)
|
#define HCR_TWEDEN (1ULL << 59)
|
||||||
#define HCR_TWEDEL MAKE_64BIT_MASK(60, 4)
|
#define HCR_TWEDEL MAKE_64BIT_MASK(60, 4)
|
||||||
|
|
||||||
|
#define HPFAR_NS (1ULL << 63)
|
||||||
|
|
||||||
#define SCR_NS (1U << 0)
|
#define SCR_NS (1U << 0)
|
||||||
#define SCR_IRQ (1U << 1)
|
#define SCR_IRQ (1U << 1)
|
||||||
#define SCR_FIQ (1U << 2)
|
#define SCR_FIQ (1U << 2)
|
||||||
|
|
|
@ -3445,6 +3445,9 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
|
||||||
target_el = 3;
|
target_el = 3;
|
||||||
} else {
|
} else {
|
||||||
env->cp15.hpfar_el2 = extract64(fi.s2addr, 12, 47) << 4;
|
env->cp15.hpfar_el2 = extract64(fi.s2addr, 12, 47) << 4;
|
||||||
|
if (arm_is_secure_below_el3(env) && fi.s1ns) {
|
||||||
|
env->cp15.hpfar_el2 |= HPFAR_NS;
|
||||||
|
}
|
||||||
target_el = 2;
|
target_el = 2;
|
||||||
}
|
}
|
||||||
take_exc = true;
|
take_exc = true;
|
||||||
|
@ -10427,6 +10430,7 @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
|
||||||
fi->s2addr = addr;
|
fi->s2addr = addr;
|
||||||
fi->stage2 = true;
|
fi->stage2 = true;
|
||||||
fi->s1ptw = true;
|
fi->s1ptw = true;
|
||||||
|
fi->s1ns = !*is_secure;
|
||||||
return ~0;
|
return ~0;
|
||||||
}
|
}
|
||||||
if ((arm_hcr_el2_eff(env) & HCR_PTW) &&
|
if ((arm_hcr_el2_eff(env) & HCR_PTW) &&
|
||||||
|
@ -10439,6 +10443,7 @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
|
||||||
fi->s2addr = addr;
|
fi->s2addr = addr;
|
||||||
fi->stage2 = true;
|
fi->stage2 = true;
|
||||||
fi->s1ptw = true;
|
fi->s1ptw = true;
|
||||||
|
fi->s1ns = !*is_secure;
|
||||||
return ~0;
|
return ~0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11356,6 +11361,7 @@ do_fault:
|
||||||
/* Tag the error as S2 for failed S1 PTW at S2 or ordinary S2. */
|
/* Tag the error as S2 for failed S1 PTW at S2 or ordinary S2. */
|
||||||
fi->stage2 = fi->s1ptw || (mmu_idx == ARMMMUIdx_Stage2 ||
|
fi->stage2 = fi->s1ptw || (mmu_idx == ARMMMUIdx_Stage2 ||
|
||||||
mmu_idx == ARMMMUIdx_Stage2_S);
|
mmu_idx == ARMMMUIdx_Stage2_S);
|
||||||
|
fi->s1ns = mmu_idx == ARMMMUIdx_Stage2;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -593,6 +593,7 @@ typedef enum ARMFaultType {
|
||||||
* @s2addr: Address that caused a fault at stage 2
|
* @s2addr: Address that caused a fault at stage 2
|
||||||
* @stage2: True if we faulted at stage 2
|
* @stage2: True if we faulted at stage 2
|
||||||
* @s1ptw: True if we faulted at stage 2 while doing a stage 1 page-table walk
|
* @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
|
||||||
* @ea: True if we should set the EA (external abort type) bit in syndrome
|
* @ea: True if we should set the EA (external abort type) bit in syndrome
|
||||||
*/
|
*/
|
||||||
typedef struct ARMMMUFaultInfo ARMMMUFaultInfo;
|
typedef struct ARMMMUFaultInfo ARMMMUFaultInfo;
|
||||||
|
@ -603,6 +604,7 @@ struct ARMMMUFaultInfo {
|
||||||
int domain;
|
int domain;
|
||||||
bool stage2;
|
bool stage2;
|
||||||
bool s1ptw;
|
bool s1ptw;
|
||||||
|
bool s1ns;
|
||||||
bool ea;
|
bool ea;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,9 @@ static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
|
||||||
if (fi->stage2) {
|
if (fi->stage2) {
|
||||||
target_el = 2;
|
target_el = 2;
|
||||||
env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
|
env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
|
||||||
|
if (arm_is_secure_below_el3(env) && fi->s1ns) {
|
||||||
|
env->cp15.hpfar_el2 |= HPFAR_NS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
same_el = (arm_current_el(env) == target_el);
|
same_el = (arm_current_el(env) == target_el);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue