We fail to validate the upper bits of a virtual address on a translation disabled regime, as per AArch64.TranslateAddressS1Off.
Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- target/arm/helper.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 7cf6642210..2867adea29 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -11615,7 +11615,38 @@ bool get_phys_addr(CPUARMState *env, target_ulong address, /* Definitely a real MMU, not an MPU */ if (regime_translation_disabled(env, mmu_idx)) { - /* MMU disabled. */ + /* + * MMU disabled. S1 addresses are still checked for bounds. + * C.f. AArch64.TranslateAddressS1Off. + */ + if (is_a64(env) && mmu_idx != ARMMMUIdx_Stage2) { + int pamax = arm_pamax(env_archcpu(env)); + uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr; + int addrtop, tbi; + + tbi = aa64_va_parameter_tbi(tcr, mmu_idx); + if (access_type == MMU_INST_FETCH) { + tbi &= ~aa64_va_parameter_tbid(tcr, mmu_idx); + } + tbi = (tbi >> extract64(address, 55, 1)) & 1; + addrtop = (tbi ? 55 : 63); + + if (extract64(address, pamax, addrtop - pamax + 1) != 0) { + fi->type = ARMFault_AddressSize; + fi->level = 0; + fi->stage2 = false; + return 1; + } + + /* + * The ARM pseudocode copies bits [51:0] to addrdesc.paddress. + * Except for TBI, we've just validated everything above PAMax + * is zero. So we only need to drop TBI. + */ + if (tbi) { + address = extract64(address, 0, 56); + } + } *phys_ptr = address; *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; *page_size = TARGET_PAGE_SIZE; -- 2.20.1