pmap: Fix largemap restart checks in the kernel_maps sysctl handler
The purpose of these checks is to ensure that the address of the next-level page table page is valid, since nothing is synchronizing with a concurrent update of the large map and large map PTPs are freed to the system. However, if PG_PS is set, there is no next level. Reported by: rpokala Reviewed by: kib Tested by: rpokala MFC after: 3 days Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D28922
This commit is contained in:
parent
90972f0402
commit
aac25e2225
@ -11348,9 +11348,6 @@ sysctl_kmaps(SYSCTL_HANDLER_ARGS)
|
||||
continue;
|
||||
}
|
||||
pa = pdpe & PG_FRAME;
|
||||
if (PMAP_ADDRESS_IN_LARGEMAP(sva) &&
|
||||
vm_phys_paddr_to_vm_page(pa) == NULL)
|
||||
goto restart;
|
||||
if ((pdpe & PG_PS) != 0) {
|
||||
sva = rounddown2(sva, NBPDP);
|
||||
sysctl_kmaps_check(sb, &range, sva, pml4e, pdpe,
|
||||
@ -11359,6 +11356,15 @@ sysctl_kmaps(SYSCTL_HANDLER_ARGS)
|
||||
sva += NBPDP;
|
||||
continue;
|
||||
}
|
||||
if (PMAP_ADDRESS_IN_LARGEMAP(sva) &&
|
||||
vm_phys_paddr_to_vm_page(pa) == NULL) {
|
||||
/*
|
||||
* Page table pages for the large map may be
|
||||
* freed. Validate the next-level address
|
||||
* before descending.
|
||||
*/
|
||||
goto restart;
|
||||
}
|
||||
pd = (pd_entry_t *)PHYS_TO_DMAP(pa);
|
||||
|
||||
for (k = pmap_pde_index(sva); k < NPDEPG; k++) {
|
||||
@ -11370,9 +11376,6 @@ sysctl_kmaps(SYSCTL_HANDLER_ARGS)
|
||||
continue;
|
||||
}
|
||||
pa = pde & PG_FRAME;
|
||||
if (PMAP_ADDRESS_IN_LARGEMAP(sva) &&
|
||||
vm_phys_paddr_to_vm_page(pa) == NULL)
|
||||
goto restart;
|
||||
if ((pde & PG_PS) != 0) {
|
||||
sva = rounddown2(sva, NBPDR);
|
||||
sysctl_kmaps_check(sb, &range, sva,
|
||||
@ -11381,6 +11384,15 @@ sysctl_kmaps(SYSCTL_HANDLER_ARGS)
|
||||
sva += NBPDR;
|
||||
continue;
|
||||
}
|
||||
if (PMAP_ADDRESS_IN_LARGEMAP(sva) &&
|
||||
vm_phys_paddr_to_vm_page(pa) == NULL) {
|
||||
/*
|
||||
* Page table pages for the large map
|
||||
* may be freed. Validate the
|
||||
* next-level address before descending.
|
||||
*/
|
||||
goto restart;
|
||||
}
|
||||
pt = (pt_entry_t *)PHYS_TO_DMAP(pa);
|
||||
|
||||
for (l = pmap_pte_index(sva); l < NPTEPG; l++,
|
||||
|
Loading…
Reference in New Issue
Block a user