Replace remaining uses of vm_fault_quick() with vm_fault_page_quick().
authorMatthew Dillon <dillon@dragonflybsd.org>
Thu, 11 Jan 2007 20:53:42 +0000 (20:53 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Thu, 11 Jan 2007 20:53:42 +0000 (20:53 +0000)
Do not directly access userland virtual addresses in the kernel UMTX code.

sys/kern/kern_umtx.c
sys/kern/kern_xio.c
sys/vm/vm_extern.h
sys/vm/vm_fault.c

index 1597e4b..078dc1f 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/kern/kern_umtx.c,v 1.5 2006/06/05 07:26:10 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_umtx.c,v 1.6 2007/01/11 20:53:41 dillon Exp $
  */
 
 /*
@@ -47,6 +47,7 @@
 #include <sys/sysunion.h>
 #include <sys/sysent.h>
 #include <sys/syscall.h>
+#include <sys/sfbuf.h>
 #include <sys/module.h>
 
 #include <vm/vm.h>
@@ -90,33 +91,36 @@ int
 sys_umtx_sleep(struct umtx_sleep_args *uap)
 {
     int error = EBUSY;
-    vm_paddr_t pa;
+    struct sf_buf *sf;
     vm_page_t m;
     void *waddr;
+    int offset;
     int timeout;
 
     if ((unsigned int)uap->timeout > 1000000)
        return (EINVAL);
-    if (vm_fault_quick((caddr_t)__DEQUALIFY(int *, uap->ptr), VM_PROT_READ) < 0)
+    if ((vm_offset_t)uap->ptr & (sizeof(int) - 1))
        return (EFAULT);
+    m = vm_fault_page_quick((vm_offset_t)uap->ptr, VM_PROT_READ, &error);
+    if (m == NULL)
+       return (EFAULT);
+    sf = sf_buf_alloc(m, SFB_CPUPRIVATE);
+    offset = (vm_offset_t)uap->ptr & PAGE_MASK;
 
-    if (fuword(__DEQUALIFY(const int *, uap->ptr)) == uap->value) {
-       if ((pa = pmap_kextract((vm_offset_t)uap->ptr)) == 0)
-           return (EFAULT);
-       m = PHYS_TO_VM_PAGE(pa);
-       vm_page_hold(m);
-
+    if (*(int *)(sf_buf_kva(sf) + offset) == uap->value) {
        if ((timeout = uap->timeout) != 0)
            timeout = (timeout * hz + 999999) / 1000000;
-       waddr = (void *)((intptr_t)pa + ((intptr_t)uap->ptr & PAGE_MASK));
+       waddr = (void *)((intptr_t)VM_PAGE_TO_PHYS(m) + offset);
        error = tsleep(waddr, PCATCH|PDOMAIN_UMTX, "umtxsl", timeout);
-       vm_page_unhold(m);
        /* Can not restart timeout wait. */
        if (timeout != 0 && error == ERESTART)
                error = EINTR;
     } else {
        error = EBUSY;
     }
+
+    sf_buf_free(sf);
+    vm_page_unhold(m);
     return(error);
 }
 
@@ -132,21 +136,27 @@ sys_umtx_sleep(struct umtx_sleep_args *uap)
 int
 sys_umtx_wakeup(struct umtx_wakeup_args *uap)
 {
-    vm_paddr_t pa;
+    vm_page_t m;
+    int offset;
+    int error;
     void *waddr;
 
     cpu_mfence();
-    if (vm_fault_quick((caddr_t)__DEQUALIFY(int *, uap->ptr), VM_PROT_READ) < 0)
+    if ((vm_offset_t)uap->ptr & (sizeof(int) - 1))
        return (EFAULT);
-    if ((pa = pmap_kextract((vm_offset_t)uap->ptr)) == 0)
+    m = vm_fault_page_quick((vm_offset_t)uap->ptr, VM_PROT_READ, &error);
+    if (m == NULL)
        return (EFAULT);
-    waddr = (void *)((intptr_t)pa + ((intptr_t)uap->ptr & PAGE_MASK));
+    offset = (vm_offset_t)uap->ptr & PAGE_MASK;
+    waddr = (void *)((intptr_t)VM_PAGE_TO_PHYS(m) + offset);
+
     if (uap->count == 1) {
        wakeup_domain_one(waddr, PDOMAIN_UMTX);
     } else {
        /* XXX wakes them all up for now */
        wakeup_domain(waddr, PDOMAIN_UMTX);
     }
+    vm_page_unhold(m);
     return(0);
 }
 
index 2b51857..79083f6 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/kern/kern_xio.c,v 1.11 2006/05/07 00:23:08 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_xio.c,v 1.12 2007/01/11 20:53:41 dillon Exp $
  */
 /*
  * Kernel XIO interface.  An initialized XIO is basically a collection of
@@ -93,8 +93,8 @@ int
 xio_init_ubuf(xio_t xio, void *ubase, size_t ubytes, int flags)
 {
     vm_offset_t addr;
-    vm_paddr_t paddr;
     vm_page_t m;
+    int error;
     int i;
     int n;
     int vmprot;
@@ -113,14 +113,9 @@ xio_init_ubuf(xio_t xio, void *ubase, size_t ubytes, int flags)
        if ((n = PAGE_SIZE - xio->xio_offset) > ubytes)
            n = ubytes;
        for (i = 0; n && i < XIO_INTERNAL_PAGES; ++i) {
-           if (vm_fault_quick((caddr_t)addr, vmprot) < 0)
-               break;
-           if ((paddr = pmap_extract(&curproc->p_vmspace->vm_pmap, addr)) == 0)
+           m = vm_fault_page_quick(addr, vmprot, &error);
+           if (m == NULL)
                break;
-           crit_enter();
-           m = PHYS_TO_VM_PAGE(paddr);
-           vm_page_hold(m);
-           crit_exit();
            xio->xio_pages[i] = m;
            ubytes -= n;
            xio->xio_bytes += n;
index 71c88db..660712f 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)vm_extern.h 8.2 (Berkeley) 1/12/94
  * $FreeBSD: src/sys/vm/vm_extern.h,v 1.46.2.3 2003/01/13 22:51:17 dillon Exp $
- * $DragonFly: src/sys/vm/vm_extern.h,v 1.23 2007/01/08 19:41:01 dillon Exp $
+ * $DragonFly: src/sys/vm/vm_extern.h,v 1.24 2007/01/11 20:53:42 dillon Exp $
  */
 
 #ifndef _VM_VM_EXTERN_H_
@@ -111,7 +111,6 @@ void vslock (caddr_t, u_int);
 void vsunlock (caddr_t, u_int);
 void vm_object_print (/* db_expr_t */ long, boolean_t, /* db_expr_t */ long,
                          char *);
-int vm_fault_quick (caddr_t v, int prot);
 
 static __inline
 vm_offset_t
index c1b3626..1418764 100644 (file)
@@ -67,7 +67,7 @@
  * rights to redistribute these changes.
  *
  * $FreeBSD: src/sys/vm/vm_fault.c,v 1.108.2.8 2002/02/26 05:49:27 silby Exp $
- * $DragonFly: src/sys/vm/vm_fault.c,v 1.39 2007/01/11 10:15:21 dillon Exp $
+ * $DragonFly: src/sys/vm/vm_fault.c,v 1.40 2007/01/11 20:53:42 dillon Exp $
  */
 
 /*
@@ -1312,21 +1312,6 @@ readrest:
 }
 
 /*
- * quick version of vm_fault
- */
-int
-vm_fault_quick(caddr_t v, int prot)
-{
-       int r;
-
-       if (prot & VM_PROT_WRITE)
-               r = subyte(v, fubyte(v));
-       else
-               r = fubyte(v);
-       return(r);
-}
-
-/*
  * Wire down a range of virtual addresses in a map.  The entry in question
  * should be marked in-transition and the map must be locked.  We must
  * release the map temporarily while faulting-in the page to avoid a