summaryrefslogtreecommitdiffstats
path: root/sys/sparc64
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2006-09-22 07:02:15 +0000
committeralc <alc@FreeBSD.org>2006-09-22 07:02:15 +0000
commitaf1e0e1577dc1cad8f00713af1ba0d150ce5b5c4 (patch)
treec6b71540d807eed57185ef3007561f55687405f3 /sys/sparc64
parent5f08ee5bcaa32a20b752d530da87ec5ed9e4c306 (diff)
downloadFreeBSD-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.c21
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) {
OpenPOWER on IntegriCloud