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