diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -9292,6 +9292,11 @@ va = va_next; for (pte = pmap_pde_to_pte(pde, sva); sva != va_next; pte++, sva += PAGE_SIZE) { + /* + * Avoid clearing the accessed bit for wired mappings. + * Superpage demotion assumes that a wired mapping is + * always accessed. + */ if ((*pte & (PG_MANAGED | PG_V)) != (PG_MANAGED | PG_V)) goto maybe_invlrng; else if ((*pte & (PG_M | PG_RW)) == (PG_M | PG_RW)) { @@ -9304,8 +9309,9 @@ m = PHYS_TO_VM_PAGE(*pte & PG_FRAME); vm_page_dirty(m); } - atomic_clear_long(pte, PG_M | PG_A); - } else if ((*pte & PG_A) != 0) + atomic_clear_long(pte, PG_M | + ((*pte & PG_W) == 0 ? PG_A : 0)); + } else if ((*pte & (PG_A | PG_W)) == PG_A) atomic_clear_long(pte, PG_A); else goto maybe_invlrng;