aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchell Horne <mhorne@FreeBSD.org>2022-10-05 17:11:02 +0000
committerMitchell Horne <mhorne@FreeBSD.org>2022-10-06 22:02:38 +0000
commit9d1aef84021f4e99d37f4e9149a8799c3d9e5e03 (patch)
tree4905e8ba0d72988a5519fd80fc2f53b92f084e1b
parent95b1c27069775dd969cd045888b4ea5aeb53cb7f (diff)
riscv: handle superpage in pmap_enter_quick_locked()
Previously, if pmap_enter_l2() was asked to re-map an existing superpage (the result of madvise(MADV_WILLNEED) on a mapped range), it could 'fail' to do so, falling back to trying pmap_enter_quick_locked() for each 4K virtual page. Because this function does not check if the l2 entry it finds is a superpage, it would proceed, sometimes resulting in the creation of false PV entries. If the relevant range was later munmap'ed, the system would panic during the process' exit in pmap_remove_pages(), while attempting to clean up the PV entries for mappings which no longer exist. Instead, we should return early in the presence of an existing superpage, as is done in other pmaps. PR: 266108 Reviewed by: markj, alc MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D36563
-rw-r--r--sys/riscv/riscv/pmap.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/sys/riscv/riscv/pmap.c b/sys/riscv/riscv/pmap.c
index 69f2a9ab1522..9f73a020d0f4 100644
--- a/sys/riscv/riscv/pmap.c
+++ b/sys/riscv/riscv/pmap.c
@@ -3383,6 +3383,8 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m,
* attempt fails, we don't retry. Instead, we give up.
*/
if (l2 != NULL && pmap_load(l2) != 0) {
+ if ((pmap_load(l2) & PTE_RWX) != 0)
+ return (NULL);
phys = PTE_TO_PHYS(pmap_load(l2));
mpte = PHYS_TO_VM_PAGE(phys);
mpte->ref_count++;