Date: Wed, 15 Sep 2010 13:43:43 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r212658 - stable/8/sys/powerpc/aim Message-ID: <201009151343.o8FDhhwq037867@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201009151343.o8FDhhwq037867>