aboutsummaryrefslogtreecommitdiff
path: root/target/arm/tlb_helper.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2022-10-10 20:18:57 -0700
committerPeter Maydell <peter.maydell@linaro.org>2022-10-20 11:27:49 +0100
commitf3639a64f602ea5c1436eb9c9b89f42028e3a4a8 (patch)
tree23fbc572beedae7856fc430988a8012b310d8615 /target/arm/tlb_helper.c
parent4e7a2c9860eabd21376da522ef11e6b39fe36f85 (diff)
downloadqemu-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.c17
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