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(-)

diff --git a/include/accel/tcg/probe.h b/include/accel/tcg/probe.h
index 0b788901ba..e3068a79de 100644
--- a/include/accel/tcg/probe.h
+++ b/include/accel/tcg/probe.h
@@ -86,7 +86,7 @@ int probe_access_flags(CPUArchState *env, vaddr addr, int 
size,
  * This function will return TLB_MMIO in order to force the access
  * to be handled out-of-line if plugins wish to instrument the access.
  */
-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);
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 7f7c208ba1..6299cc73a4 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -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/helper-a64.c b/target/arm/tcg/helper-a64.c
index 05ab9ab6d3..2e0e7cd756 100644
--- a/target/arm/tcg/helper-a64.c
+++ b/target/arm/tcg/helper-a64.c
@@ -1745,7 +1745,10 @@ static bool is_guarded_page(CPUARMState *env, vaddr 
addr, uintptr_t ra)
     CPUTLBEntryFull *full;
     void *host;
     int mmu_idx = cpu_mmu_index(env_cpu(env), true);
-    int flags = probe_access_full(env, addr, 0, MMU_INST_FETCH, mmu_idx,
+    int flags = probe_access_full(env, addr,
+                                  addr & TARGET_PAGE_MASK,
+                                  addr | ~TARGET_PAGE_MASK,
+                                  MMU_INST_FETCH, mmu_idx,
                                   false, &host, &full, ra);
 
     assert(!(flags & TLB_INVALID_MASK));
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;
+
+    ret.flags = probe_access_full(env, ptr, ptr, MIN(ptr_last, ptr_page_last),
+                                  ptr_access, ptr_mmu_idx,
                                   atm_kind >= ATM_PROBE_PAGES,
                                   &ret.ptr_mem, &full, ra);
     if (unlikely(ret.flags & TLB_INVALID_MASK)) {
@@ -184,14 +189,12 @@ allocation_tag_mem_internal(CPUARMState *env, int 
ptr_mmu_idx,
      * tag on the first page.
      * Any page access exception has priority over tag check exception.
      */
-    if (atm_kind == ATM_NORMAL) {
-        int in_page = -(ptr | TARGET_PAGE_MASK);
-        if (unlikely(ptr_size > in_page)) {
-            void *discard_mem;
-            ret.flags |= probe_access_full(env, ptr + in_page, 0, ptr_access,
-                                           ptr_mmu_idx, false,
-                                           &discard_mem, &full, ra);
-        }
+    if (atm_kind == ATM_NORMAL && unlikely(ptr_page_last < ptr_last)) {
+        void *discard_mem;
+        ret.flags |= probe_access_full(env, ptr_page_last + 1,
+                                       ptr_page_last + 1, ptr_last,
+                                       ptr_access, ptr_mmu_idx, false,
+                                       &discard_mem, &full, ra);
     }
 
     switch (pte_attrs) {
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
index ac96b18784..4e77a824dd 100644
--- a/target/arm/tcg/sve_helper.c
+++ b/target/arm/tcg/sve_helper.c
@@ -6040,7 +6040,10 @@ bool sve_probe_page(SVEHostPage *info, bool nofault, 
CPUARMState *env,
                                &info->host, retaddr);
 #else
     CPUTLBEntryFull *full;
-    flags = probe_access_full(env, addr, 0, access_type, mmu_idx, nofault,
+    flags = probe_access_full(env, addr,
+                              addr & TARGET_PAGE_MASK,
+                              addr | ~TARGET_PAGE_MASK,
+                              access_type, mmu_idx, nofault,
                               &info->host, &full, retaddr);
 #endif
     info->flags = flags;
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;                                                        \
-- 
2.43.0


Reply via email to