Message ID | 20241114160131.48616-49-richard.henderson@linaro.org |
---|---|
State | New |
Headers | show |
Series | accel/tcg: Convert victim tlb to IntervalTree | expand |
On 11/14/24 08:01, Richard Henderson wrote: > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > target/sparc/cpu.h | 8 ++++--- > target/sparc/cpu.c | 2 +- > target/sparc/mmu_helper.c | 44 +++++++++++++++++++++++++-------------- > 3 files changed, 34 insertions(+), 20 deletions(-) > > diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h > index f517e5a383..4c8927e9fa 100644 > --- a/target/sparc/cpu.h > +++ b/target/sparc/cpu.h > @@ -4,6 +4,7 @@ > #include "qemu/bswap.h" > #include "cpu-qom.h" > #include "exec/cpu-defs.h" > +#include "exec/memop.h" > #include "qemu/cpu-float.h" > > #if !defined(TARGET_SPARC64) > @@ -596,9 +597,10 @@ G_NORETURN void cpu_raise_exception_ra(CPUSPARCState *, int, uintptr_t); > void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu); > void sparc_cpu_list(void); > /* mmu_helper.c */ > -bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size, > - MMUAccessType access_type, int mmu_idx, > - bool probe, uintptr_t retaddr); > +bool sparc_cpu_tlb_fill_align(CPUState *cs, CPUTLBEntryFull *out, > + vaddr addr, MMUAccessType access_type, > + int mmu_idx, MemOp memop, int size, > + bool probe, uintptr_t retaddr); > target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev); > void dump_mmu(CPUSPARCState *env); > > diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c > index dd7af86de7..57ae53bd71 100644 > --- a/target/sparc/cpu.c > +++ b/target/sparc/cpu.c > @@ -932,7 +932,7 @@ static const TCGCPUOps sparc_tcg_ops = { > .restore_state_to_opc = sparc_restore_state_to_opc, > > #ifndef CONFIG_USER_ONLY > - .tlb_fill = sparc_cpu_tlb_fill, > + .tlb_fill_align = sparc_cpu_tlb_fill_align, > .cpu_exec_interrupt = sparc_cpu_exec_interrupt, > .cpu_exec_halt = sparc_cpu_has_work, > .do_interrupt = sparc_cpu_do_interrupt, > diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c > index 9ff06026b8..32766a37d6 100644 > --- a/target/sparc/mmu_helper.c > +++ b/target/sparc/mmu_helper.c > @@ -203,12 +203,12 @@ static int get_physical_address(CPUSPARCState *env, CPUTLBEntryFull *full, > } > > /* Perform address translation */ > -bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size, > - MMUAccessType access_type, int mmu_idx, > - bool probe, uintptr_t retaddr) > +bool sparc_cpu_tlb_fill_align(CPUState *cs, CPUTLBEntryFull *out, > + vaddr address, MMUAccessType access_type, > + int mmu_idx, MemOp memop, int size, > + bool probe, uintptr_t retaddr) > { > CPUSPARCState *env = cpu_env(cs); > - CPUTLBEntryFull full = {}; > target_ulong vaddr; > int error_code = 0, access_index; > > @@ -220,16 +220,21 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size, > */ > assert(!probe); > > + if (address & ((1 << memop_alignment_bits(memop)) - 1)) { > + sparc_cpu_do_unaligned_access(cs, address, access_type, > + mmu_idx, retaddr); > + } > + > + memset(out, 0, sizeof(*out)); > address &= TARGET_PAGE_MASK; > - error_code = get_physical_address(env, &full, &access_index, > + error_code = get_physical_address(env, out, &access_index, > address, access_type, mmu_idx); > vaddr = address; > if (likely(error_code == 0)) { > qemu_log_mask(CPU_LOG_MMU, > "Translate at %" VADDR_PRIx " -> " > HWADDR_FMT_plx ", vaddr " TARGET_FMT_lx "\n", > - address, full.phys_addr, vaddr); > - tlb_set_page_full(cs, mmu_idx, vaddr, &full); > + address, out->phys_addr, vaddr); > return true; > } > > @@ -244,8 +249,7 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size, > permissions. If no mapping is available, redirect accesses to > neverland. Fake/overridden mappings will be flushed when > switching to normal mode. */ > - full.prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; > - tlb_set_page_full(cs, mmu_idx, vaddr, &full); > + out->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; > return true; > } else { > if (access_type == MMU_INST_FETCH) { > @@ -754,22 +758,30 @@ static int get_physical_address(CPUSPARCState *env, CPUTLBEntryFull *full, > } > > /* Perform address translation */ > -bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size, > - MMUAccessType access_type, int mmu_idx, > - bool probe, uintptr_t retaddr) > +bool sparc_cpu_tlb_fill_align(CPUState *cs, CPUTLBEntryFull *out, > + vaddr address, MMUAccessType access_type, > + int mmu_idx, MemOp memop, int size, > + bool probe, uintptr_t retaddr) > { > CPUSPARCState *env = cpu_env(cs); > - CPUTLBEntryFull full = {}; > int error_code = 0, access_index; > > + if (address & ((1 << memop_alignment_bits(memop)) - 1)) { > + if (probe) { > + return false; > + } > + sparc_cpu_do_unaligned_access(cs, address, access_type, > + mmu_idx, retaddr); > + } > + > + memset(out, 0, sizeof(*out)); > address &= TARGET_PAGE_MASK; > - error_code = get_physical_address(env, &full, &access_index, > + error_code = get_physical_address(env, out, &access_index, > address, access_type, mmu_idx); > if (likely(error_code == 0)) { > - trace_mmu_helper_mmu_fault(address, full.phys_addr, mmu_idx, env->tl, > + trace_mmu_helper_mmu_fault(address, out->phys_addr, mmu_idx, env->tl, > env->dmmu.mmu_primary_context, > env->dmmu.mmu_secondary_context); > - tlb_set_page_full(cs, mmu_idx, address, &full); > return true; > } > if (probe) { Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h index f517e5a383..4c8927e9fa 100644 --- a/target/sparc/cpu.h +++ b/target/sparc/cpu.h @@ -4,6 +4,7 @@ #include "qemu/bswap.h" #include "cpu-qom.h" #include "exec/cpu-defs.h" +#include "exec/memop.h" #include "qemu/cpu-float.h" #if !defined(TARGET_SPARC64) @@ -596,9 +597,10 @@ G_NORETURN void cpu_raise_exception_ra(CPUSPARCState *, int, uintptr_t); void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu); void sparc_cpu_list(void); /* mmu_helper.c */ -bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size, - MMUAccessType access_type, int mmu_idx, - bool probe, uintptr_t retaddr); +bool sparc_cpu_tlb_fill_align(CPUState *cs, CPUTLBEntryFull *out, + vaddr addr, MMUAccessType access_type, + int mmu_idx, MemOp memop, int size, + bool probe, uintptr_t retaddr); target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev); void dump_mmu(CPUSPARCState *env); diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c index dd7af86de7..57ae53bd71 100644 --- a/target/sparc/cpu.c +++ b/target/sparc/cpu.c @@ -932,7 +932,7 @@ static const TCGCPUOps sparc_tcg_ops = { .restore_state_to_opc = sparc_restore_state_to_opc, #ifndef CONFIG_USER_ONLY - .tlb_fill = sparc_cpu_tlb_fill, + .tlb_fill_align = sparc_cpu_tlb_fill_align, .cpu_exec_interrupt = sparc_cpu_exec_interrupt, .cpu_exec_halt = sparc_cpu_has_work, .do_interrupt = sparc_cpu_do_interrupt, diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c index 9ff06026b8..32766a37d6 100644 --- a/target/sparc/mmu_helper.c +++ b/target/sparc/mmu_helper.c @@ -203,12 +203,12 @@ static int get_physical_address(CPUSPARCState *env, CPUTLBEntryFull *full, } /* Perform address translation */ -bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size, - MMUAccessType access_type, int mmu_idx, - bool probe, uintptr_t retaddr) +bool sparc_cpu_tlb_fill_align(CPUState *cs, CPUTLBEntryFull *out, + vaddr address, MMUAccessType access_type, + int mmu_idx, MemOp memop, int size, + bool probe, uintptr_t retaddr) { CPUSPARCState *env = cpu_env(cs); - CPUTLBEntryFull full = {}; target_ulong vaddr; int error_code = 0, access_index; @@ -220,16 +220,21 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size, */ assert(!probe); + if (address & ((1 << memop_alignment_bits(memop)) - 1)) { + sparc_cpu_do_unaligned_access(cs, address, access_type, + mmu_idx, retaddr); + } + + memset(out, 0, sizeof(*out)); address &= TARGET_PAGE_MASK; - error_code = get_physical_address(env, &full, &access_index, + error_code = get_physical_address(env, out, &access_index, address, access_type, mmu_idx); vaddr = address; if (likely(error_code == 0)) { qemu_log_mask(CPU_LOG_MMU, "Translate at %" VADDR_PRIx " -> " HWADDR_FMT_plx ", vaddr " TARGET_FMT_lx "\n", - address, full.phys_addr, vaddr); - tlb_set_page_full(cs, mmu_idx, vaddr, &full); + address, out->phys_addr, vaddr); return true; } @@ -244,8 +249,7 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size, permissions. If no mapping is available, redirect accesses to neverland. Fake/overridden mappings will be flushed when switching to normal mode. */ - full.prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; - tlb_set_page_full(cs, mmu_idx, vaddr, &full); + out->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; return true; } else { if (access_type == MMU_INST_FETCH) { @@ -754,22 +758,30 @@ static int get_physical_address(CPUSPARCState *env, CPUTLBEntryFull *full, } /* Perform address translation */ -bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size, - MMUAccessType access_type, int mmu_idx, - bool probe, uintptr_t retaddr) +bool sparc_cpu_tlb_fill_align(CPUState *cs, CPUTLBEntryFull *out, + vaddr address, MMUAccessType access_type, + int mmu_idx, MemOp memop, int size, + bool probe, uintptr_t retaddr) { CPUSPARCState *env = cpu_env(cs); - CPUTLBEntryFull full = {}; int error_code = 0, access_index; + if (address & ((1 << memop_alignment_bits(memop)) - 1)) { + if (probe) { + return false; + } + sparc_cpu_do_unaligned_access(cs, address, access_type, + mmu_idx, retaddr); + } + + memset(out, 0, sizeof(*out)); address &= TARGET_PAGE_MASK; - error_code = get_physical_address(env, &full, &access_index, + error_code = get_physical_address(env, out, &access_index, address, access_type, mmu_idx); if (likely(error_code == 0)) { - trace_mmu_helper_mmu_fault(address, full.phys_addr, mmu_idx, env->tl, + trace_mmu_helper_mmu_fault(address, out->phys_addr, mmu_idx, env->tl, env->dmmu.mmu_primary_context, env->dmmu.mmu_secondary_context); - tlb_set_page_full(cs, mmu_idx, address, &full); return true; } if (probe) {
Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/sparc/cpu.h | 8 ++++--- target/sparc/cpu.c | 2 +- target/sparc/mmu_helper.c | 44 +++++++++++++++++++++++++-------------- 3 files changed, 34 insertions(+), 20 deletions(-)