patch-2.1.3 linux/arch/i386/mm/fault.c
Next file: linux/drivers/block/md.c
Previous file: linux/arch/i386/math-emu/reg_round.S
Back to the patch index
Back to the overall index
- Lines: 58
- Date:
Thu Oct 10 17:09:51 1996
- Orig file:
v2.1.2/linux/arch/i386/mm/fault.c
- Orig date:
Wed Oct 9 08:55:17 1996
diff -u --recursive --new-file v2.1.2/linux/arch/i386/mm/fault.c linux/arch/i386/mm/fault.c
@@ -22,6 +22,57 @@
extern void die_if_kernel(const char *,struct pt_regs *,long);
/*
+ * Ugly, ugly, but the goto's result in better assembly..
+ */
+int __verify_write(const void * addr, unsigned long size)
+{
+ struct vm_area_struct * vma;
+ unsigned long start = (unsigned long) addr;
+
+ if (!size)
+ return 0;
+
+ vma = find_vma(current->mm, start);
+ if (!vma)
+ goto bad_area;
+ if (vma->vm_start > start)
+ goto check_stack;
+
+good_area:
+ if (!(vma->vm_flags & VM_WRITE))
+ goto bad_area;
+ size--;
+ size += start & ~PAGE_MASK;
+ size >>= PAGE_SHIFT;
+ start &= PAGE_MASK;
+
+ for (;;) {
+ do_wp_page(current, vma, start, 1);
+ if (!size)
+ break;
+ size--;
+ start += PAGE_SIZE;
+ if (start < vma->vm_end)
+ continue;
+ vma = vma->vm_next;
+ if (!vma || vma->vm_start != start)
+ goto bad_area;
+ if (!(vma->vm_flags & VM_WRITE))
+ goto bad_area;;
+ }
+ return 0;
+
+check_stack:
+ if (!(vma->vm_flags & VM_GROWSDOWN))
+ goto bad_area;
+ if (expand_stack(vma, start) == 0)
+ goto good_area;
+
+bad_area:
+ return -EFAULT;
+}
+
+/*
* This routine handles page faults. It determines the address,
* and the problem, and then passes it off to one of the appropriate
* routines.
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov