patch-2.2.18 linux/arch/s390/mm/fault.c
Next file: linux/arch/s390/mm/init.c
Previous file: linux/arch/s390/lib/uaccess.S
Back to the patch index
Back to the overall index
- Lines: 126
- Date:
Wed Nov 8 23:09:58 2000
- Orig file:
v2.2.17/arch/s390/mm/fault.c
- Orig date:
Sat Sep 9 18:42:33 2000
diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.17/arch/s390/mm/fault.c linux/arch/s390/mm/fault.c
@@ -48,6 +48,7 @@
int write;
unsigned long psw_mask;
unsigned long psw_addr;
+ int kernel_address = 0;
/*
* get psw mask of Program old psw to find out,
@@ -71,6 +72,49 @@
if (atomic_read(&S390_lowcore.local_irq_count))
die("page fault from irq handler",regs,error_code);
+ /*
+ * Check which address space the address belongs to
+ */
+ switch (S390_lowcore.trans_exc_code & 3)
+ {
+ case 0: /* Primary Segment Table Descriptor */
+ kernel_address = 1;
+ goto no_context;
+
+ case 1: /* STD determined via access register */
+ if (S390_lowcore.exc_access_id == 0)
+ {
+ kernel_address = 1;
+ goto no_context;
+ }
+ if (regs && S390_lowcore.exc_access_id < NUM_ACRS)
+ {
+ if (regs->acrs[S390_lowcore.exc_access_id] == 0)
+ {
+ kernel_address = 1;
+ goto no_context;
+ }
+ if (regs->acrs[S390_lowcore.exc_access_id] == 1)
+ {
+ /* user space address */
+ break;
+ }
+ }
+ die("page fault via unknown access register", regs, error_code);
+ break;
+
+ case 2: /* Secondary Segment Table Descriptor */
+ case 3: /* Home Segment Table Descriptor */
+ /* user space address */
+ break;
+ }
+
+
+ /*
+ * When we get here, the fault happened in the current
+ * task's user address space, so we search the VMAs
+ */
+
down(&mm->mmap_sem);
vma = find_vma(mm, address);
@@ -129,12 +173,12 @@
/* User mode accesses just cause a SIGSEGV */
if (psw_mask & PSW_PROBLEM_STATE) {
tsk->tss.prot_addr = address;
- tsk->tss.error_code = error_code;
- tsk->tss.trap_no = 14;
-
+ tsk->tss.trap_no = error_code;
+#ifdef CONFIG_PROCESS_DEBUG
printk("User process fault: interruption code 0x%lX\n",error_code);
printk("failing address: %lX\n",address);
- show_crashed_task_info();
+ show_regs(regs);
+#endif
force_sig(SIGSEGV, tsk);
return;
}
@@ -149,14 +193,13 @@
/*
* Oops. The kernel tried to access some bad page. We'll have to
* terminate things with extreme prejudice.
- *
- * First we check if it was the bootup rw-test, though..
*/
- if (address < PAGE_SIZE)
- printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
+ if (kernel_address)
+ printk(KERN_ALERT "Unable to handle kernel pointer dereference"
+ " at virtual kernel address %08lx\n", address);
else
- printk(KERN_ALERT "Unable to handle kernel paging request");
- printk(" at virtual address %08lx\n",address);
+ printk(KERN_ALERT "Unable to handle kernel paging request"
+ " at virtual user address %08lx\n", address);
/*
* need to define, which information is useful here
*/
@@ -171,17 +214,17 @@
*/
out_of_memory:
if (tsk->pid == 1)
- {
+ {
tsk->policy |= SCHED_YIELD;
schedule();
goto survive;
- }
+ }
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:
@@ -192,8 +235,7 @@
* or user mode.
*/
tsk->tss.prot_addr = address;
- tsk->tss.error_code = error_code;
- tsk->tss.trap_no = 14;
+ tsk->tss.trap_no = error_code;
force_sig(SIGBUS, tsk);
/* Kernel mode? Handle exceptions or die */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)