diff options
author | alc <alc@FreeBSD.org> | 2006-09-22 07:02:15 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2006-09-22 07:02:15 +0000 |
commit | af1e0e1577dc1cad8f00713af1ba0d150ce5b5c4 (patch) | |
tree | c6b71540d807eed57185ef3007561f55687405f3 /sys/sparc64 | |
parent | 5f08ee5bcaa32a20b752d530da87ec5ed9e4c306 (diff) | |
download | FreeBSD-src-af1e0e1577dc1cad8f00713af1ba0d150ce5b5c4.zip FreeBSD-src-af1e0e1577dc1cad8f00713af1ba0d150ce5b5c4.tar.gz |
The sparc64/sparc64/pmap.c implementations of pmap_remove(),
pmap_protect(), and pmap_copy() have optimizations for regions
larger than PMAP_TSB_THRESH (which works out to 16MB). This
caused a panic in tsb_foreach for kernel mappings, since
pm->pm_tsb is NULL in that case. This fix teaches tsb_foreach
to use the kernel's tsb in that case.
Submitted by: Michael Plass
MFC after: 3 days
Diffstat (limited to 'sys/sparc64')
-rw-r--r-- | sys/sparc64/sparc64/tsb.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/sys/sparc64/sparc64/tsb.c b/sys/sparc64/sparc64/tsb.c index 8e99633..8c381cb 100644 --- a/sys/sparc64/sparc64/tsb.c +++ b/sys/sparc64/sparc64/tsb.c @@ -192,9 +192,9 @@ enter: * Traverse the tsb of a pmap, calling the callback function for any tte entry * that has a virtual address between start and end. If this function returns 0, * tsb_foreach() terminates. - * This is used by pmap_remove() and pmap_protect() in the case that the number - * of pages in the range given to them reaches the dimensions of the tsb size as - * an optimization. + * This is used by pmap_remove(), pmap_protect(), and pmap_copy() in the case + * that the number of pages in the range given to them reaches the + * dimensions of the tsb size as an optimization. */ void tsb_foreach(pmap_t pm1, pmap_t pm2, vm_offset_t start, vm_offset_t end, @@ -202,11 +202,20 @@ tsb_foreach(pmap_t pm1, pmap_t pm2, vm_offset_t start, vm_offset_t end, { vm_offset_t va; struct tte *tp; - int i; + struct tte *tsbp; + uintptr_t i; + uintptr_t n; PMAP_STATS_INC(tsb_nforeach); - for (i = 0; i < TSB_SIZE; i++) { - tp = &pm1->pm_tsb[i]; + if (pm1 == kernel_pmap) { + tsbp = tsb_kernel; + n = tsb_kernel_size / sizeof(struct tte); + } else { + tsbp = pm1->pm_tsb; + n = TSB_SIZE; + } + for (i = 0; i < n; i++) { + tp = &tsbp[i]; if ((tp->tte_data & TD_V) != 0) { va = TTE_GET_VA(tp); if (va >= start && va < end) { |