From 7992921bfe49bd9719c06159e199f41ef057914e Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Tue, 8 Oct 2019 14:54:35 +0000 Subject: [PATCH] Clear PGA_WRITEABLE in riscv's pmap_remove_l3(). pmap_remove_l3() may remove the last mapping of a page, in which case it must clear PGA_WRITEABLE. Reported by: Jenkins, via lwhsu MFC after: 1 week Sponsored by: The FreeBSD Foundation --- sys/riscv/riscv/pmap.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sys/riscv/riscv/pmap.c b/sys/riscv/riscv/pmap.c index 4de5f48509c1..cb88ba49ee59 100644 --- a/sys/riscv/riscv/pmap.c +++ b/sys/riscv/riscv/pmap.c @@ -2085,6 +2085,7 @@ static int pmap_remove_l3(pmap_t pmap, pt_entry_t *l3, vm_offset_t va, pd_entry_t l2e, struct spglist *free, struct rwlock **lockp) { + struct md_page *pvh; pt_entry_t old_l3; vm_paddr_t phys; vm_page_t m; @@ -2104,6 +2105,12 @@ pmap_remove_l3(pmap_t pmap, pt_entry_t *l3, vm_offset_t va, vm_page_aflag_set(m, PGA_REFERENCED); CHANGE_PV_LIST_LOCK_TO_VM_PAGE(lockp, m); pmap_pvh_free(&m->md, pmap, va); + if (TAILQ_EMPTY(&m->md.pv_list) && + (m->flags & PG_FICTITIOUS) == 0) { + pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m)); + if (TAILQ_EMPTY(&pvh->pv_list)) + vm_page_aflag_clear(m, PGA_WRITEABLE); + } } return (pmap_unuse_pt(pmap, va, l2e, free));