--- zzzz-none-000/linux-2.4.17/arch/mips/mm/fault.c 2001-07-04 18:50:39.000000000 +0000 +++ sangam-fb-322/linux-2.4.17/arch/mips/mm/fault.c 2004-11-24 13:22:40.000000000 +0000 @@ -28,13 +28,44 @@ #define development_version (LINUX_VERSION_CODE & 0x100) -unsigned long asid_cache = ASID_FIRST_VERSION; - /* * Macro for exception fixup code to access integer registers. */ #define dpf_reg(r) (regs->regs[r]) +extern spinlock_t timerlist_lock; + +/* + * Unlock any spinlocks which will prevent us from getting the + * message out (timerlist_lock is acquired through the + * console unblank code) + */ +void bust_spinlocks(int yes) +{ + 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 + unblank_screen(); +#endif + oops_in_progress = 0; + /* + * OK, the message is on the console. Now we call printk() + * without oops_in_progress set so that printk will give klogd + * a poke. Hold onto your hats... + */ + console_loglevel = 15; /* NMI oopser may have shut the console up */ + printk(" "); + console_loglevel = loglevel_save; + } +} + /* * This routine handles page faults. It determines the address, * and the problem, and then passes it off to one of the appropriate @@ -58,7 +89,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; @@ -97,6 +128,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 @@ -170,7 +202,7 @@ "address %08lx, epc == %08lx, ra == %08lx\n", address, regs->cp0_epc, regs->regs[31]); die("Oops", regs); - do_exit(SIGKILL); + /* Game over. */ /* * We ran out of memory, or some other thing happened to us that made @@ -178,6 +210,12 @@ */ out_of_memory: up_read(&mm->mmap_sem); + if (tsk->pid == 1) { + tsk->policy |= SCHED_YIELD; + schedule(); + down_read(&mm->mmap_sem); + goto survive; + } printk("VM: killing process %s\n", tsk->comm); if (user_mode(regs)) do_exit(SIGKILL); @@ -191,7 +229,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;