[RFC PATCH 07/18] accel/tcg: Replace size with first/last in probe_access_full
Richard Henderson <[email protected]>
| Newsgroups | org.nongnu.qemu-riscv,org.nongnu.qemu-arm,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
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