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

Reply via email to