Author: kib
Date: Fri May 31 19:13:31 2019
New Revision: 348479
URL: https://svnweb.freebsd.org/changeset/base/348479

Log:
  MFC r348246:
  Fix a corner case in demotion of kernel mappings.

Modified:
  stable/12/sys/amd64/amd64/pmap.c
  stable/12/sys/i386/i386/pmap.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/amd64/amd64/pmap.c
==============================================================================
--- stable/12/sys/amd64/amd64/pmap.c    Fri May 31 19:09:56 2019        
(r348478)
+++ stable/12/sys/amd64/amd64/pmap.c    Fri May 31 19:13:31 2019        
(r348479)
@@ -4167,8 +4167,10 @@ pmap_demote_pde_locked(pmap_t pmap, pd_entry_t *pde, v
                            " in pmap %p", va, pmap);
                        return (FALSE);
                }
-               if (va < VM_MAXUSER_ADDRESS)
+               if (va < VM_MAXUSER_ADDRESS) {
+                       mpte->wire_count = NPTEPG;
                        pmap_resident_count_inc(pmap, 1);
+               }
        }
        mptepa = VM_PAGE_TO_PHYS(mpte);
        firstpte = (pt_entry_t *)PHYS_TO_DMAP(mptepa);
@@ -4181,12 +4183,12 @@ pmap_demote_pde_locked(pmap_t pmap, pd_entry_t *pde, v
        newpte = pmap_swap_pat(pmap, newpte);
 
        /*
-        * If the page table page is new, initialize it.
+        * If the page table page is not leftover from an earlier promotion,
+        * initialize it.
         */
-       if (mpte->wire_count == 1) {
-               mpte->wire_count = NPTEPG;
+       if ((oldpde & PG_PROMOTED) == 0)
                pmap_fill_ptp(firstpte, newpte);
-       }
+
        KASSERT((*firstpte & PG_FRAME) == (newpte & PG_FRAME),
            ("pmap_demote_pde: firstpte and newpte map different physical"
            " addresses"));

Modified: stable/12/sys/i386/i386/pmap.c
==============================================================================
--- stable/12/sys/i386/i386/pmap.c      Fri May 31 19:09:56 2019        
(r348478)
+++ stable/12/sys/i386/i386/pmap.c      Fri May 31 19:13:31 2019        
(r348479)
@@ -2845,8 +2845,10 @@ pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offse
                            " in pmap %p", va, pmap);
                        return (FALSE);
                }
-               if (pmap != kernel_pmap)
+               if (pmap != kernel_pmap) {
+                       mpte->wire_count = NPTEPG;
                        pmap->pm_stats.resident_count++;
+               }
        }
        mptepa = VM_PAGE_TO_PHYS(mpte);
 
@@ -2894,12 +2896,12 @@ pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offse
                newpte ^= PG_PDE_PAT | PG_PTE_PAT;
 
        /*
-        * If the page table page is new, initialize it.
+        * If the page table page is not leftover from an earlier promotion,
+        * initialize it.
         */
-       if (mpte->wire_count == 1) {
-               mpte->wire_count = NPTEPG;
+       if ((oldpde & PG_PROMOTED) == 0)
                pmap_fill_ptp(firstpte, newpte);
-       }
+
        KASSERT((*firstpte & PG_FRAME) == (newpte & PG_FRAME),
            ("pmap_demote_pde: firstpte and newpte map different physical"
            " addresses"));
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to