diff options
author | nwhitehorn <nwhitehorn@FreeBSD.org> | 2010-09-16 03:46:17 +0000 |
---|---|---|
committer | nwhitehorn <nwhitehorn@FreeBSD.org> | 2010-09-16 03:46:17 +0000 |
commit | 7f0b02b79cf7811ad0f1862f4b68caab6b3e8467 (patch) | |
tree | 2bd7d7e5a8713d75b37192097b4bf47505d6b141 /sys/powerpc/aim/trap.c | |
parent | e0d6e8068db893e66e2cacca8a3b1b800c40bc43 (diff) | |
download | FreeBSD-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.c | 18 |
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); |