Date: Mon, 1 Mar 2021 00:33:12 GMT From: Mark Johnston <markj@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 113bd64cdf4e - releng/13.0 - pmap: Fix largemap restart checks in the kernel_maps sysctl handler Message-ID: <202103010033.1210XCYE072016@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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@FreeBSD.org> AuthorDate: 2021-02-25 23:49:47 +0000 Commit: Mark Johnston <markj@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++,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202103010033.1210XCYE072016>