patch-2.0.19 linux/arch/i386/mm/fault.c
Next file: linux/drivers/block/ide-tape.c
Previous file: linux/arch/i386/lib/semaphore.S
Back to the patch index
Back to the overall index
- Lines: 108
- Date:
Mon Sep 9 21:04:56 1996
- Orig file:
v2.0.18/linux/arch/i386/mm/fault.c
- Orig date:
Sun Sep 8 19:50:20 1996
diff -u --recursive --new-file v2.0.18/linux/arch/i386/mm/fault.c linux/arch/i386/mm/fault.c
@@ -33,13 +33,21 @@
*/
asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
{
+ void (*handler)(struct task_struct *,
+ struct vm_area_struct *,
+ unsigned long,
+ int);
+ struct task_struct *tsk = current;
+ struct mm_struct *mm = tsk->mm;
struct vm_area_struct * vma;
unsigned long address;
unsigned long page;
+ int write;
/* get the address */
__asm__("movl %%cr2,%0":"=r" (address));
- vma = find_vma(current, address);
+ down(&mm->mmap_sem);
+ vma = find_vma(mm, address);
if (!vma)
goto bad_area;
if (vma->vm_start <= address)
@@ -63,36 +71,37 @@
* we can handle it..
*/
good_area:
- /*
- * was it a write?
- */
- if (error_code & 2) {
- if (!(vma->vm_flags & VM_WRITE))
- goto bad_area;
- } else {
- /* read with protection fault? */
- if (error_code & 1)
- goto bad_area;
- if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+ write = 0;
+ handler = do_no_page;
+ switch (error_code & 3) {
+ default: /* 3: write, present */
+ handler = do_wp_page;
+#ifdef TEST_VERIFY_AREA
+ if (regs->cs == KERNEL_CS)
+ printk("WP fault at %08lx\n", regs->eip);
+#endif
+ /* fall through */
+ case 2: /* write, not present */
+ if (!(vma->vm_flags & VM_WRITE))
+ goto bad_area;
+ write++;
+ break;
+ case 1: /* read, present */
goto bad_area;
+ case 0: /* read, not present */
+ if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+ goto bad_area;
}
+ handler(tsk, vma, address, write);
+ up(&mm->mmap_sem);
/*
* Did it hit the DOS screen memory VA from vm86 mode?
*/
if (regs->eflags & VM_MASK) {
unsigned long bit = (address - 0xA0000) >> PAGE_SHIFT;
if (bit < 32)
- current->tss.screen_bitmap |= 1 << bit;
- }
- if (error_code & 1) {
-#ifdef TEST_VERIFY_AREA
- if (regs->cs == KERNEL_CS)
- printk("WP fault at %08lx\n", regs->eip);
-#endif
- do_wp_page(current, vma, address, error_code & 2);
- return;
+ tsk->tss.screen_bitmap |= 1 << bit;
}
- do_no_page(current, vma, address, error_code & 2);
return;
/*
@@ -100,11 +109,12 @@
* Fix it, but check if it's kernel or user first..
*/
bad_area:
+ up(&mm->mmap_sem);
if (error_code & 4) {
- current->tss.cr2 = address;
- current->tss.error_code = error_code;
- current->tss.trap_no = 14;
- force_sig(SIGSEGV, current);
+ tsk->tss.cr2 = address;
+ tsk->tss.error_code = error_code;
+ tsk->tss.trap_no = 14;
+ force_sig(SIGSEGV, tsk);
return;
}
/*
@@ -128,7 +138,7 @@
printk(" at virtual address %08lx\n",address);
__asm__("movl %%cr3,%0" : "=r" (page));
printk(KERN_ALERT "current->tss.cr3 = %08lx, %%cr3 = %08lx\n",
- current->tss.cr3, page);
+ tsk->tss.cr3, page);
page = ((unsigned long *) page)[address >> 22];
printk(KERN_ALERT "*pde = %08lx\n", page);
if (page & 1) {
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov