Handle a race between pmap_kextract() and pmap_promote_pde(). This race

caused ZFS to crash when restoring a snapshot with superpage promotion
enabled.

Reported by:	kris
This commit is contained in:
Alan Cox 2008-07-13 18:19:53 +00:00
parent e7e0618629
commit cfcbf8c6fd
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=180498

View File

@ -1041,17 +1041,25 @@ pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
vm_paddr_t
pmap_kextract(vm_offset_t va)
{
pd_entry_t *pde;
pd_entry_t pde;
vm_paddr_t pa;
if (va >= DMAP_MIN_ADDRESS && va < DMAP_MAX_ADDRESS) {
pa = DMAP_TO_PHYS(va);
} else {
pde = vtopde(va);
if (*pde & PG_PS) {
pa = (*pde & PG_PS_FRAME) | (va & PDRMASK);
pde = *vtopde(va);
if (pde & PG_PS) {
pa = (pde & PG_PS_FRAME) | (va & PDRMASK);
} else {
pa = *vtopte(va);
/*
* Beware of a concurrent promotion that changes the
* PDE at this point! For example, vtopte() must not
* be used to access the PTE because it would use the
* new PDE. It is, however, safe to use the old PDE
* because the page table page is preserved by the
* promotion.
*/
pa = *pmap_pde_to_pte(&pde, va);
pa = (pa & PG_FRAME) | (va & PAGE_MASK);
}
}