patch-2.1.126 linux/arch/mips/mm/fault.c

Next file: linux/arch/mips/mm/init.c
Previous file: linux/arch/mips/mm/andes.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.125/linux/arch/mips/mm/fault.c linux/arch/mips/mm/fault.c
@@ -1,10 +1,14 @@
-/*
- *  arch/mips/mm/fault.c
+/* $Id: fault.c,v 1.12 1998/10/19 21:27:37 ralf Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
- *  Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+ * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle
  */
 #include <linux/signal.h>
 #include <linux/sched.h>
+#include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
@@ -14,16 +18,20 @@
 #include <linux/mm.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
+#include <linux/version.h>
 
 #include <asm/hardirq.h>
 #include <asm/pgtable.h>
 #include <asm/mmu_context.h>
+#include <asm/softirq.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
-extern void die_if_kernel(char *, struct pt_regs *, long);
+#define development_version (LINUX_VERSION_CODE & 0x100)
+
+extern void die(char *, struct pt_regs *, unsigned long write);
 
-unsigned long asid_cache = ASID_FIRST_VERSION;
+unsigned long asid_cache;
 
 /*
  * Macro for exception fixup code to access integer registers.
@@ -43,9 +51,12 @@
 	struct mm_struct *mm = tsk->mm;
 	unsigned long fixup;
 
-	if (local_irq_count[smp_processor_id()] != 0)
-		die_if_kernel("page fault from irq handler", regs, writeaccess);
-	lock_kernel();
+	/*
+	 * If we're in an interrupt or have no user
+	 * context, we must not take the fault..
+	 */
+	if (in_interrupt() || mm == &init_mm)
+		goto no_context;
 #if 0
 	printk("[%s:%d:%08lx:%ld:%08lx]\n", current->comm, current->pid,
 	       address, writeaccess, regs->cp0_epc);
@@ -74,8 +85,7 @@
 	}
 	handle_mm_fault(tsk, vma, address, writeaccess);
 	up(&mm->mmap_sem);
-
-	goto out;
+	return;
 
 /*
  * Something tried to access memory that isn't in our memory map..
@@ -97,20 +107,22 @@
 		       (unsigned long) regs->regs[31]);
 #endif
 		force_sig(SIGSEGV, tsk);
-		goto out;
+		return;
 	}
 
-	/* Did we have an exception handler installed? */
+no_context:
+	/* Are we prepared to handle this kernel fault?  */
 	fixup = search_exception_table(regs->cp0_epc);
 	if (fixup) {
 		long new_epc;
 
 		tsk->tss.cp0_baduaddr = address;
 		new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
-		printk(KERN_DEBUG "%s: Exception at [<%lx>] (%lx)\n",
-		       tsk->comm, regs->cp0_epc, new_epc);
+		if (development_version)
+			printk(KERN_DEBUG "%s: Exception at [<%lx>] (%lx)\n",
+			       tsk->comm, regs->cp0_epc, new_epc);
 		regs->cp0_epc = new_epc;
-		goto out;
+		return;
 	}
 
 	/*
@@ -120,8 +132,6 @@
 	printk(KERN_ALERT "Unable to handle kernel paging request at virtual "
 	       "address %08lx, epc == %08lx, ra == %08lx\n",
 	       address, regs->cp0_epc, regs->regs[31]);
-	die_if_kernel("Oops", regs, writeaccess);
+	die("Oops", regs, writeaccess);
 	do_exit(SIGKILL);
-out:
-	unlock_kernel();
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov