Source-Changes-HG archive

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

[src/trunk]: src/sys/compat/mach Factor the code for OOL data movement into m...



details:   https://anonhg.NetBSD.org/src/rev/dcb5526fceac
branches:  trunk
changeset: 556181:dcb5526fceac
user:      manu <manu%NetBSD.org@localhost>
date:      Mon Dec 08 19:27:38 2003 +0000

description:
Factor the code for OOL data movement into mach_ool_copyin and
mach_ool_copyout.

Handle port namespace and address space translations when OOL
data moves between different processes (untested)

diffstat:

 sys/compat/mach/mach_iokit.c   |   48 ++-------
 sys/compat/mach/mach_message.c |  202 +++++++++++++++++++++++++++++++++++++++-
 sys/compat/mach/mach_message.h |   12 ++-
 sys/compat/mach/mach_task.c    |   53 +++-------
 4 files changed, 233 insertions(+), 82 deletions(-)

diffs (truncated from 530 to 300 lines):

diff -r d9c829d10e72 -r dcb5526fceac sys/compat/mach/mach_iokit.c
--- a/sys/compat/mach/mach_iokit.c      Mon Dec 08 17:51:53 2003 +0000
+++ b/sys/compat/mach/mach_iokit.c      Mon Dec 08 19:27:38 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mach_iokit.c,v 1.27 2003/12/08 12:03:16 manu Exp $ */
+/*     $NetBSD: mach_iokit.c,v 1.28 2003/12/08 19:27:38 manu Exp $ */
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -39,7 +39,7 @@
 #include "opt_ktrace.h"
 #include "opt_compat_darwin.h"
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mach_iokit.c,v 1.27 2003/12/08 12:03:16 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mach_iokit.c,v 1.28 2003/12/08 19:27:38 manu Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -50,10 +50,6 @@
 #include <sys/proc.h>
 #include <sys/ktrace.h>
 #include <sys/device.h>
-
-#include <uvm/uvm_extern.h>
-#include <uvm/uvm_map.h>
-
 #include <compat/mach/mach_types.h>
 #include <compat/mach/mach_message.h>
 #include <compat/mach/mach_port.h>
@@ -746,7 +742,7 @@
        size_t *msglen = args->rsize; 
        struct lwp *l = args->l;
        int error;
-       vaddr_t va;
+       void *uaddr;
        size_t size;
        mach_port_t mn;
        struct mach_right *mr;
@@ -764,25 +760,14 @@
                return mach_iokit_error(args, MACH_IOKIT_EINVAL);
        size = strlen(mid->mid_properties) + 1; /* Include trailing zero */
 
-       va = vm_map_min(&l->l_proc->p_vmspace->vm_map);
-       if ((error = uvm_map(&l->l_proc->p_vmspace->vm_map, &va, 
-           round_page(size), NULL, UVM_UNKNOWN_OFFSET, 0, 
-           UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_ALL,
-           UVM_INH_COPY, UVM_ADV_NORMAL, UVM_FLAG_COPYONW))) != 0)
-               return mach_msg_error(args, error);
-
-       if ((error = copyout(mid->mid_properties, (void *)va, size)) != 0) {
+       if ((error = mach_ool_copyout(l->l_proc, 
+           mid->mid_properties, &uaddr, size, MACH_OOL_TRACE)) != 0) {
 #ifdef DEBUG_MACH
                printf("pid %d.%d: copyout iokit properties failed\n",
                    l->l_proc->p_pid, l->l_lid);
 #endif
        }
 
-#ifdef KTRACE
-       if (KTRPOINT(l->l_proc, KTR_MOOL) && error == 0)
-               ktrmool(l->l_proc, mid->mid_properties, size, (void *)va);
-#endif
-
        rep->rep_msgh.msgh_bits = 
            MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE) |
            MACH_MSGH_BITS_COMPLEX;
@@ -790,7 +775,7 @@
        rep->rep_msgh.msgh_local_port = req->req_msgh.msgh_local_port;
        rep->rep_msgh.msgh_id = req->req_msgh.msgh_id + 100;
        rep->rep_body.msgh_descriptor_count = 1;
-       rep->rep_properties.address = (void *)va;
+       rep->rep_properties.address = uaddr;
        rep->rep_properties.size = size;
        rep->rep_properties.deallocate = 0;
        rep->rep_properties.copy = MACH_MSG_ALLOCATE;
@@ -811,7 +796,7 @@
        size_t *msglen = args->rsize; 
        struct lwp *l = args->l;
        int error;
-       vaddr_t va;
+       void *uaddr;
        size_t size;
        mach_port_t mn;
        struct mach_right *mr;
@@ -848,28 +833,17 @@
 
        if (mip->mip_value == NULL)
                return mach_iokit_error(args, MACH_IOKIT_ENOENT);
-
-       /* And copyout its associated value */
-       va = vm_map_min(&l->l_proc->p_vmspace->vm_map);
        size = strlen(mip->mip_value) + 1; /* Include trailing zero */
 
-       if ((error = uvm_map(&l->l_proc->p_vmspace->vm_map, &va, 
-           round_page(size), NULL, UVM_UNKNOWN_OFFSET, 0, 
-           UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_ALL,
-           UVM_INH_COPY, UVM_ADV_NORMAL, UVM_FLAG_COPYONW))) != 0)
-               return mach_msg_error(args, error);
-
-       if ((error = copyout(mip->mip_value, (void *)va, size)) != 0) {
+       /* And copyout its associated value */
+       if ((error = mach_ool_copyout(l->l_proc, 
+           (void *)mip->mip_value, &uaddr, size, MACH_OOL_TRACE)) != 0) {
 #ifdef DEBUG_MACH
                printf("pid %d.%d: copyout iokit property failed\n",
                    l->l_proc->p_pid, l->l_lid);
 #endif
        }
 
-#ifdef KTRACE
-       if (KTRPOINT(l->l_proc, KTR_MOOL) && error == 0)
-               ktrmool(l->l_proc, mip->mip_value, size, (void *)va);
-#endif
        rep->rep_msgh.msgh_bits = 
            MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE) |
            MACH_MSGH_BITS_COMPLEX;
@@ -877,7 +851,7 @@
        rep->rep_msgh.msgh_local_port = req->req_msgh.msgh_local_port;
        rep->rep_msgh.msgh_id = req->req_msgh.msgh_id + 100;
        rep->rep_body.msgh_descriptor_count = 1;
-       rep->rep_properties.address = (void *)va;
+       rep->rep_properties.address = uaddr;
        rep->rep_properties.size = size;
        rep->rep_properties.deallocate = 0;
        rep->rep_properties.copy = MACH_MSG_ALLOCATE;
diff -r d9c829d10e72 -r dcb5526fceac sys/compat/mach/mach_message.c
--- a/sys/compat/mach/mach_message.c    Mon Dec 08 17:51:53 2003 +0000
+++ b/sys/compat/mach/mach_message.c    Mon Dec 08 19:27:38 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mach_message.c,v 1.35 2003/12/08 12:02:24 manu Exp $ */
+/*     $NetBSD: mach_message.c,v 1.36 2003/12/08 19:27:38 manu Exp $ */
 
 /*-
  * Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mach_message.c,v 1.35 2003/12/08 12:02:24 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mach_message.c,v 1.36 2003/12/08 19:27:38 manu Exp $");
 
 #include "opt_ktrace.h"
 #include "opt_compat_mach.h" /* For COMPAT_MACH in <sys/ktrace.h> */
@@ -56,6 +56,9 @@
 #include <sys/ktrace.h>
 #endif 
 
+#include <uvm/uvm_extern.h>
+#include <uvm/uvm_map.h>
+
 #include <compat/mach/mach_types.h>
 #include <compat/mach/mach_message.h>
 #include <compat/mach/mach_port.h>
@@ -845,19 +848,204 @@
        }
 
        for (i = 0; i < count; i++) {
-               if (mcm->mcm_desc[i].type != MACH_MSG_PORT_DESCRIPTOR) {
+               switch (mcm->mcm_desc[i].type) {
+               case MACH_MSG_PORT_DESCRIPTOR:
+                       mach_trade_rights(l, mm->mm_l, 
+                           &mcm->mcm_port_desc[i].name, 
+                           mcm->mcm_port_desc[i].disposition);
+                       break;
+
+               case MACH_MSG_OOL_PORTS_DESCRIPTOR: {   /* XXX untested */
+                       struct proc *rp;        /* remote process */
+                       struct proc *lp;        /* local process */
+                       void *lumnp;            /* local user address */
+                       void *rumnp;            /* remote user address */
+                       int disp;               /* disposition*/
+                       size_t size;            /* data size */
+                       int count;              /* descriptor count */
+                       mach_port_t *kmnp;
+                       void *kaddr;
+                       int error;      
+                       int j;
+                       
+                       rp = mm->mm_l->l_proc;
+                       lp = l->l_proc;
+                       disp = mcm->mcm_ool_ports_desc[i].disposition;
+                       rumnp = mcm->mcm_ool_ports_desc[i].address;
+                       count = mcm->mcm_ool_ports_desc[i].count;
+                       size = count * sizeof(*kmnp);
+                       kaddr = NULL;
+                       lumnp = NULL;
+
+                       /* This allocates kmnp */
+                       error = mach_ool_copyin(rp, rumnp, &kaddr, size, 0);
+                       if (error != 0)
+                               return MACH_SEND_INVALID_DATA;
+
+                       kmnp = (mach_port_t *)kaddr;
+                       for (j = 0; j < count; j++) 
+                               mach_trade_rights(l, mm->mm_l, &kmnp[j], disp);
+
+                       /* This frees kmnp */
+                       if ((error = mach_ool_copyout(lp, kmnp, &lumnp, 
+                           size, MACH_OOL_FREE|MACH_OOL_TRACE)) != 0)
+                               return MACH_SEND_INVALID_DATA;
+
+                       mcm->mcm_ool_ports_desc[i].address = lumnp;
+                       break;
+               }
+
+               case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
 #ifdef DEBUG_MACH
-                       printf("OOL data in task to task message\n");
+                       printf("MACH_MSG_OOL_VOLATILE_DESCRIPTOR\n");
 #endif
-                       continue;
+                       /* FALLTHROUGH */
+               case MACH_MSG_OOL_DESCRIPTOR: { /* XXX untested */
+                       struct proc *rp;        /* remote process */
+                       struct proc *lp;        /* local process */
+                       void *ludata;           /* local user address */
+                       void *rudata;           /* remote user address */
+                       size_t size;            /* data size */
+                       void *kdata;
+                       int error;      
+                       
+                       rp = mm->mm_l->l_proc;
+                       lp = l->l_proc;
+                       rudata = mcm->mcm_ool_desc[i].address;
+                       size = mcm->mcm_ool_desc[i].size;
+                       kdata = NULL;
+                       ludata = NULL;
+
+                       /* 
+                        * XXX This is unefficient for large chunk of OOL
+                        * memory. Think about remapping COW when possible
+                        */ 
+
+                       /* This allocates kdata */
+                       error = mach_ool_copyin(rp, rudata, &kdata, size, 0);
+                       if (error != 0)
+                               return MACH_SEND_INVALID_DATA;
+
+                       /* This frees kdata */
+                       if ((error = mach_ool_copyout(lp, kdata, &ludata, 
+                           size, MACH_OOL_FREE|MACH_OOL_TRACE)) != 0)
+                               return MACH_SEND_INVALID_DATA;
+
+                       mcm->mcm_ool_ports_desc[i].address = ludata;
+                       break;
                }
-               mach_trade_rights(l, mm->mm_l, &mcm->mcm_port_desc[i].name, 
-                   mcm->mcm_port_desc[i].disposition);
+               default:
+#ifdef DEBUG_MACH
+                       printf("unknown descriptor type %d\n",
+                           mcm->mcm_desc[i].type);
+#endif
+                       break;
+               }
        }
 
        return MACH_MSG_SUCCESS;
 }
 
+inline int
+mach_ool_copyin(p, uaddr, kaddr, size, flags)
+       struct proc *p;
+       const void *uaddr;
+       void **kaddr;
+       size_t size;
+       int flags;
+{
+       int error;
+       void *kbuf;
+
+       /* 
+        * Sanity check OOL size to avoid DoS on malloc: useless once
+        * we remap data instead of copying it. In the meantime, 
+        * disabled since it makes some OOL transfer fail 
+        */
+#if 0
+       if (size > MACH_MAX_OOL_LEN)
+               return ENOMEM;
+#endif
+
+       if (*kaddr == NULL)
+               kbuf = malloc(size, M_EMULDATA, M_WAITOK);
+       else
+               kbuf = *kaddr;
+
+       if ((error = copyin_proc(p, (void *)uaddr, kbuf, size)) != 0) {
+               if (*kaddr == NULL)
+                       free(kbuf, M_EMULDATA);
+               return error;
+       }
+
+#ifdef KTRACE
+       if (size > PAGE_SIZE)
+               size = PAGE_SIZE;
+       if ((flags & MACH_OOL_TRACE) && KTRPOINT(p, KTR_MOOL))
+               ktrmool(p, kaddr, size, uaddr);
+#endif
+
+       *kaddr = kbuf;



Home | Main Index | Thread Index | Old Index