- Introduce a specific function, pmap_remove_kernel_pde, for removing
huge pages in the kernel's address space. This works around several asserts from pmap_demote_pde_locked that did not apply and gave false warnings. Discovered by: pho Reviewed by: alc Sponsored by: EMC / Isilon Storage Division
This commit is contained in:
parent
66bacd7e17
commit
2c0b86b48f
@ -2794,6 +2794,44 @@ pmap_demote_pde_locked(pmap_t pmap, pd_entry_t *pde, vm_offset_t va,
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* pmap_remove_kernel_pde: Remove a kernel superpage mapping.
|
||||
*/
|
||||
static void
|
||||
pmap_remove_kernel_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va)
|
||||
{
|
||||
pd_entry_t newpde;
|
||||
vm_paddr_t mptepa;
|
||||
vm_page_t mpte;
|
||||
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
mpte = pmap_lookup_pt_page(pmap, va);
|
||||
if (mpte == NULL)
|
||||
panic("pmap_remove_kernel_pde: Missing pt page.");
|
||||
|
||||
pmap_remove_pt_page(pmap, mpte);
|
||||
mptepa = VM_PAGE_TO_PHYS(mpte);
|
||||
newpde = mptepa | PG_M | PG_A | PG_RW | PG_V;
|
||||
|
||||
/*
|
||||
* Initialize the page table page.
|
||||
*/
|
||||
pagezero((void *)PHYS_TO_DMAP(mptepa));
|
||||
|
||||
/*
|
||||
* Demote the mapping.
|
||||
*/
|
||||
if (workaround_erratum383)
|
||||
pmap_update_pde(pmap, va, pde, newpde);
|
||||
else
|
||||
pde_store(pde, newpde);
|
||||
|
||||
/*
|
||||
* Invalidate a stale recursive mapping of the page table page.
|
||||
*/
|
||||
pmap_invalidate_page(pmap, (vm_offset_t)vtopte(va));
|
||||
}
|
||||
|
||||
/*
|
||||
* pmap_remove_pde: do the things to unmap a superpage in a process
|
||||
*/
|
||||
@ -2837,8 +2875,7 @@ pmap_remove_pde(pmap_t pmap, pd_entry_t *pdq, vm_offset_t sva,
|
||||
}
|
||||
}
|
||||
if (pmap == kernel_pmap) {
|
||||
if (!pmap_demote_pde_locked(pmap, pdq, sva, lockp))
|
||||
panic("pmap_remove_pde: failed demotion");
|
||||
pmap_remove_kernel_pde(pmap, pdq, sva);
|
||||
} else {
|
||||
mpte = pmap_lookup_pt_page(pmap, sva);
|
||||
if (mpte != NULL) {
|
||||
|
@ -2772,6 +2772,44 @@ pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va)
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes a 2- or 4MB page mapping from the kernel pmap.
|
||||
*/
|
||||
static void
|
||||
pmap_remove_kernel_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va)
|
||||
{
|
||||
pd_entry_t newpde;
|
||||
vm_paddr_t mptepa;
|
||||
vm_page_t mpte;
|
||||
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
mpte = pmap_lookup_pt_page(pmap, va);
|
||||
if (mpte == NULL)
|
||||
panic("pmap_remove_kernel_pde: Missing pt page.");
|
||||
|
||||
pmap_remove_pt_page(pmap, mpte);
|
||||
mptepa = VM_PAGE_TO_PHYS(mpte);
|
||||
newpde = mptepa | PG_M | PG_A | PG_RW | PG_V;
|
||||
|
||||
/*
|
||||
* Initialize the page table page.
|
||||
*/
|
||||
pagezero((void *)&KPTmap[i386_btop(trunc_4mpage(va))]);
|
||||
|
||||
/*
|
||||
* Remove the mapping.
|
||||
*/
|
||||
if (workaround_erratum383)
|
||||
pmap_update_pde(pmap, va, pde, newpde);
|
||||
else
|
||||
pmap_kenter_pde(va, newpde);
|
||||
|
||||
/*
|
||||
* Invalidate the recursive mapping of the page table page.
|
||||
*/
|
||||
pmap_invalidate_page(pmap, (vm_offset_t)vtopte(va));
|
||||
}
|
||||
|
||||
/*
|
||||
* pmap_remove_pde: do the things to unmap a superpage in a process
|
||||
*/
|
||||
@ -2814,8 +2852,7 @@ pmap_remove_pde(pmap_t pmap, pd_entry_t *pdq, vm_offset_t sva,
|
||||
}
|
||||
}
|
||||
if (pmap == kernel_pmap) {
|
||||
if (!pmap_demote_pde(pmap, pdq, sva))
|
||||
panic("pmap_remove_pde: failed demotion");
|
||||
pmap_remove_kernel_pde(pmap, pdq, sva);
|
||||
} else {
|
||||
mpte = pmap_lookup_pt_page(pmap, sva);
|
||||
if (mpte != NULL) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user