Weaken assertions in pmap_l1_to_l2() and pmap_l2_to_l3().

pmap_update_entry() will temporarily clear the valid bit of page table
entries in order to satisfy the arm64 pmap's break-before-make
constraint.  pmap_kextract() may operate concurrently on kernel page
table pages, introducing windows where the assertions added in r365879
may fail incorrectly since they implicitly assert that the valid bit is
set.  Modify the assertions to handle this.

Reviewed by:	andrew, mmel (previous version)
Reviewed by:	alc, kib
Reported by:	mmel, scottph
MFC with:	r365879
This commit is contained in:
Mark Johnston 2020-09-21 22:19:21 +00:00
parent 26a3bf76c9
commit a9cf0eebb3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=365976

View File

@ -438,8 +438,15 @@ pmap_l1_to_l2(pd_entry_t *l1p, vm_offset_t va)
pd_entry_t l1, *l2p;
l1 = pmap_load(l1p);
KASSERT((l1 & ATTR_DESCR_MASK) == L1_TABLE,
("%s: L1 entry %#lx is a leaf", __func__, l1));
/*
* The valid bit may be clear if pmap_update_entry() is concurrently
* modifying the entry, so for KVA only the entry type may be checked.
*/
KASSERT(va >= VM_MAX_USER_ADDRESS || (l1 & ATTR_DESCR_VALID) != 0,
("%s: L1 entry %#lx for %#lx is invalid", __func__, l1, va));
KASSERT((l1 & ATTR_DESCR_TYPE_MASK) == ATTR_DESCR_TYPE_TABLE,
("%s: L1 entry %#lx for %#lx is a leaf", __func__, l1, va));
l2p = (pd_entry_t *)PHYS_TO_DMAP(l1 & ~ATTR_MASK);
return (&l2p[pmap_l2_index(va)]);
}
@ -463,8 +470,15 @@ pmap_l2_to_l3(pd_entry_t *l2p, vm_offset_t va)
pt_entry_t *l3p;
l2 = pmap_load(l2p);
KASSERT((l2 & ATTR_DESCR_MASK) == L2_TABLE,
("%s: L2 entry %#lx is a leaf", __func__, l2));
/*
* The valid bit may be clear if pmap_update_entry() is concurrently
* modifying the entry, so for KVA only the entry type may be checked.
*/
KASSERT(va >= VM_MAX_USER_ADDRESS || (l2 & ATTR_DESCR_VALID) != 0,
("%s: L2 entry %#lx for %#lx is invalid", __func__, l2, va));
KASSERT((l2 & ATTR_DESCR_TYPE_MASK) == ATTR_DESCR_TYPE_TABLE,
("%s: L2 entry %#lx for %#lx is a leaf", __func__, l2, va));
l3p = (pt_entry_t *)PHYS_TO_DMAP(l2 & ~ATTR_MASK);
return (&l3p[pmap_l3_index(va)]);
}