git: 9d1aef84021f - main - riscv: handle superpage in pmap_enter_quick_locked()

From: Mitchell Horne <mhorne_at_FreeBSD.org>
Date: Thu, 06 Oct 2022 22:05:39 UTC
The branch main has been updated by mhorne:

URL: https://cgit.FreeBSD.org/src/commit/?id=9d1aef84021f4e99d37f4e9149a8799c3d9e5e03

commit 9d1aef84021f4e99d37f4e9149a8799c3d9e5e03
Author:     Mitchell Horne <mhorne@FreeBSD.org>
AuthorDate: 2022-10-05 17:11:02 +0000
Commit:     Mitchell Horne <mhorne@FreeBSD.org>
CommitDate: 2022-10-06 22:02:38 +0000

    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
---
 sys/riscv/riscv/pmap.c | 2 ++
 1 file changed, 2 insertions(+)

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++;