On Sat, 15 Aug 2026 at 21:39, Richard Henderson
<[email protected]> wrote:
>
> Signed-off-by: Richard Henderson <[email protected]>
> ---
> include/accel/tcg/probe.h | 2 +-
> accel/tcg/cputlb.c | 17 +++++++++++------
> target/arm/tcg/helper-a64.c | 5 ++++-
> target/arm/tcg/mte_helper.c | 21 ++++++++++++---------
> target/arm/tcg/sve_helper.c | 5 ++++-
> target/mips/tcg/ldst_helper.c | 4 ++--
> 6 files changed, 34 insertions(+), 20 deletions(-)
> @@ -1412,19 +1412,24 @@ static int probe_access_internal(CPUState *cpu, vaddr
> addr,
> return flags;
> }
>
> -int probe_access_full(CPUArchState *env, vaddr addr, int size,
> +int probe_access_full(CPUArchState *env, vaddr addr, vaddr first, vaddr last,
> MMUAccessType access_type, int mmu_idx,
> bool nonfault, void **phost, CPUTLBEntryFull **pfull,
> uintptr_t retaddr)
> {
> - int flags = probe_access_internal(env_cpu(env), addr, size, access_type,
> - mmu_idx, nonfault, phost, pfull,
> retaddr,
> - true);
> + int flags;
> +
> + assert(first <= addr);
> + assert(addr <= last);
> + assert(((first ^ last) & TARGET_PAGE_MASK) == 0);
> +
> + flags = probe_access_internal(env_cpu(env), addr, last - addr + 1,
> + access_type, mmu_idx, nonfault,
> + phost, pfull, retaddr, true);
>
> /* Handle clean RAM pages. */
> if (unlikely(flags & TLB_NOTDIRTY)) {
> - int dirtysize = size == 0 ? 1 : size;
> - notdirty_write(env_cpu(env), addr, dirtysize, *pfull, retaddr);
> + notdirty_write(env_cpu(env), first, last - first + 1, *pfull,
> retaddr);
> flags &= ~TLB_NOTDIRTY;
> }
> diff --git a/target/arm/tcg/mte_helper.c b/target/arm/tcg/mte_helper.c
> index 399bca30c9..f36286d596 100644
> --- a/target/arm/tcg/mte_helper.c
> +++ b/target/arm/tcg/mte_helper.c
> @@ -151,6 +151,7 @@ allocation_tag_mem_internal(CPUARMState *env, int
> ptr_mmu_idx,
> ret.flags = 0;
> #else
> CPUTLBEntryFull *full;
> + vaddr ptr_last, ptr_page_last;
> hwaddr ptr_paddr, tag_paddr, xlat;
> MemoryRegion *mr;
> ARMASIdx tag_asi;
> @@ -162,7 +163,11 @@ allocation_tag_mem_internal(CPUARMState *env, int
> ptr_mmu_idx,
> * exception for inaccessible pages, and resolves the virtual address
> * into the softmmu tlb.
> */
> - ret.flags = probe_access_full(env, ptr, 0, ptr_access, ptr_mmu_idx,
> + ptr_last = ptr + ptr_size - 1;
> + ptr_page_last = ptr | ~TARGET_PAGE_MASK;
Are we definitely guaranteed not to get here such that ptr_last has wrapped
back around to 0 ? I think 'ptr' can come directly from the guest
(e.g. trans_LDG can pass a guest register value to HELPER(ldg), which
calls us). In that case we'll fail the assert() inside probe_access_full()
because last will be < addr. The second probe below will also calculate
a ptr_page_last + 1 that wraps round to 0.
> diff --git a/target/mips/tcg/ldst_helper.c b/target/mips/tcg/ldst_helper.c
> index 1b25466b49..065570a8f1 100644
> --- a/target/mips/tcg/ldst_helper.c
> +++ b/target/mips/tcg/ldst_helper.c
> @@ -44,8 +44,8 @@ target_ulong helper_##name(CPUMIPSState *env, target_ulong
> arg, \
> int flags;
> \
>
> \
> env->llval = do_cast cpu_##insn##_mmu(env, arg, oi, ra);
> \
> - flags = probe_access_full(env, arg, size, MMU_DATA_LOAD, mem_idx,
> \
> - true, &host_unused, &full, ra);
> \
> + flags = probe_access_full(env, arg, arg, arg + size - 1, MMU_DATA_LOAD,
> \
> + mem_idx, true, &host_unused, &full, ra);
> \
> assert(!(flags & TLB_INVALID_MASK));
> \
> env->CP0_LLAddr = full->phys_addr;
> \
> env->lladdr = arg;
> \
The macro magic in the MIPS translator is confusing, but I think that
it's possible that "arg + size - 1" here also might wrap round to 0 ?
thanks
-- PMM