svn commit: r212658 - stable/8/sys/powerpc/aim

Nathan Whitehorn nwhitehorn at FreeBSD.org
Wed Sep 15 13:43:44 UTC 2010


Author: nwhitehorn
Date: Wed Sep 15 13:43:43 2010
New Revision: 212658
URL: http://svn.freebsd.org/changeset/base/212658

Log:
  MFC r211967,212044,212278,212322,212331:
  
  Fix a variety of race conditions and errors in VSID allocation in both
  the 32 and 64-bit PMAP modules, some dating back to the original PMAP
  import from NetBSD. This fixes a variety of potential crashes and memory
  corruption bugs, especially on SMP systems under heavy load.

Modified:
  stable/8/sys/powerpc/aim/mmu_oea.c
  stable/8/sys/powerpc/aim/mmu_oea64.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/powerpc/aim/mmu_oea.c
==============================================================================
--- stable/8/sys/powerpc/aim/mmu_oea.c	Wed Sep 15 11:05:41 2010	(r212657)
+++ stable/8/sys/powerpc/aim/mmu_oea.c	Wed Sep 15 13:43:43 2010	(r212658)
@@ -203,6 +203,7 @@ extern struct pmap ofw_pmap;
  * Lock for the pteg and pvo tables.
  */
 struct mtx	moea_table_mutex;
+struct mtx	moea_vsid_mutex;
 
 /* tlbie instruction synchronization */
 static struct mtx tlbie_mtx;
@@ -817,6 +818,7 @@ moea_bootstrap(mmu_t mmup, vm_offset_t k
 	 */
 	mtx_init(&moea_table_mutex, "pmap table", NULL, MTX_DEF |
 	    MTX_RECURSE);
+	mtx_init(&moea_vsid_mutex, "VSID table", NULL, MTX_DEF);
 
 	mtx_init(&tlbie_mtx, "tlbie", NULL, MTX_SPIN);
 
@@ -1535,6 +1537,7 @@ moea_pinit(mmu_t mmu, pmap_t pmap)
 	}
 	
 
+	mtx_lock(&moea_vsid_mutex);
 	/*
 	 * Allocate some segment registers for this pmap.
 	 */
@@ -1561,7 +1564,7 @@ moea_pinit(mmu_t mmu, pmap_t pmap)
 				entropy = (moea_vsidcontext >> 20);
 				continue;
 			}
-			i = ffs(~moea_vsid_bitmap[i]) - 1;
+			i = ffs(~moea_vsid_bitmap[n]) - 1;
 			mask = 1 << i;
 			hash &= 0xfffff & ~(VSID_NBPW - 1);
 			hash |= i;
@@ -1569,9 +1572,11 @@ moea_pinit(mmu_t mmu, pmap_t pmap)
 		moea_vsid_bitmap[n] |= mask;
 		for (i = 0; i < 16; i++)
 			pmap->pm_sr[i] = VSID_MAKE(i, hash);
+		mtx_unlock(&moea_vsid_mutex);
 		return;
 	}
 
+	mtx_unlock(&moea_vsid_mutex);
 	panic("moea_pinit: out of segments");
 }
 
@@ -1683,10 +1688,12 @@ moea_release(mmu_t mmu, pmap_t pmap)
         if (pmap->pm_sr[0] == 0)
                 panic("moea_release");
 
+	mtx_lock(&moea_vsid_mutex);
         idx = VSID_TO_HASH(pmap->pm_sr[0]) & (NPMAPS-1);
         mask = 1 << (idx % VSID_NBPW);
         idx /= VSID_NBPW;
         moea_vsid_bitmap[idx] &= ~mask;
+	mtx_unlock(&moea_vsid_mutex);
 	PMAP_LOCK_DESTROY(pmap);
 }
 

Modified: stable/8/sys/powerpc/aim/mmu_oea64.c
==============================================================================
--- stable/8/sys/powerpc/aim/mmu_oea64.c	Wed Sep 15 11:05:41 2010	(r212657)
+++ stable/8/sys/powerpc/aim/mmu_oea64.c	Wed Sep 15 13:43:43 2010	(r212658)
@@ -277,6 +277,7 @@ extern void bs_remap_earlyboot(void);
  * Lock for the pteg and pvo tables.
  */
 struct mtx	moea64_table_mutex;
+struct mtx	moea64_slb_mutex;
 
 /*
  * PTEG data.
@@ -841,6 +842,7 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_o
 	 */
 	mtx_init(&moea64_table_mutex, "pmap table", NULL, MTX_DEF |
 	    MTX_RECURSE);
+	mtx_init(&moea64_slb_mutex, "SLB table", NULL, MTX_DEF);
 
 	/*
 	 * Initialize the TLBIE lock. TLBIE can only be executed by one CPU.
@@ -1721,6 +1723,7 @@ moea64_pinit(mmu_t mmu, pmap_t pmap)
 	/*
 	 * Allocate some segment registers for this pmap.
 	 */
+	mtx_lock(&moea64_slb_mutex);
 	for (i = 0; i < NPMAPS; i += VSID_NBPW) {
 		u_int	hash, n;
 
@@ -1744,19 +1747,24 @@ moea64_pinit(mmu_t mmu, pmap_t pmap)
 				entropy = (moea64_vsidcontext >> 20);
 				continue;
 			}
-			i = ffs(~moea64_vsid_bitmap[i]) - 1;
+			i = ffs(~moea64_vsid_bitmap[n]) - 1;
 			mask = 1 << i;
 			hash &= 0xfffff & ~(VSID_NBPW - 1);
 			hash |= i;
 		}
+		KASSERT(!(moea64_vsid_bitmap[n] & mask),
+		    ("Allocating in-use VSID %#zx\n", hash));
 		moea64_vsid_bitmap[n] |= mask;
+		mtx_unlock(&moea64_slb_mutex);
+
 		for (i = 0; i < 16; i++) {
 			pmap->pm_sr[i] = VSID_MAKE(i, hash);
 		}
 		return;
 	}
 
-	panic("moea64_pinit: out of segments");
+	mtx_unlock(&moea64_slb_mutex);
+	panic("%s: out of segments",__func__);
 }
 
 /*
@@ -1871,12 +1879,14 @@ moea64_release(mmu_t mmu, pmap_t pmap)
 	 * Free segment register's VSID
 	 */
         if (pmap->pm_sr[0] == 0)
-                panic("moea64_release");
+                panic("moea64_release: pm_sr[0] = 0");
 
-        idx = VSID_TO_HASH(pmap->pm_sr[0]) & (NPMAPS-1);
-        mask = 1 << (idx % VSID_NBPW);
-        idx /= VSID_NBPW;
-        moea64_vsid_bitmap[idx] &= ~mask;
+	mtx_lock(&moea64_slb_mutex);
+	idx = VSID_TO_HASH(pmap->pm_sr[0]) & (NPMAPS-1);
+	mask = 1 << (idx % VSID_NBPW);
+	idx /= VSID_NBPW;
+	moea64_vsid_bitmap[idx] &= ~mask;
+	mtx_unlock(&moea64_slb_mutex);
 	PMAP_LOCK_DESTROY(pmap);
 }
 


More information about the svn-src-all mailing list