We are required to skip DB update for AT instructions, and we are allowed to skip AF updates. Choose to skip both.
Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- target/arm/ptw.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 1866c494ef..efbad7af1f 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -58,6 +58,12 @@ typedef struct S1Translate { * and will not change the state of the softmmu TLBs. */ 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. @@ -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 = {}; -- 2.43.0