diff options
Diffstat (limited to 'target/arm/tlb_helper.c')
| -rw-r--r-- | target/arm/tlb_helper.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c index 49601394ec..69b0dc69df 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 @@ -231,10 +242,9 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size, res.f.phys_addr &= TARGET_PAGE_MASK; address &= TARGET_PAGE_MASK; } - /* Notice and record tagged memory. */ - if (cpu_isar_feature(aa64_mte, cpu) && res.cacheattrs.attrs == 0xf0) { - arm_tlb_mte_tagged(&res.f.attrs) = true; - } + + res.f.pte_attrs = res.cacheattrs.attrs; + res.f.shareability = res.cacheattrs.shareability; tlb_set_page_full(cs, mmu_idx, address, &res.f); return true; @@ -243,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 |