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