Author: neel
Date: Wed Jul  3 23:21:25 2013
New Revision: 252646
URL: http://svnweb.freebsd.org/changeset/base/252646

Log:
  If a superpage mapping is being removed then we need to ignore the PG_PDE_PAT
  bit when looking up the vm_page associated with the superpage's physical
  address.
  
  If the caching attribute for the mapping is write combining or write protected
  then the PG_PDE_PAT bit will be set and thus cause an 'off-by-one' error
  when looking up the vm_page.
  
  Fix this by using the PG_PS_FRAME mask to compute the physical address for
  a superpage mapping instead of PG_FRAME.
  
  This is a theoretical issue at this point since non-writeback attributes are
  currently used only for fictitious mappings and fictitious mappings are not
  subject to promotion.
  
  Discussed with:       alc, kib
  MFC after:    2 weeks

Modified:
  head/sys/amd64/amd64/pmap.c

Modified: head/sys/amd64/amd64/pmap.c
==============================================================================
--- head/sys/amd64/amd64/pmap.c Wed Jul  3 23:19:57 2013        (r252645)
+++ head/sys/amd64/amd64/pmap.c Wed Jul  3 23:21:25 2013        (r252646)
@@ -4400,6 +4400,7 @@ pmap_remove_pages(pmap_t pmap)
        int64_t bit;
        uint64_t inuse, bitmask;
        int allfree, field, freed, idx;
+       vm_paddr_t pa;
 
        if (pmap != PCPU_GET(curpmap)) {
                printf("warning: pmap_remove_pages called with non-current 
pmap\n");
@@ -4429,7 +4430,7 @@ pmap_remove_pages(pmap_t pmap)
                                        pte = (pt_entry_t *)PHYS_TO_DMAP(tpte &
                                            PG_FRAME);
                                        pte = &pte[pmap_pte_index(pv->pv_va)];
-                                       tpte = *pte & ~PG_PTE_PAT;
+                                       tpte = *pte;
                                }
                                if ((tpte & PG_V) == 0) {
                                        panic("bad pte va %lx pte %lx",
@@ -4444,8 +4445,13 @@ pmap_remove_pages(pmap_t pmap)
                                        continue;
                                }
 
-                               m = PHYS_TO_VM_PAGE(tpte & PG_FRAME);
-                               KASSERT(m->phys_addr == (tpte & PG_FRAME),
+                               if (tpte & PG_PS)
+                                       pa = tpte & PG_PS_FRAME;
+                               else
+                                       pa = tpte & PG_FRAME;
+
+                               m = PHYS_TO_VM_PAGE(pa);
+                               KASSERT(m->phys_addr == pa,
                                    ("vm_page_t %p phys_addr mismatch %016jx 
%016jx",
                                    m, (uintmax_t)m->phys_addr,
                                    (uintmax_t)tpte));
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to