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
- Lines: 173
- Date:
Fri Aug 2 17:39:43 2002
- Orig file:
linux-2.4.18/arch/mips64/mm/fault.c
- Orig date:
Sun Sep 16 21:22:50 2001
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)