git: 113bd64cdf4e - releng/13.0 - pmap: Fix largemap restart checks in the kernel_maps sysctl handler
Mark Johnston
markj at FreeBSD.org
Mon Mar 1 00:33:12 UTC 2021
The branch releng/13.0 has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=113bd64cdf4ef3f54fffcd9874ae7ec07afd882e
commit 113bd64cdf4ef3f54fffcd9874ae7ec07afd882e
Author: Mark Johnston <markj at FreeBSD.org>
AuthorDate: 2021-02-25 23:49:47 +0000
Commit: Mark Johnston <markj at FreeBSD.org>
CommitDate: 2021-03-01 00:32:58 +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.
Approved by: re (gjb)
Reported by: rpokala
Reviewed by: kib
Tested by: rpokala
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D28922
(cherry picked from commit aac25e222525780db8939d07a594d3e090c0a148)
(cherry picked from commit 5966aae9c7c25707c785ec056cb8462a037a480e)
---
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 0e1d1c02d1fc..bd23fd176e88 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -11349,9 +11349,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,
@@ -11360,6 +11357,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++) {
@@ -11371,9 +11377,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,
@@ -11382,6 +11385,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-branches
mailing list