summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/aim/trap.c
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2010-09-16 03:46:17 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2010-09-16 03:46:17 +0000
commit7f0b02b79cf7811ad0f1862f4b68caab6b3e8467 (patch)
tree2bd7d7e5a8713d75b37192097b4bf47505d6b141 /sys/powerpc/aim/trap.c
parente0d6e8068db893e66e2cacca8a3b1b800c40bc43 (diff)
downloadFreeBSD-src-7f0b02b79cf7811ad0f1862f4b68caab6b3e8467.zip
FreeBSD-src-7f0b02b79cf7811ad0f1862f4b68caab6b3e8467.tar.gz
Split the SLB mirror cache into two kinds of object, one for kernel maps
which are similar to the previous ones, and one for user maps, which are arrays of pointers into the SLB tree. This changes makes user SLB updates atomic, closing a window for memory corruption. While here, rearrange the allocation functions to make context switches faster.
Diffstat (limited to 'sys/powerpc/aim/trap.c')
-rw-r--r--sys/powerpc/aim/trap.c18
1 files changed, 8 insertions, 10 deletions
diff --git a/sys/powerpc/aim/trap.c b/sys/powerpc/aim/trap.c
index aafdb69..6130eab 100644
--- a/sys/powerpc/aim/trap.c
+++ b/sys/powerpc/aim/trap.c
@@ -445,17 +445,15 @@ syscall(struct trapframe *frame)
static int
handle_slb_spill(pmap_t pm, vm_offset_t addr)
{
- struct slb kern_entry, *user_entry;
+ struct slb *user_entry;
uint64_t esid;
int i;
esid = (uintptr_t)addr >> ADDR_SR_SHFT;
if (pm == kernel_pmap) {
- kern_entry.slbv = kernel_va_to_slbv(addr);
- kern_entry.slbe = (esid << SLBE_ESID_SHIFT) | SLBE_VALID;
-
- slb_insert(pm, PCPU_GET(slb), &kern_entry);
+ slb_insert_kernel((esid << SLBE_ESID_SHIFT) | SLBE_VALID,
+ kernel_va_to_slbv(addr));
return (0);
}
@@ -464,18 +462,18 @@ handle_slb_spill(pmap_t pm, vm_offset_t addr)
if (user_entry == NULL) {
/* allocate_vsid auto-spills it */
- (void)allocate_vsid(pm, esid, 0);
+ (void)allocate_user_vsid(pm, esid, 0);
} else {
/*
* Check that another CPU has not already mapped this.
* XXX: Per-thread SLB caches would be better.
*/
- for (i = 0; i < 64; i++)
- if (pm->pm_slb[i].slbe == (user_entry->slbe | i))
+ for (i = 0; i < pm->pm_slb_len; i++)
+ if (pm->pm_slb[i] == user_entry)
break;
- if (i == 64)
- slb_insert(pm, pm->pm_slb, user_entry);
+ if (i == pm->pm_slb_len)
+ slb_insert_user(pm, user_entry);
}
PMAP_UNLOCK(pm);
OpenPOWER on IntegriCloud