git: 6c1d6d4c7ffd - main - i386: Add a leaf PTP when pmap_enter(psind=1) creates a wired mapping
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 09 Oct 2023 00:47:14 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=6c1d6d4c7ffd81d66acd4869cfe596398df301b7
commit 6c1d6d4c7ffd81d66acd4869cfe596398df301b7
Author: Bojan Novković <bojan.novkovic@fer.hr>
AuthorDate: 2023-10-09 00:32:35 +0000
Commit: Mark Johnston <markj@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);