svn commit: r362034 - head/sys/powerpc/booke

Justin Hibbits jhibbits at FreeBSD.org
Wed Jun 10 23:03:36 UTC 2020


Author: jhibbits
Date: Wed Jun 10 23:03:35 2020
New Revision: 362034
URL: https://svnweb.freebsd.org/changeset/base/362034

Log:
  powerpc/pmap: Fix pte_find_next() iterators for booke64 pmap
  
  After r361988 fixed the reference count leak on booke64, it became possible
  for an iteration somewhere in the middle of a page to become stale, with the
  page vanishing (correctly) due to all PTEs on that page going away.
  pte_find_next() would start at that iterator, and move along 'higher' order
  directory pages until it finds a valid one, without zeroing out the lower
  order pages.  For instance:
  
  	/* Find next pte at or above 0x10002000. */
  	pte = pte_find_next(pmap, &(0x10002000));
  	pte_remove(pmap, pte);
  	/* This pte was the last reference in the page table page, page is
  	 * gone.
  	 */
  	pte = pte_find_next(pmap, 0x10002000);
  	/* pte_find_next will see 0x10002000's page is gone, and jump to the
  	 * next one, but starting iteration at the '0x2000' slot, skipping
  	 * 0x0000 and 0x1000.
  	 */
  
  This caused some processes, like git, to trip the KASSERT() in
  pmap_release().
  
  Fix this by zeroing all lower order iterators at each level.

Modified:
  head/sys/powerpc/booke/pmap_64.c

Modified: head/sys/powerpc/booke/pmap_64.c
==============================================================================
--- head/sys/powerpc/booke/pmap_64.c	Wed Jun 10 22:30:32 2020	(r362033)
+++ head/sys/powerpc/booke/pmap_64.c	Wed Jun 10 23:03:35 2020	(r362034)
@@ -220,12 +220,13 @@ pte_find_next(pmap_t pmap, vm_offset_t *pva)
 	k = PDIR_IDX(va);
 	l = PTBL_IDX(va);
 	pm_root = pmap->pm_root;
+
 	/* truncate the VA for later. */
 	va &= ~((1UL << (PG_ROOT_H + 1)) - 1);
-	for (; i < PG_ROOT_NENTRIES; i++, j = 0) {
+	for (; i < PG_ROOT_NENTRIES; i++, j = 0, k = 0, l = 0) {
 		if (pm_root[i] == 0)
 			continue;
-		for (; j < PDIR_L1_NENTRIES; j++, k = 0) {
+		for (; j < PDIR_L1_NENTRIES; j++, k = 0, l = 0) {
 			if (pm_root[i][j] == 0)
 				continue;
 			for (; k < PDIR_NENTRIES; k++, l = 0) {


More information about the svn-src-head mailing list