patch-2.3.13 linux/arch/alpha/mm/fault.c
Next file: linux/arch/alpha/mm/init.c
Previous file: linux/arch/alpha/math-emu/fp-emul.c
Back to the patch index
Back to the overall index
- Lines: 113
- Date:
Fri Aug 6 10:41:47 1999
- Orig file:
v2.3.12/linux/arch/alpha/mm/fault.c
- Orig date:
Wed Jul 21 15:46:48 1999
diff -u --recursive --new-file v2.3.12/linux/arch/alpha/mm/fault.c linux/arch/alpha/mm/fault.c
@@ -37,12 +37,9 @@
unsigned long last_asn = ASN_FIRST_VERSION;
#endif
-void
-get_new_mmu_context(struct task_struct *p, struct mm_struct *mm)
+void ev5_flush_tlb_current(struct mm_struct *mm)
{
- unsigned long new = __get_new_mmu_context(p, mm);
- mm->context = new;
- p->tss.asn = new & HARDWARE_ASN_MASK;
+ ev5_activate_mm(NULL, mm, smp_processor_id());
}
@@ -78,7 +75,8 @@
{
struct vm_area_struct * vma;
struct mm_struct *mm = current->mm;
- unsigned fixup;
+ unsigned int fixup;
+ int fault;
/* As of EV6, a load into $31/$f31 is a prefetch, and never faults
(or is suppressed by the PALcode). Support that for older CPUs
@@ -94,8 +92,12 @@
}
}
+ /* If we're in an interrupt context, or have no user context,
+ we must not take the fault. */
+ if (!mm || in_interrupt())
+ goto no_context;
+
down(&mm->mmap_sem);
- lock_kernel();
vma = find_vma(mm, address);
if (!vma)
goto bad_area;
@@ -121,9 +123,21 @@
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
}
- handle_mm_fault(current, vma, address, cause > 0);
+
+ /*
+ * If for any reason at all we couldn't handle the fault,
+ * make sure we exit gracefully rather than endlessly redo
+ * the fault.
+ */
+ fault = handle_mm_fault(current, vma, address, cause > 0);
up(&mm->mmap_sem);
- goto out;
+
+ if (fault < 0)
+ goto out_of_memory;
+ if (fault == 0)
+ goto do_sigbus;
+
+ return;
/*
* Something tried to access memory that isn't in our memory map..
@@ -134,9 +148,10 @@
if (user_mode(regs)) {
force_sig(SIGSEGV, current);
- goto out;
+ return;
}
+no_context:
/* Are we prepared to handle this fault as an exception? */
if ((fixup = search_exception_table(regs->pc)) != 0) {
unsigned long newpc;
@@ -144,7 +159,7 @@
printk("%s: Exception at [<%lx>] (%lx)\n",
current->comm, regs->pc, newpc);
regs->pc = newpc;
- goto out;
+ return;
}
/*
@@ -155,7 +170,25 @@
"virtual address %016lx\n", address);
die_if_kernel("Oops", regs, cause, (unsigned long*)regs - 16);
do_exit(SIGKILL);
- out:
- unlock_kernel();
-}
+/*
+ * We ran out of memory, or some other thing happened to us that made
+ * us unable to handle the page fault gracefully.
+ */
+out_of_memory:
+ printk(KERN_ALERT "VM: killing process %s(%d)\n",
+ current->comm, current->pid);
+ if (!user_mode(regs))
+ goto no_context;
+ do_exit(SIGKILL);
+
+do_sigbus:
+ /*
+ * Send a sigbus, regardless of whether we were in kernel
+ * or user mode.
+ */
+ force_sig(SIGBUS, current);
+ if (!user_mode(regs))
+ goto no_context;
+ return;
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)