summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2010-08-29 18:17:38 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2010-08-29 18:17:38 +0000
commitc7313507efc899f693f73ecc1b97b23563178ad5 (patch)
tree1dc7cd135c473e245c5bd950d9f270cc6747b1c3 /sys
parentee1046e8592955b54e1a0b666d98d423529d7e32 (diff)
downloadFreeBSD-src-c7313507efc899f693f73ecc1b97b23563178ad5.zip
FreeBSD-src-c7313507efc899f693f73ecc1b97b23563178ad5.tar.gz
Avoid a race in the allocation of new segment IDs that could result in
memory corruption on heavily loaded SMP systems. MFC after: 2 weeks
Diffstat (limited to 'sys')
-rw-r--r--sys/powerpc/aim/mmu_oea64.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
index 962e8ec..c1c2651 100644
--- a/sys/powerpc/aim/mmu_oea64.c
+++ b/sys/powerpc/aim/mmu_oea64.c
@@ -285,6 +285,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.
@@ -1068,6 +1069,7 @@ moea64_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
*/
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.
@@ -2054,6 +2056,7 @@ moea64_get_unique_vsid(void) {
entropy = 0;
__asm __volatile("mftb %0" : "=r"(entropy));
+ mtx_lock(&moea64_slb_mutex);
for (i = 0; i < NVSIDS; i += VSID_NBPW) {
u_int n;
@@ -2083,9 +2086,11 @@ moea64_get_unique_vsid(void) {
hash |= i;
}
moea64_vsid_bitmap[n] |= mask;
+ mtx_unlock(&moea64_slb_mutex);
return (hash);
}
+ mtx_unlock(&moea64_slb_mutex);
panic("%s: out of segments",__func__);
}
OpenPOWER on IntegriCloud