Without FEAT_LVA, the behaviour of programming an invalid value is IMPLEMENTATION DEFINED. With FEAT_LVA, programming an invalid minimum value requires a Translation fault.
It is most self-consistent to choose to generate the fault always. Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- target/arm/helper.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 9b317899a6..575723d62c 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -11129,7 +11129,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, { uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr; bool epd, hpd, using16k, using64k; - int select, tsz, tbi, max_tsz; + int select, tsz, tbi; if (!regime_has_2_ranges(mmu_idx)) { select = 0; @@ -11165,15 +11165,6 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, } } - if (cpu_isar_feature(aa64_st, env_archcpu(env))) { - max_tsz = 48 - using64k; - } else { - max_tsz = 39; - } - - tsz = MIN(tsz, max_tsz); - tsz = MAX(tsz, 16); /* TODO: ARMv8.2-LVA */ - /* Present TBI as a composite with TBID. */ tbi = aa64_va_parameter_tbi(tcr, mmu_idx); if (!data) { @@ -11309,9 +11300,30 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, /* TODO: This code does not support shareability levels. */ if (aarch64) { + int min_tsz = 16, max_tsz = 39; /* TODO: ARMv8.2-LVA */ + param = aa64_va_parameters(env, address, mmu_idx, access_type != MMU_INST_FETCH); level = 0; + + if (cpu_isar_feature(aa64_st, env_archcpu(env))) { + max_tsz = 48 - param.using64k; + } + + /* + * If TxSZ is programmed to a value larger than the maximum, + * or smaller than the effective minimum, it is IMPLEMENTATION + * DEFINED whether we behave as if the field were programmed + * within bounds, or if a level 0 Translation fault is generated. + * + * With FEAT_LVA, fault on less than minimum becomes required, + * so our choice is to always raise the fault. + */ + if (param.tsz < min_tsz || param.tsz > max_tsz) { + fault_type = ARMFault_Translation; + goto do_fault; + } + addrsize = 64 - 8 * param.tbi; inputsize = 64 - param.tsz; } else { -- 2.25.1