diff -urNp linux-890/arch/i386/mm/fault.c linux-900/arch/i386/mm/fault.c --- linux-890/arch/i386/mm/fault.c +++ linux-900/arch/i386/mm/fault.c @@ -178,9 +178,10 @@ asmlinkage void do_page_fault(struct pt_ * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_interrupt() || !mm) - goto no_context; + if (tsk->in_page_fault || in_interrupt() || !mm) + goto must_oops; + tsk->in_page_fault = 1; down_read(&mm->mmap_sem); vma = find_vma(mm, address); @@ -256,6 +257,7 @@ good_area: tsk->thread.screen_bitmap |= 1 << bit; } up_read(&mm->mmap_sem); + tsk->in_page_fault = 0; return; /* @@ -264,6 +266,7 @@ good_area: */ bad_area: up_read(&mm->mmap_sem); + tsk->in_page_fault = 0; /* User mode accesses just cause a SIGSEGV */ if (error_code & 4) { @@ -304,6 +307,7 @@ no_context: * terminate things with extreme prejudice. */ +must_oops: bust_spinlocks(1); if (address < PAGE_SIZE) @@ -336,6 +340,7 @@ out_of_memory: goto survive; } up_read(&mm->mmap_sem); + tsk->in_page_fault = 0; printk("VM: killing process %s\n", tsk->comm); if (error_code & 4) do_exit(SIGKILL); @@ -343,6 +348,7 @@ out_of_memory: do_sigbus: up_read(&mm->mmap_sem); + tsk->in_page_fault = 0; /* * Send a sigbus, regardless of whether we were in kernel diff -urNp linux-890/include/linux/sched.h linux-900/include/linux/sched.h --- linux-890/include/linux/sched.h +++ linux-900/include/linux/sched.h @@ -339,7 +339,7 @@ struct task_struct { int pdeath_signal; /* The signal sent when the parent dies */ /* ??? */ unsigned long personality; - int did_exec:1; + int did_exec:1, in_page_fault:1; unsigned task_dumpable:1; pid_t pid; pid_t pgrp;