The branch releng/13.0 has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=113bd64cdf4ef3f54fffcd9874ae7ec07afd882e

commit 113bd64cdf4ef3f54fffcd9874ae7ec07afd882e
Author:     Mark Johnston <ma...@freebsd.org>
AuthorDate: 2021-02-25 23:49:47 +0000
Commit:     Mark Johnston <ma...@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++,
_______________________________________________
dev-commits-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"

Reply via email to