patch-2.4.19 linux-2.4.19/arch/mips64/mm/fault.c

Next file: linux-2.4.19/arch/mips64/mm/init.c
Previous file: linux-2.4.19/arch/mips64/mm/c-sb1.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.18/arch/mips64/mm/fault.c linux-2.4.19/arch/mips64/mm/fault.c
@@ -21,6 +21,7 @@
 #include <linux/smp_lock.h>
 #include <linux/version.h>
 
+#include <asm/branch.h>
 #include <asm/hardirq.h>
 #include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
@@ -31,22 +32,19 @@
 
 #define development_version (LINUX_VERSION_CODE & 0x100)
 
-extern void die(char *, struct pt_regs *, unsigned long write);
-
 /*
  * Macro for exception fixup code to access integer registers.
  */
 #define dpf_reg(r) (regs->regs[r])
 
-asmlinkage void
-dodebug(abi64_no_regargs, struct pt_regs regs)
+asmlinkage void dodebug(abi64_no_regargs, struct pt_regs regs)
 {
-	printk("Got syscall %ld, cpu %d proc %s:%d epc 0x%lx\n", regs.regs[2],
-	       smp_processor_id(), current->comm, current->pid, regs.cp0_epc);
+	printk(KERN_DEBUG "Got syscall %ld, cpu %d proc %s:%d epc 0x%lx\n",
+	       regs.regs[2], smp_processor_id(), current->comm, current->pid,
+	       regs.cp0_epc);
 }
 
-asmlinkage void
-dodebug2(abi64_no_regargs, struct pt_regs regs)
+asmlinkage void dodebug2(abi64_no_regargs, struct pt_regs regs)
 {
 	unsigned long retaddr;
 
@@ -55,7 +53,8 @@
 		"add %0,$0,$31\n\t"
 		".set reorder"
 		: "=r" (retaddr));
-	printk("Got exception 0x%lx at 0x%lx\n", retaddr, regs.cp0_epc);
+	printk(KERN_DEBUG "Got exception 0x%lx at 0x%lx\n", retaddr,
+	       regs.cp0_epc);
 }
 
 extern spinlock_t timerlist_lock;
@@ -70,6 +69,10 @@
 	spin_lock_init(&timerlist_lock);
 	if (yes) {
 		oops_in_progress = 1;
+#ifdef CONFIG_SMP
+		/* Many serial drivers do __global_cli() */
+		global_irq_lock = SPIN_LOCK_UNLOCKED;
+#endif
 	} else {
 		int loglevel_save = console_loglevel;
 #ifdef CONFIG_VT
@@ -92,8 +95,8 @@
  * and the problem, and then passes it off to one of the appropriate
  * routines.
  */
-asmlinkage void
-do_page_fault(struct pt_regs *regs, unsigned long write, unsigned long address)
+asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
+			      unsigned long address)
 {
 	struct vm_area_struct * vma;
 	struct task_struct *tsk = current;
@@ -101,6 +104,11 @@
 	unsigned long fixup;
 	siginfo_t info;
 
+#if 0
+	printk("Cpu%d[%s:%d:%08lx:%ld:%08lx]\n", smp_processor_id(),
+		current->comm, current->pid, address, write, regs->cp0_epc);
+#endif
+
 	/*
 	 * We fault-in kernel-space virtual memory on-demand. The
 	 * 'reference' page table is init_mm.pgd.
@@ -110,7 +118,7 @@
 	 * only copy the information from the master page table,
 	 * nothing more.
 	 */
-	if (address >= TASK_SIZE)
+	if (address >= VMALLOC_START)
 		goto vmalloc_fault;
 
 	info.si_code = SEGV_MAPERR;
@@ -120,10 +128,7 @@
 	 */
 	if (in_interrupt() || mm == &init_mm)
 		goto no_context;
-#if DEBUG_MIPS64
-	printk("Cpu%d[%s:%d:%08lx:%ld:%08lx]\n", smp_processor_id(), current->comm,
-		current->pid, address, write, regs->cp0_epc);
-#endif
+
 	down_read(&mm->mmap_sem);
 	vma = find_vma(mm, address);
 	if (!vma)
@@ -149,6 +154,7 @@
 			goto bad_area;
 	}
 
+survive:
 	/*
 	 * If for any reason at all we couldn't handle the fault,
 	 * make sure we exit gracefully rather than endlessly redo
@@ -177,7 +183,6 @@
 bad_area:
 	up_read(&mm->mmap_sem);
 
-bad_area_nosemaphore:
 	if (user_mode(regs)) {
 		tsk->thread.cp0_badvaddr = address;
 		tsk->thread.error_code = write;
@@ -189,6 +194,7 @@
 		       address,
 		       (unsigned long) regs->cp0_epc,
 		       (unsigned long) regs->regs[31]);
+while(1);
 #endif
 		info.si_signo = SIGSEGV;
 		info.si_errno = 0;
@@ -200,7 +206,7 @@
 
 no_context:
 	/* Are we prepared to handle this kernel fault?  */
-	fixup = search_exception_table(regs->cp0_epc);
+	fixup = search_exception_table(exception_epc(regs));
 	if (fixup) {
 		long new_epc;
 
@@ -221,12 +227,9 @@
 	bust_spinlocks(1);
 
 	printk(KERN_ALERT "Cpu %d Unable to handle kernel paging request at "
-	       "address %08lx, epc == %08x, ra == %08x\n",
-	       smp_processor_id(), address, (unsigned int) regs->cp0_epc,
-               (unsigned int) regs->regs[31]);
+	       "address %016lx, epc == %016lx, ra == %016lx\n",
+	       smp_processor_id(), address, regs->cp0_epc, regs->regs[31]);
 	die("Oops", regs, write);
-	do_exit(SIGKILL);
-	bust_spinlocks(0);
 
 /*
  * We ran out of memory, or some other thing happened to us that made
@@ -234,7 +237,13 @@
  */
 out_of_memory:
 	up_read(&mm->mmap_sem);
-	printk("VM: killing process %s\n", tsk->comm);
+	if (tsk->pid == 1) {
+		tsk->policy |= SCHED_YIELD;
+		schedule();
+		down_read(&mm->mmap_sem);
+		goto survive;
+	}
+	printk(KERN_NOTICE "VM: killing process %s\n", tsk->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
 	goto no_context;
@@ -247,7 +256,7 @@
 	 * or user mode.
 	 */
 	tsk->thread.cp0_badvaddr = address;
-	info.si_code = SIGBUS;
+	info.si_signo = SIGBUS;
 	info.si_errno = 0;
 	info.si_code = BUS_ADRERR;
 	info.si_addr = (void *) address;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)