The branch main has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=6c1d6d4c7ffd81d66acd4869cfe596398df301b7

commit 6c1d6d4c7ffd81d66acd4869cfe596398df301b7
Author:     Bojan Novković <bojan.novko...@fer.hr>
AuthorDate: 2023-10-09 00:32:35 +0000
Commit:     Mark Johnston <ma...@freebsd.org>
CommitDate: 2023-10-09 00:40:44 +0000

    i386: Add a leaf PTP when pmap_enter(psind=1) creates a wired mapping
    
    Let pmap_enter_pde() create wired mappings.  In particular, allocate a
    leaf PTP for use during demotion.  This is a step towards reverting
    commit 64087fd7f372.
    
    Reviewed by:    alc, kib, markj
    Sponsored by:   Google, Inc. (GSoC 2023)
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D41635
---
 sys/i386/i386/pmap.c | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 2d19fc51dd53..6b839484e6c5 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -3973,12 +3973,11 @@ pmap_enter_pde(pmap_t pmap, vm_offset_t va, pd_entry_t 
newpde, u_int flags,
        struct spglist free;
        pd_entry_t oldpde, *pde;
        vm_page_t mt;
+       vm_page_t uwptpg;
 
        rw_assert(&pvh_global_lock, RA_WLOCKED);
        KASSERT((newpde & (PG_M | PG_RW)) != PG_RW,
            ("pmap_enter_pde: newpde is missing PG_M"));
-       KASSERT(pmap == kernel_pmap || (newpde & PG_W) == 0,
-           ("pmap_enter_pde: cannot create wired user mapping"));
        PMAP_LOCK_ASSERT(pmap, MA_OWNED);
        pde = pmap_pde(pmap, va);
        oldpde = *pde;
@@ -4028,11 +4027,40 @@ pmap_enter_pde(pmap_t pmap, vm_offset_t va, pd_entry_t 
newpde, u_int flags,
                                panic("pmap_enter_pde: trie insert failed");
                }
        }
+
+       /*
+        * Allocate a leaf ptpage for wired userspace pages.
+        */
+       uwptpg = NULL;
+       if ((newpde & PG_W) != 0 && pmap != kernel_pmap) {
+               uwptpg = vm_page_alloc_noobj(VM_ALLOC_WIRED);
+               if (uwptpg == NULL) {
+                       return (KERN_RESOURCE_SHORTAGE);
+               }
+               uwptpg->pindex = va >> PDRSHIFT;
+               if (pmap_insert_pt_page(pmap, uwptpg, true, false)) {
+                       vm_page_unwire_noq(uwptpg);
+                       vm_page_free(uwptpg);
+                       return (KERN_RESOURCE_SHORTAGE);
+               }
+               pmap->pm_stats.resident_count++;
+               uwptpg->ref_count = NPTEPG;
+       }
        if ((newpde & PG_MANAGED) != 0) {
                /*
                 * Abort this mapping if its PV entry could not be created.
                 */
                if (!pmap_pv_insert_pde(pmap, va, newpde, flags)) {
+                       if (uwptpg != NULL) {
+                               mt = pmap_remove_pt_page(pmap, va);
+                               KASSERT(mt == uwptpg,
+                                   ("removed pt page %p, expected %p", mt,
+                                   uwptpg));
+                               pmap->pm_stats.resident_count--;
+                               uwptpg->ref_count = 1;
+                               vm_page_unwire_noq(uwptpg);
+                               vm_page_free(uwptpg);
+                       }
                        CTR2(KTR_PMAP, "pmap_enter_pde: failure for va %#lx"
                            " in pmap %p", va, pmap);
                        return (KERN_RESOURCE_SHORTAGE);

Reply via email to