diff --git a/sys/riscv/riscv/pmap.c b/sys/riscv/riscv/pmap.c index e3122beaba87..0974583eac28 100644 --- a/sys/riscv/riscv/pmap.c +++ b/sys/riscv/riscv/pmap.c @@ -2054,7 +2054,7 @@ pmap_remove_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_t sva, vm_page_aflag_set(m, PGA_REFERENCED); if (TAILQ_EMPTY(&m->md.pv_list) && TAILQ_EMPTY(&pvh->pv_list)) - vm_page_aflag_clear(m, PGA_WRITEABLE); + vm_page_aflag_clear(m, PGA_WRITEABLE | PGA_EXECUTABLE); } } if (pmap == kernel_pmap) { @@ -2274,7 +2274,7 @@ pmap_remove_all(vm_page_t m) free_pv_entry(pmap, pv); PMAP_UNLOCK(pmap); } - vm_page_aflag_clear(m, PGA_WRITEABLE); + vm_page_aflag_clear(m, PGA_WRITEABLE | PGA_EXECUTABLE); rw_wunlock(&pvh_global_lock); vm_page_free_pages_toq(&free, false); } @@ -2817,9 +2817,9 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, ("pmap_enter: no PV entry for %#lx", va)); if ((new_l3 & PTE_SW_MANAGED) == 0) free_pv_entry(pmap, pv); - if ((om->aflags & PGA_WRITEABLE) != 0 && + if ((om->aflags & (PGA_WRITEABLE | PGA_EXECUTABLE)) != 0 && TAILQ_EMPTY(&om->md.pv_list)) - vm_page_aflag_clear(om, PGA_WRITEABLE); + vm_page_aflag_clear(om, PGA_WRITEABLE | PGA_EXECUTABLE)); } pmap_invalidate_page(pmap, va); orig_l3 = 0; @@ -2851,8 +2851,11 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, * Sync the i-cache on all harts before updating the PTE * if the new PTE is executable. */ - if (prot & VM_PROT_EXECUTE) + if ((prot & VM_PROT_EXECUTE) != 0 && + (m->aflags & PGA_EXECUTABLE) == 0) { + vm_page_aflag_set(m, PGA_EXECUTABLE); pmap_sync_icache(pmap, va, PAGE_SIZE); + } /* * Update the L3 entry. @@ -3204,8 +3207,11 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, * Sync the i-cache on all harts before updating the PTE * if the new PTE is executable. */ - if (prot & VM_PROT_EXECUTE) + if ((prot & VM_PROT_EXECUTE) == 0 && + (m->aflags & PGA_EXECUTABLE) == 0) { + vm_page_aflag_set(m, PGA_EXECUTABLE); pmap_sync_icache(pmap, va, PAGE_SIZE); + } pmap_store(l3, newl3); @@ -3550,8 +3556,8 @@ pmap_remove_pages_pv(pmap_t pmap, vm_page_t m, pv_entry_t pv, if (TAILQ_EMPTY(&pvh->pv_list)) { for (mt = m; mt < &m[Ln_ENTRIES]; mt++) if (TAILQ_EMPTY(&mt->md.pv_list) && - (mt->aflags & PGA_WRITEABLE) != 0) - vm_page_aflag_clear(mt, PGA_WRITEABLE); + (mt->aflags & (PGA_WRITEABLE | PGA_EXECUTABLE)) != 0) + vm_page_aflag_clear(mt, PGA_WRITEABLE | PGA_EXECUTABLE); } mpte = pmap_remove_pt_page(pmap, pv->pv_va); if (mpte != NULL) { @@ -3566,10 +3572,10 @@ pmap_remove_pages_pv(pmap_t pmap, vm_page_t m, pv_entry_t pv, TAILQ_REMOVE(&m->md.pv_list, pv, pv_next); m->md.pv_gen++; if (TAILQ_EMPTY(&m->md.pv_list) && - (m->aflags & PGA_WRITEABLE) != 0) { + (m->aflags & (PGA_WRITEABLE | PGA_EXECUTABLE)) != 0) { pvh = pa_to_pvh(m->phys_addr); if (TAILQ_EMPTY(&pvh->pv_list)) - vm_page_aflag_clear(m, PGA_WRITEABLE); + vm_page_aflag_clear(m, PGA_WRITEABLE | PGA_EXECUTABLE); } } }