diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2022-10-10 20:18:57 -0700 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2022-10-20 11:27:49 +0100 |
commit | f3639a64f602ea5c1436eb9c9b89f42028e3a4a8 (patch) | |
tree | 23fbc572beedae7856fc430988a8012b310d8615 /target/arm/tlb_helper.c | |
parent | 4e7a2c9860eabd21376da522ef11e6b39fe36f85 (diff) | |
download | qemu-f3639a64f602ea5c1436eb9c9b89f42028e3a4a8.zip qemu-f3639a64f602ea5c1436eb9c9b89f42028e3a4a8.tar.gz qemu-f3639a64f602ea5c1436eb9c9b89f42028e3a4a8.tar.bz2 |
target/arm: Use softmmu tlbs for page table walking
So far, limit the change to S1_ptw_translate, arm_ldl_ptw, and
arm_ldq_ptw. Use probe_access_full to find the host address,
and if so use a host load. If the probe fails, we've got our
fault info already. On the off chance that page tables are not
in RAM, continue to use the address_space_ld* functions.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20221011031911.2408754-11-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/tlb_helper.c')
-rw-r--r-- | target/arm/tlb_helper.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c index 3462a6e..69b0dc6 100644 --- a/target/arm/tlb_helper.c +++ b/target/arm/tlb_helper.c @@ -208,11 +208,22 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size, bool probe, uintptr_t retaddr) { ARMCPU *cpu = ARM_CPU(cs); - ARMMMUFaultInfo fi = {}; GetPhysAddrResult res = {}; + ARMMMUFaultInfo local_fi, *fi; int ret; /* + * Allow S1_ptw_translate to see any fault generated here. + * Since this may recurse, read and clear. + */ + fi = cpu->env.tlb_fi; + if (fi) { + cpu->env.tlb_fi = NULL; + } else { + fi = memset(&local_fi, 0, sizeof(local_fi)); + } + + /* * Walk the page table and (if the mapping exists) add the page * to the TLB. On success, return true. Otherwise, if probing, * return false. Otherwise populate fsr with ARM DFSR/IFSR fault @@ -220,7 +231,7 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size, */ ret = get_phys_addr(&cpu->env, address, access_type, core_to_arm_mmu_idx(&cpu->env, mmu_idx), - &res, &fi); + &res, fi); if (likely(!ret)) { /* * Map a single [sub]page. Regions smaller than our declared @@ -242,7 +253,7 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size, } else { /* now we have a real cpu fault */ cpu_restore_state(cs, retaddr, true); - arm_deliver_fault(cpu, address, access_type, mmu_idx, &fi); + arm_deliver_fault(cpu, address, access_type, mmu_idx, fi); } } #else |