summaryrefslogtreecommitdiffstats
path: root/arch/sparc64/mm/fault.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/mm/fault.c')
-rw-r--r--arch/sparc64/mm/fault.c64
1 files changed, 52 insertions, 12 deletions
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index 04aa8284e..1a20b399b 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.36 1999/07/04 04:35:56 davem Exp $
+/* $Id: fault.c,v 1.39 1999/08/30 10:07:09 davem Exp $
* arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -84,10 +84,11 @@ void unhandled_fault(unsigned long address, struct task_struct *tsk,
printk(KERN_ALERT "Unable to handle kernel paging request "
"at virtual address %016lx\n", (unsigned long)address);
}
- printk(KERN_ALERT "tsk->mm->context = %016lx\n",
- (unsigned long) tsk->mm->context);
- printk(KERN_ALERT "tsk->mm->pgd = %016lx\n",
- (unsigned long) tsk->mm->pgd);
+ printk(KERN_ALERT "tsk->{mm,active_mm}->context = %016lx\n",
+ (tsk->mm ? tsk->mm->context : tsk->active_mm->context));
+ printk(KERN_ALERT "tsk->{mm,active_mm}->pgd = %016lx\n",
+ (tsk->mm ? (unsigned long) tsk->mm->pgd :
+ (unsigned long) tsk->active_mm->pgd));
die_if_kernel("Oops", regs);
}
@@ -154,16 +155,45 @@ asmlinkage void do_sparc64_fault(struct pt_regs *regs, unsigned long address, in
* If we're in an interrupt or have no user
* context, we must not take the fault..
*/
- if (in_interrupt() || mm == &init_mm)
+ if (in_interrupt() || !mm)
goto do_kernel_fault;
down(&mm->mmap_sem);
#ifdef DEBUG_LOCKUPS
- if (regs->tpc == lastpc && address == lastaddr && write == lastwrite) {
+ if (regs->tpc == lastpc &&
+ address == lastaddr &&
+ write == lastwrite) {
lockcnt++;
if (lockcnt == 100000) {
- printk("do_sparc64_fault: possible fault loop for %016lx %s\n", address, write ? "write" : "read");
+ unsigned char tmp;
+ register unsigned long tmp1 asm("o5");
+ register unsigned long tmp2 asm("o4");
+
+ printk("do_sparc64_fault[%s:%d]: possible fault loop for %016lx %s\n",
+ current->comm, current->pid,
+ address, write ? "write" : "read");
+ printk("do_sparc64_fault: CHECK[papgd[%016lx],pcac[%016lx]]\n",
+ __pa(mm->pgd), pgd_val(mm->pgd[0])<<11UL);
+ __asm__ __volatile__(
+ "wrpr %%g0, 0x494, %%pstate\n\t"
+ "mov %3, %%g4\n\t"
+ "mov %%g7, %0\n\t"
+ "ldxa [%%g4] %2, %1\n\t"
+ "wrpr %%g0, 0x096, %%pstate"
+ : "=r" (tmp1), "=r" (tmp2)
+ : "i" (ASI_DMMU), "i" (TSB_REG));
+ printk("do_sparc64_fault: IS[papgd[%016lx],pcac[%016lx]]\n",
+ tmp1, tmp2);
+ printk("do_sparc64_fault: CHECK[ctx(%016lx)] IS[ctx(%016lx)]\n",
+ mm->context, spitfire_get_secondary_context());
+ __asm__ __volatile__("rd %%asi, %0"
+ : "=r" (tmp));
+ printk("do_sparc64_fault: CHECK[seg(%02x)] IS[seg(%02x)]\n",
+ current->thread.current_ds.seg, tmp);
show_regs(regs);
+ __sti();
+ while(1)
+ barrier();
}
} else {
lastpc = regs->tpc;
@@ -282,8 +312,18 @@ do_kernel_fault:
return;
}
} else {
- current->tss.sig_address = address;
- current->tss.sig_desc = SUBSIG_NOMAPPING;
+#if 0
+ extern void __show_regs(struct pt_regs *);
+ printk("SHIT(%s:%d:cpu(%d)): PC[%016lx] ADDR[%016lx]\n",
+ current->comm, current->pid, smp_processor_id(),
+ regs->tpc, address);
+ __show_regs(regs);
+ __sti();
+ while(1)
+ barrier();
+#endif
+ current->thread.sig_address = address;
+ current->thread.sig_desc = SUBSIG_NOMAPPING;
force_sig(SIGSEGV, current);
return;
}
@@ -293,8 +333,8 @@ do_kernel_fault:
do_sigbus:
up(&mm->mmap_sem);
- current->tss.sig_address = address;
- current->tss.sig_desc = SUBSIG_MISCERROR;
+ current->thread.sig_address = address;
+ current->thread.sig_desc = SUBSIG_MISCERROR;
force_sig(SIGBUS, current);
if (regs->tstate & TSTATE_PRIV)
goto do_kernel_fault;