On Tue, 14 Oct 2025 at 21:09, Richard Henderson
<[email protected]> wrote:
>
> Signed-off-by: Richard Henderson <[email protected]>
> ---
> target/arm/tcg/tlb-insns.c | 93 ++++++++++++++++++++++++++++++--------
> 1 file changed, 74 insertions(+), 19 deletions(-)
>
> diff --git a/target/arm/tcg/tlb-insns.c b/target/arm/tcg/tlb-insns.c
> index f7510a1208..daadba7bfc 100644
> --- a/target/arm/tcg/tlb-insns.c
> +++ b/target/arm/tcg/tlb-insns.c
> @@ -918,16 +918,43 @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env,
> ARMMMUIdx mmuidx,
> return ret;
> }
>
> -static void do_rvae_write(CPUARMState *env, uint64_t value,
> - int idxmap, bool synced)
> +static TLBIRange tlbi_aa64_get_range128(CPUARMState *env, ARMMMUIdx mmuidx,
> + uint64_t vallo, uint64_t valhi)
> {
> - ARMMMUIdx one_idx = ARM_MMU_IDX_A | ctz32(idxmap);
> - TLBIRange range;
> - int bits;
> + uint64_t uaddr = extract64(valhi << 12, 0, 56);
> + ARMVAParameters param = aa64_va_parameters(env, uaddr, mmuidx, true,
> false);
> + TLBIRange ret = { };
> + unsigned page_size_granule = extract64(vallo, 46, 2);
> + ARMGranuleSize gran = tlbi_range_tg_to_gran_size(page_size_granule);
>
> - range = tlbi_aa64_get_range(env, one_idx, value);
> - bits = tlbbits_for_regime(env, one_idx, range.base);
> + /* The granule encoded in value must match the granule in use. */
> + if (gran != param.gran) {
> + qemu_log_mask(LOG_GUEST_ERROR, "Invalid tlbi page size granule %d\n",
> + page_size_granule);
Having an early-return here would make this code more obviously
parallel with tlbi_aa64_get_range().
> + } else {
> + unsigned page_shift = arm_granule_bits(gran);
> + unsigned num = extract64(vallo, 39, 5);
> + unsigned scale = extract64(vallo, 44, 2);
> + unsigned exponent = (5 * scale) + 1;
> + uint64_t max = 1ull << 56;
>
> + ret.length = (num + 1) << (exponent + page_shift);
> + ret.length = MIN(ret.length, max - uaddr);
> + /*
> + * Note that TLBIPRange ignores the high bits, because the HW TLB
> + * does not use it. But the qemu softmmu tlb does, so sign-extend
> + * if and only if the regime has two ranges.
> + */
> + ret.base = uaddr | (-(uint64_t)param.select << 56);
I think it would be clearer if we wrote this "sign extend
based on param.select" the same way that tlbi_aa64_get_range()
does".
Otherwise
Reviewed-by: Peter Maydell <[email protected]>
thanks
-- PMM