pmap_enter_{l2,pde}: correct the handling of an error case
When pmap_enter_object()'s call to pmap_enter_{l2,pde}() fails to create
a managed mapping within the kernel address space due to the inability
to allocate a PV entry, it needs to remove the kernel page table page
from the pmap's trie of idle page table pages. Previously, it did not.
Reviewed by: andrew, kib, markj
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D51353
This commit is contained in:
@@ -7561,6 +7561,9 @@ pmap_enter_pde(pmap_t pmap, vm_offset_t va, pd_entry_t newpde, u_int flags,
|
||||
PG_RW = pmap_rw_bit(pmap);
|
||||
KASSERT((newpde & (pmap_modified_bit(pmap) | PG_RW)) != PG_RW,
|
||||
("pmap_enter_pde: newpde is missing PG_M"));
|
||||
KASSERT((flags & (PMAP_ENTER_NOREPLACE | PMAP_ENTER_NORECLAIM)) !=
|
||||
PMAP_ENTER_NORECLAIM,
|
||||
("pmap_enter_pde: flags is missing PMAP_ENTER_NOREPLACE"));
|
||||
PG_V = pmap_valid_bit(pmap);
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
|
||||
@@ -7689,6 +7692,14 @@ pmap_enter_pde(pmap_t pmap, vm_offset_t va, pd_entry_t newpde, u_int flags,
|
||||
if (!pmap_pv_insert_pde(pmap, va, newpde, flags, lockp)) {
|
||||
if (pdpg != NULL)
|
||||
pmap_abort_ptp(pmap, va, pdpg);
|
||||
else {
|
||||
KASSERT(va >= VM_MAXUSER_ADDRESS &&
|
||||
(*pde & (PG_PS | PG_V)) == PG_V,
|
||||
("pmap_enter_pde: invalid kernel PDE"));
|
||||
mt = pmap_remove_pt_page(pmap, va);
|
||||
KASSERT(mt != NULL,
|
||||
("pmap_enter_pde: missing kernel PTP"));
|
||||
}
|
||||
if (uwptpg != NULL) {
|
||||
mt = pmap_remove_pt_page(pmap, va);
|
||||
KASSERT(mt == uwptpg,
|
||||
|
||||
@@ -5709,6 +5709,9 @@ pmap_enter_l2(pmap_t pmap, vm_offset_t va, pd_entry_t new_l2, u_int flags,
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
KASSERT(ADDR_IS_CANONICAL(va),
|
||||
("%s: Address not in canonical form: %lx", __func__, va));
|
||||
KASSERT((flags & (PMAP_ENTER_NOREPLACE | PMAP_ENTER_NORECLAIM)) !=
|
||||
PMAP_ENTER_NORECLAIM,
|
||||
("pmap_enter_l2: flags is missing PMAP_ENTER_NOREPLACE"));
|
||||
|
||||
if ((l2 = pmap_alloc_l2(pmap, va, &l2pg, (flags &
|
||||
PMAP_ENTER_NOSLEEP) != 0 ? NULL : lockp)) == NULL) {
|
||||
@@ -5828,6 +5831,15 @@ pmap_enter_l2(pmap_t pmap, vm_offset_t va, pd_entry_t new_l2, u_int flags,
|
||||
if (!pmap_pv_insert_l2(pmap, va, new_l2, flags, lockp)) {
|
||||
if (l2pg != NULL)
|
||||
pmap_abort_ptp(pmap, va, l2pg);
|
||||
else {
|
||||
KASSERT(ADDR_IS_KERNEL(va) &&
|
||||
(pmap_load(l2) & ATTR_DESCR_MASK) ==
|
||||
L2_TABLE,
|
||||
("pmap_enter_l2: invalid kernel L2E"));
|
||||
mt = pmap_remove_pt_page(pmap, va);
|
||||
KASSERT(mt != NULL,
|
||||
("pmap_enter_l2: missing kernel PTP"));
|
||||
}
|
||||
if (uwptpg != NULL) {
|
||||
mt = pmap_remove_pt_page(pmap, va);
|
||||
KASSERT(mt == uwptpg,
|
||||
|
||||
Reference in New Issue
Block a user