patch-2.1.124 linux/arch/sparc64/mm/fault.c
Next file: linux/arch/sparc64/mm/init.c
Previous file: linux/arch/sparc64/mm/asyncd.c
Back to the patch index
Back to the overall index
- Lines: 105
- Date:
Sun Oct 4 10:22:43 1998
- Orig file:
v2.1.123/linux/arch/sparc64/mm/fault.c
- Orig date:
Thu Apr 23 20:21:32 1998
diff -u --recursive --new-file v2.1.123/linux/arch/sparc64/mm/fault.c linux/arch/sparc64/mm/fault.c
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.21 1998/03/25 10:43:20 jj Exp $
+/* $Id: fault.c,v 1.24 1998/09/22 03:27:33 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)
@@ -100,49 +100,38 @@
(unsigned long) tsk->mm->context);
printk(KERN_ALERT "tsk->mm->pgd = %016lx\n",
(unsigned long) tsk->mm->pgd);
+ lock_kernel();
die_if_kernel("Oops", regs);
-}
-
-asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc,
- unsigned long address)
-{
- unsigned long g2;
- int i;
- unsigned insn;
- struct pt_regs regs;
-
- i = search_exception_table (ret_pc, &g2);
- switch (i) {
- /* load & store will be handled by fixup */
- case 3: return 3;
- /* store will be handled by fixup, load will bump out */
- /* for _to_ macros */
- case 1: insn = *(unsigned *)pc; if ((insn >> 21) & 1) return 1; break;
- /* load will be handled by fixup, store will bump out */
- /* for _from_ macros */
- case 2: insn = *(unsigned *)pc;
- if (!((insn >> 21) & 1) || ((insn>>19)&0x3f) == 15) return 2;
- break;
- default: break;
- }
- memset (®s, 0, sizeof (regs));
- regs.tpc = pc;
- regs.tnpc = pc + 4;
- /* FIXME: Should set up regs->tstate? */
- unhandled_fault (address, current, ®s);
- /* Not reached */
- return 0;
+ unlock_kernel();
}
/* #define DEBUG_EXCEPTIONS */
+/* #define DEBUG_LOCKUPS */
asmlinkage void do_sparc64_fault(struct pt_regs *regs, unsigned long address, int write)
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
+#ifdef DEBUG_LOCKUPS
+ static unsigned long lastaddr, lastpc;
+ static int lastwrite, lockcnt;
+#endif
- lock_kernel();
down(&mm->mmap_sem);
+#ifdef DEBUG_LOCKUPS
+ 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");
+ show_regs(regs);
+ }
+ } else {
+ lastpc = regs->tpc;
+ lastaddr = address;
+ lastwrite = write;
+ lockcnt = 0;
+ }
+#endif
vma = find_vma(mm, address);
if(!vma)
goto bad_area;
@@ -167,7 +156,7 @@
}
handle_mm_fault(current, vma, address, write);
up(&mm->mmap_sem);
- goto out;
+ return;
/*
* Something tried to access memory that isn't in our memory map..
* Fix it, but check if it's kernel or user first..
@@ -204,16 +193,14 @@
regs->tpc = fixup;
regs->tnpc = regs->tpc + 4;
regs->u_regs[UREG_G2] = g2;
- goto out;
+ return;
}
} else {
current->tss.sig_address = address;
current->tss.sig_desc = SUBSIG_NOMAPPING;
force_sig(SIGSEGV, current);
- goto out;
+ return;
}
unhandled_fault (address, current, regs);
}
-out:
- unlock_kernel();
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov