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,12 +9309,11 @@ 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_A); - else + } else goto maybe_invlrng; + atomic_clear_long(pte, + PG_M | ((*pte & PG_W) == 0 ? PG_A : 0)); if ((*pte & PG_G) != 0) { if (va == va_next) va = sva;