Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-1-6]: src/sys/kern Pull up revision 1.82 (requested by thorpej in...



details:   https://anonhg.NetBSD.org/src/rev/70e27113667d
branches:  netbsd-1-6
changeset: 529308:70e27113667d
user:      tron <tron%NetBSD.org@localhost>
date:      Sat Nov 09 10:21:36 2002 +0000

description:
Pull up revision 1.82 (requested by thorpej in ticket #527):
* Add copyin_proc() and copyout_proc(), which are like copyin() and
  copyout(), except they can operate on any process, not just curproc.
* Use this in uiomove() to allow UIO_USERSPACE to non-curproc.

diffstat:

 sys/kern/kern_subr.c |  95 +++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 84 insertions(+), 11 deletions(-)

diffs (139 lines):

diff -r d46abda00c2d -r 70e27113667d sys/kern/kern_subr.c
--- a/sys/kern/kern_subr.c      Sat Nov 09 10:21:27 2002 +0000
+++ b/sys/kern/kern_subr.c      Sat Nov 09 10:21:36 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_subr.c,v 1.80 2002/03/17 22:19:20 christos Exp $  */
+/*     $NetBSD: kern_subr.c,v 1.80.6.1 2002/11/09 10:21:36 tron Exp $  */
 
 /*-
  * Copyright (c) 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_subr.c,v 1.80 2002/03/17 22:19:20 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_subr.c,v 1.80.6.1 2002/11/09 10:21:36 tron Exp $");
 
 #include "opt_ddb.h"
 #include "opt_md.h"
@@ -106,6 +106,8 @@
 #include <sys/disklabel.h>
 #include <sys/queue.h>
 
+#include <uvm/uvm_extern.h>
+
 #include <dev/cons.h>
 
 #include <net/if.h>
@@ -147,8 +149,6 @@
 #ifdef DIAGNOSTIC
        if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE)
                panic("uiomove: mode");
-       if (uio->uio_segflg == UIO_USERSPACE && p != curproc)
-               panic("uiomove proc");
 #endif
        while (n > 0 && uio->uio_resid) {
                iov = uio->uio_iov;
@@ -163,15 +163,22 @@
                switch (uio->uio_segflg) {
 
                case UIO_USERSPACE:
-                       KDASSERT(p->p_cpu != NULL);
-                       KDASSERT(p->p_cpu == curcpu());
-                       if (p->p_cpu->ci_schedstate.spc_flags &
+                       if (curproc->p_cpu->ci_schedstate.spc_flags &
                            SPCF_SHOULDYIELD)
                                preempt(NULL);
-                       if (uio->uio_rw == UIO_READ)
-                               error = copyout(cp, iov->iov_base, cnt);
-                       else
-                               error = copyin(iov->iov_base, cp, cnt);
+                       if (__predict_true(p == curproc)) {
+                               if (uio->uio_rw == UIO_READ)
+                                       error = copyout(cp, iov->iov_base, cnt);
+                               else
+                                       error = copyin(iov->iov_base, cp, cnt);
+                       } else {
+                               if (uio->uio_rw == UIO_READ)
+                                       error = copyout_proc(p, cp,
+                                           iov->iov_base, cnt);
+                               else
+                                       error = copyin_proc(p, iov->iov_base,
+                                           cp, cnt);
+                       }
                        if (error)
                                return (error);
                        break;
@@ -235,6 +242,72 @@
 }
 
 /*
+ * Like copyin(), but operates on an arbitrary process.
+ */
+int
+copyin_proc(struct proc *p, const void *uaddr, void *kaddr, size_t len)
+{
+       struct iovec iov;
+       struct uio uio;
+       int error;
+
+       if (len == 0)
+               return (0);
+
+       iov.iov_base = kaddr;
+       iov.iov_len = len;
+       uio.uio_iov = &iov;
+       uio.uio_iovcnt = 1;
+       uio.uio_offset = (off_t)(intptr_t)uaddr;
+       uio.uio_resid = len;
+       uio.uio_segflg = UIO_SYSSPACE;
+       uio.uio_rw = UIO_READ;
+       uio.uio_procp = NULL;
+
+       /* XXXCDC: how should locking work here? */
+       if ((p->p_flag & P_WEXIT) || (p->p_vmspace->vm_refcnt < 1))
+               return (EFAULT);
+       p->p_vmspace->vm_refcnt++;      /* XXX */
+       error = uvm_io(&p->p_vmspace->vm_map, &uio);
+       uvmspace_free(p->p_vmspace);
+
+       return (error);
+}
+
+/*
+ * Like copyout(), but operates on an arbitrary process.
+ */
+int
+copyout_proc(struct proc *p, const void *kaddr, void *uaddr, size_t len)
+{
+       struct iovec iov;
+       struct uio uio;
+       int error;
+
+       if (len == 0)
+               return (0);
+
+       iov.iov_base = (void *) kaddr;  /* XXX cast away const */
+       iov.iov_len = len;
+       uio.uio_iov = &iov;
+       uio.uio_iovcnt = 1;
+       uio.uio_offset = (off_t)(intptr_t)uaddr;
+       uio.uio_resid = len;
+       uio.uio_segflg = UIO_SYSSPACE;
+       uio.uio_rw = UIO_WRITE;
+       uio.uio_procp = NULL;
+
+       /* XXXCDC: how should locking work here? */
+       if ((p->p_flag & P_WEXIT) || (p->p_vmspace->vm_refcnt < 1))
+               return (EFAULT);
+       p->p_vmspace->vm_refcnt++;      /* XXX */
+       error = uvm_io(&p->p_vmspace->vm_map, &uio);
+       uvmspace_free(p->p_vmspace);
+
+       return (error);
+}
+
+/*
  * General routine to allocate a hash table.
  * Allocate enough memory to hold at least `elements' list-head pointers.
  * Return a pointer to the allocated space and set *hashmask to a pattern



Home | Main Index | Thread Index | Old Index