Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 20 Nov 2018 16:35:54 +0000 (UTC)
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r340680 - stable/12/sys/arm64/arm64
Message-ID:  <201811201635.wAKGZsnc084578@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: markj
Date: Tue Nov 20 16:35:53 2018
New Revision: 340680
URL: https://svnweb.freebsd.org/changeset/base/340680

Log:
  MFC r340678:
  Handle kernel superpage mappings in pmap_remove_l2().

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

Modified: stable/12/sys/arm64/arm64/pmap.c
==============================================================================
--- stable/12/sys/arm64/arm64/pmap.c	Tue Nov 20 15:14:30 2018	(r340679)
+++ stable/12/sys/arm64/arm64/pmap.c	Tue Nov 20 16:35:53 2018	(r340680)
@@ -2382,8 +2382,40 @@ pmap_pv_insert_l2(pmap_t pmap, vm_offset_t va, pd_entr
 	return (true);
 }
 
+static void
+pmap_remove_kernel_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_t va)
+{
+	pt_entry_t newl2, oldl2;
+	vm_page_t ml3;
+	vm_paddr_t ml3pa;
+
+	KASSERT(!VIRT_IN_DMAP(va), ("removing direct mapping of %#lx", va));
+	KASSERT(pmap == kernel_pmap, ("pmap %p is not kernel_pmap", pmap));
+	PMAP_LOCK_ASSERT(pmap, MA_OWNED);
+
+	ml3 = pmap_remove_pt_page(pmap, va);
+	if (ml3 == NULL)
+		panic("pmap_remove_kernel_l2: Missing pt page");
+
+	ml3pa = VM_PAGE_TO_PHYS(ml3);
+	newl2 = ml3pa | L2_TABLE;
+
+	/*
+	 * Initialize the page table page.
+	 */
+	pagezero((void *)PHYS_TO_DMAP(ml3pa));
+
+	/*
+	 * Demote the mapping.  The caller must have already invalidated the
+	 * mapping (i.e., the "break" in break-before-make).
+	 */
+	oldl2 = pmap_load_store(l2, newl2);
+	KASSERT(oldl2 == 0, ("%s: found existing mapping at %p: %#lx",
+	    __func__, l2, oldl2));
+}
+
 /*
- * pmap_remove_l2: do the things to unmap a level 2 superpage in a process
+ * pmap_remove_l2: Do the things to unmap a level 2 superpage.
  */
 static int
 pmap_remove_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_t sva,
@@ -2419,16 +2451,18 @@ pmap_remove_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_
 				vm_page_aflag_clear(m, PGA_WRITEABLE);
 		}
 	}
-	KASSERT(pmap != kernel_pmap,
-	    ("Attempting to remove an l2 kernel page"));
-	ml3 = pmap_remove_pt_page(pmap, sva);
-	if (ml3 != NULL) {
-		pmap_resident_count_dec(pmap, 1);
-		KASSERT(ml3->wire_count == NL3PG,
-		    ("pmap_remove_l2: l3 page wire count error"));
-		ml3->wire_count = 1;
-		vm_page_unwire_noq(ml3);
-		pmap_add_delayed_free_list(ml3, free, FALSE);
+	if (pmap == kernel_pmap) {
+		pmap_remove_kernel_l2(pmap, l2, sva);
+	} else {
+		ml3 = pmap_remove_pt_page(pmap, sva);
+		if (ml3 != NULL) {
+			pmap_resident_count_dec(pmap, 1);
+			KASSERT(ml3->wire_count == NL3PG,
+			    ("pmap_remove_l2: l3 page wire count error"));
+			ml3->wire_count = 1;
+			vm_page_unwire_noq(ml3);
+			pmap_add_delayed_free_list(ml3, free, FALSE);
+		}
 	}
 	return (pmap_unuse_pt(pmap, sva, l1e, free));
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201811201635.wAKGZsnc084578>