patch-2.2.16 linux/arch/s390/mm/fault.c
Next file: linux/arch/s390/mm/init.c
Previous file: linux/arch/s390/lib/strncpy.S
Back to the patch index
Back to the overall index
- Lines: 120
- Date:
Wed Jun 7 14:26:42 2000
- Orig file:
v2.2.15/linux/arch/s390/mm/fault.c
- Orig date:
Tue Jan 4 10:12:12 2000
diff -urN v2.2.15/linux/arch/s390/mm/fault.c linux/arch/s390/mm/fault.c
@@ -65,12 +65,12 @@
address = S390_lowcore.trans_exc_code&0x7ffff000;
- if (atomic_read(&S390_lowcore.local_irq_count))
- die("page fault from irq handler",regs,error_code);
-
tsk = current;
mm = tsk->mm;
+ if (atomic_read(&S390_lowcore.local_irq_count))
+ die("page fault from irq handler",regs,error_code);
+
down(&mm->mmap_sem);
vma = find_vma(mm, address);
@@ -116,7 +116,20 @@
printk("code should be 4, 10 or 11 (%lX) \n",error_code&0xFF);
goto bad_area;
}
- handle_mm_fault(tsk, vma, address, write);
+
+ /*
+ * If for any reason at all we couldn't handle the fault,
+ * make sure we exit gracefully rather than endlessly redo
+ * the fault.
+ */
+survive:
+ {
+ int fault = handle_mm_fault(tsk, vma, address, write);
+ if (!fault)
+ goto do_sigbus;
+ if (fault < 0)
+ goto out_of_memory;
+ }
up(&mm->mmap_sem);
return;
@@ -141,8 +154,8 @@
return;
}
+ no_context:
/* Are we prepared to handle this kernel fault? */
-
if ((fixup = search_exception_table(regs->psw.addr)) != 0) {
regs->psw.addr = fixup;
return;
@@ -163,41 +176,43 @@
* need to define, which information is useful here
*/
- lock_kernel();
die("Oops", regs, error_code);
do_exit(SIGKILL);
- 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:
+ if (tsk->pid == 1)
{
- char c;
- int i,j;
- char *addr;
- addr = ((char*) psw_addr)-0x20;
- for (i=0;i<16;i++) {
- if (i == 2)
- printk("\n");
- printk ("%08X: ",(unsigned long) addr);
- for (j=0;j<4;j++) {
- printk("%08X ",*(unsigned long*)addr);
- addr += 4;
- }
- addr -=0x10;
- printk(" | ");
- for (j=0;j<16;j++) {
- printk("%c",(c=*addr++) < 0x20 ? '.' : c );
+ tsk->policy |= SCHED_YIELD;
+ schedule();
+ goto survive;
}
-
- printk("\n");
- }
- printk("\n");
+ up(&mm->mmap_sem);
+ if (psw_mask & PSW_PROBLEM_STATE)
+ {
+ printk("VM: killing process %s\n", tsk->comm);
+ do_exit(SIGKILL);
}
+ goto no_context;
-*/
-
-
-
-
+do_sigbus:
+ up(&mm->mmap_sem);
+ /*
+ * Send a sigbus, regardless of whether we were in kernel
+ * or user mode.
+ */
+ tsk->tss.prot_addr = address;
+ tsk->tss.error_code = error_code;
+ tsk->tss.trap_no = 14;
+ force_sig(SIGBUS, tsk);
+
+ /* Kernel mode? Handle exceptions or die */
+ if (!(psw_mask & PSW_PROBLEM_STATE))
+ goto no_context;
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)