git: aac25e222525 - main - pmap: Fix largemap restart checks in the kernel_maps sysctl handler
Mark Johnston
markj at FreeBSD.org
Thu Feb 25 23:49:57 UTC 2021
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=aac25e222525780db8939d07a594d3e090c0a148
commit aac25e222525780db8939d07a594d3e090c0a148
Author: Mark Johnston <markj at FreeBSD.org>
AuthorDate: 2021-02-25 23:49:47 +0000
Commit: Mark Johnston <markj at FreeBSD.org>
CommitDate: 2021-02-25 23:49:47 +0000
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
---
sys/amd64/amd64/pmap.c | 24 ++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 7dddeb3ee4ea..f509c40e760a 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -11348,9 +11348,6 @@ restart:
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 @@ restart:
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 @@ restart:
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 @@ restart:
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++,
More information about the dev-commits-src-all
mailing list