diff options
| -rw-r--r-- | target/arm/ptw.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 8925c9a610..089eeff845 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -59,6 +59,12 @@ typedef struct S1Translate { */ bool in_debug; /* + * in_at: is this AccessType_AT? + * This is also set for debug, because at heart that is also + * an address translation, and simplifies a test. + */ + bool in_at; + /* * If this is stage 2 of a stage 1+2 page table walk, then this must * be true if stage 1 is an EL0 access; otherwise this is ignored. * Stage 2 is indicated by in_mmu_idx set to ARMMMUIdx_Stage2{,_S}. @@ -1929,7 +1935,12 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, descaddr &= ~(hwaddr)(page_size - 1); descaddr |= (address & (page_size - 1)); - if (likely(!ptw->in_debug)) { + /* + * For AccessType_AT, DB is not updated (AArch64.SetDirtyFlag), + * and it is IMPLEMENTATION DEFINED whether AF is updated + * (AArch64.SetAccessFlag; qemu chooses to not update). + */ + if (likely(!ptw->in_at)) { /* * Access flag. * If HA is enabled, prepare to update the descriptor below. @@ -3553,6 +3564,7 @@ bool get_phys_addr_for_at(CPUARMState *env, vaddr address, S1Translate ptw = { .in_mmu_idx = mmu_idx, .in_space = space, + .in_at = true, .in_prot_check = prot_check, }; /* @@ -3653,6 +3665,7 @@ static hwaddr arm_cpu_get_phys_page(CPUARMState *env, vaddr addr, .in_mmu_idx = mmu_idx, .in_space = arm_mmu_idx_to_security_space(env, mmu_idx), .in_debug = true, + .in_at = true, .in_prot_check = 0, }; GetPhysAddrResult res = {}; |