static inline void print_task(struct task_struct *tsk)
{
- printk("Task pid %d\n", tsk->pid);
+ printk("Task pid %d:#%u\n", tsk->pid, tsk->xid);
}
static pte_t *lookup_pte(struct mm_struct *mm, unsigned long address)
mm = tsk->mm;
/* Not an IO address, so reenable interrupts */
- sti();
+ local_irq_enable();
/*
* If we're in an interrupt or have no user
* context, we must not take the fault..
*/
- if (in_interrupt() || !mm)
+ if (in_atomic() || !mm)
goto no_context;
/* TLB misses upon some cache flushes get done under cli() */
* we can handle it..
*/
good_area:
- if (writeaccess) {
- if (!(vma->vm_flags & VM_WRITE))
- goto bad_area;
- } else {
- if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
- goto bad_area;
- }
-
if (textaccess) {
if (!(vma->vm_flags & VM_EXEC))
goto bad_area;
+ } else {
+ if (writeaccess) {
+ if (!(vma->vm_flags & VM_WRITE))
+ goto bad_area;
+ } else {
+ if (!(vma->vm_flags & VM_READ))
+ goto bad_area;
+ }
}
/*
*/
survive:
switch (handle_mm_fault(mm, vma, address, writeaccess)) {
- case 1:
+ case VM_FAULT_MINOR:
tsk->min_flt++;
break;
- case 2:
+ case VM_FAULT_MAJOR:
tsk->maj_flt++;
break;
- case 0:
+ case VM_FAULT_SIGBUS:
goto do_sigbus;
default:
goto out_of_memory;
up_read(&mm->mmap_sem);
if (user_mode(regs)) {
- printk("user mode bad_area address=%08lx pid=%d (%s) pc=%08lx opcode=%08lx\n",
- address, current->pid, current->comm,
- (unsigned long) regs->pc,
- *(unsigned long *)(u32)(regs->pc & ~3));
- show_regs(regs);
- if (tsk->pid == 1) {
+ static int count=0;
+ siginfo_t info;
+ if (count < 4) {
+ /* This is really to help debug faults when starting
+ * usermode, so only need a few */
+ count++;
+ printk("user mode bad_area address=%08lx pid=%d (%s) pc=%08lx\n",
+ address, current->pid, current->comm,
+ (unsigned long) regs->pc);
+#if 0
+ show_regs(regs);
+#endif
+ }
+ if (is_init(tsk)) {
panic("INIT had user mode bad_area\n");
}
tsk->thread.address = address;
tsk->thread.error_code = writeaccess;
- force_sig(SIGSEGV, tsk);
+ info.si_signo = SIGSEGV;
+ info.si_errno = 0;
+ info.si_addr = (void *) address;
+ force_sig_info(SIGSEGV, &info, tsk);
return;
}
* us unable to handle the page fault gracefully.
*/
out_of_memory:
- if (current->pid == 1) {
+ if (is_init(current)) {
panic("INIT out of memory\n");
yield();
goto survive;
}
printk("fault:Out of memory\n");
up_read(&mm->mmap_sem);
- if (current->pid == 1) {
+ if (is_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
}
- printk("VM: killing process %s\n", tsk->comm);
+ printk("VM: killing process %s(%d:#%u)\n",
+ tsk->comm, tsk->pid, tsk->xid);
if (user_mode(regs))
do_exit(SIGKILL);
goto no_context;