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)
This commit is contained in:
parent
5c9b8df403
commit
98f233296d
|
@ -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.
|
* Copyright (c) 2003 The NetBSD Foundation, Inc.
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
#include "opt_ktrace.h"
|
#include "opt_ktrace.h"
|
||||||
#include "opt_compat_darwin.h"
|
#include "opt_compat_darwin.h"
|
||||||
#include <sys/cdefs.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/types.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
@ -50,10 +50,6 @@ __KERNEL_RCSID(0, "$NetBSD: mach_iokit.c,v 1.27 2003/12/08 12:03:16 manu Exp $")
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
#include <sys/ktrace.h>
|
#include <sys/ktrace.h>
|
||||||
#include <sys/device.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_types.h>
|
||||||
#include <compat/mach/mach_message.h>
|
#include <compat/mach/mach_message.h>
|
||||||
#include <compat/mach/mach_port.h>
|
#include <compat/mach/mach_port.h>
|
||||||
|
@ -746,7 +742,7 @@ mach_io_registry_entry_get_properties(args)
|
||||||
size_t *msglen = args->rsize;
|
size_t *msglen = args->rsize;
|
||||||
struct lwp *l = args->l;
|
struct lwp *l = args->l;
|
||||||
int error;
|
int error;
|
||||||
vaddr_t va;
|
void *uaddr;
|
||||||
size_t size;
|
size_t size;
|
||||||
mach_port_t mn;
|
mach_port_t mn;
|
||||||
struct mach_right *mr;
|
struct mach_right *mr;
|
||||||
|
@ -764,25 +760,14 @@ mach_io_registry_entry_get_properties(args)
|
||||||
return mach_iokit_error(args, MACH_IOKIT_EINVAL);
|
return mach_iokit_error(args, MACH_IOKIT_EINVAL);
|
||||||
size = strlen(mid->mid_properties) + 1; /* Include trailing zero */
|
size = strlen(mid->mid_properties) + 1; /* Include trailing zero */
|
||||||
|
|
||||||
va = vm_map_min(&l->l_proc->p_vmspace->vm_map);
|
if ((error = mach_ool_copyout(l->l_proc,
|
||||||
if ((error = uvm_map(&l->l_proc->p_vmspace->vm_map, &va,
|
mid->mid_properties, &uaddr, size, MACH_OOL_TRACE)) != 0) {
|
||||||
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) {
|
|
||||||
#ifdef DEBUG_MACH
|
#ifdef DEBUG_MACH
|
||||||
printf("pid %d.%d: copyout iokit properties failed\n",
|
printf("pid %d.%d: copyout iokit properties failed\n",
|
||||||
l->l_proc->p_pid, l->l_lid);
|
l->l_proc->p_pid, l->l_lid);
|
||||||
#endif
|
#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 =
|
rep->rep_msgh.msgh_bits =
|
||||||
MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE) |
|
MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE) |
|
||||||
MACH_MSGH_BITS_COMPLEX;
|
MACH_MSGH_BITS_COMPLEX;
|
||||||
|
@ -790,7 +775,7 @@ mach_io_registry_entry_get_properties(args)
|
||||||
rep->rep_msgh.msgh_local_port = req->req_msgh.msgh_local_port;
|
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_msgh.msgh_id = req->req_msgh.msgh_id + 100;
|
||||||
rep->rep_body.msgh_descriptor_count = 1;
|
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.size = size;
|
||||||
rep->rep_properties.deallocate = 0;
|
rep->rep_properties.deallocate = 0;
|
||||||
rep->rep_properties.copy = MACH_MSG_ALLOCATE;
|
rep->rep_properties.copy = MACH_MSG_ALLOCATE;
|
||||||
|
@ -811,7 +796,7 @@ mach_io_registry_entry_get_property(args)
|
||||||
size_t *msglen = args->rsize;
|
size_t *msglen = args->rsize;
|
||||||
struct lwp *l = args->l;
|
struct lwp *l = args->l;
|
||||||
int error;
|
int error;
|
||||||
vaddr_t va;
|
void *uaddr;
|
||||||
size_t size;
|
size_t size;
|
||||||
mach_port_t mn;
|
mach_port_t mn;
|
||||||
struct mach_right *mr;
|
struct mach_right *mr;
|
||||||
|
@ -848,28 +833,17 @@ mach_io_registry_entry_get_property(args)
|
||||||
|
|
||||||
if (mip->mip_value == NULL)
|
if (mip->mip_value == NULL)
|
||||||
return mach_iokit_error(args, MACH_IOKIT_ENOENT);
|
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 */
|
size = strlen(mip->mip_value) + 1; /* Include trailing zero */
|
||||||
|
|
||||||
if ((error = uvm_map(&l->l_proc->p_vmspace->vm_map, &va,
|
/* And copyout its associated value */
|
||||||
round_page(size), NULL, UVM_UNKNOWN_OFFSET, 0,
|
if ((error = mach_ool_copyout(l->l_proc,
|
||||||
UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_ALL,
|
(void *)mip->mip_value, &uaddr, size, MACH_OOL_TRACE)) != 0) {
|
||||||
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) {
|
|
||||||
#ifdef DEBUG_MACH
|
#ifdef DEBUG_MACH
|
||||||
printf("pid %d.%d: copyout iokit property failed\n",
|
printf("pid %d.%d: copyout iokit property failed\n",
|
||||||
l->l_proc->p_pid, l->l_lid);
|
l->l_proc->p_pid, l->l_lid);
|
||||||
#endif
|
#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 =
|
rep->rep_msgh.msgh_bits =
|
||||||
MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE) |
|
MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE) |
|
||||||
MACH_MSGH_BITS_COMPLEX;
|
MACH_MSGH_BITS_COMPLEX;
|
||||||
|
@ -877,7 +851,7 @@ mach_io_registry_entry_get_property(args)
|
||||||
rep->rep_msgh.msgh_local_port = req->req_msgh.msgh_local_port;
|
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_msgh.msgh_id = req->req_msgh.msgh_id + 100;
|
||||||
rep->rep_body.msgh_descriptor_count = 1;
|
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.size = size;
|
||||||
rep->rep_properties.deallocate = 0;
|
rep->rep_properties.deallocate = 0;
|
||||||
rep->rep_properties.copy = MACH_MSG_ALLOCATE;
|
rep->rep_properties.copy = MACH_MSG_ALLOCATE;
|
||||||
|
|
|
@ -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.
|
* Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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_ktrace.h"
|
||||||
#include "opt_compat_mach.h" /* For COMPAT_MACH in <sys/ktrace.h> */
|
#include "opt_compat_mach.h" /* For COMPAT_MACH in <sys/ktrace.h> */
|
||||||
|
@ -56,6 +56,9 @@ __KERNEL_RCSID(0, "$NetBSD: mach_message.c,v 1.35 2003/12/08 12:02:24 manu Exp $
|
||||||
#include <sys/ktrace.h>
|
#include <sys/ktrace.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <uvm/uvm_extern.h>
|
||||||
|
#include <uvm/uvm_map.h>
|
||||||
|
|
||||||
#include <compat/mach/mach_types.h>
|
#include <compat/mach/mach_types.h>
|
||||||
#include <compat/mach/mach_message.h>
|
#include <compat/mach/mach_message.h>
|
||||||
#include <compat/mach/mach_port.h>
|
#include <compat/mach/mach_port.h>
|
||||||
|
@ -845,19 +848,204 @@ mach_trade_rights_complex(l, mm)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
if (mcm->mcm_desc[i].type != MACH_MSG_PORT_DESCRIPTOR) {
|
switch (mcm->mcm_desc[i].type) {
|
||||||
#ifdef DEBUG_MACH
|
case MACH_MSG_PORT_DESCRIPTOR:
|
||||||
printf("OOL data in task to task message\n");
|
mach_trade_rights(l, mm->mm_l,
|
||||||
#endif
|
&mcm->mcm_port_desc[i].name,
|
||||||
continue;
|
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("MACH_MSG_OOL_VOLATILE_DESCRIPTOR\n");
|
||||||
|
#endif
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
#ifdef DEBUG_MACH
|
||||||
|
printf("unknown descriptor type %d\n",
|
||||||
|
mcm->mcm_desc[i].type);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
mach_trade_rights(l, mm->mm_l, &mcm->mcm_port_desc[i].name,
|
|
||||||
mcm->mcm_port_desc[i].disposition);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return MACH_MSG_SUCCESS;
|
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;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int
|
||||||
|
mach_ool_copyout(p, kaddr, uaddr, size, flags)
|
||||||
|
struct proc *p;
|
||||||
|
void *kaddr;
|
||||||
|
void **uaddr;
|
||||||
|
size_t size;
|
||||||
|
int flags;
|
||||||
|
{
|
||||||
|
vaddr_t ubuf;
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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) {
|
||||||
|
error = ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (*uaddr == NULL)
|
||||||
|
ubuf = (vaddr_t)vm_map_min(&p->p_vmspace->vm_map);
|
||||||
|
else
|
||||||
|
ubuf = (vaddr_t)*uaddr;
|
||||||
|
|
||||||
|
/* Never map anything at address zero: this is a red zone */
|
||||||
|
if (ubuf == (vaddr_t)NULL)
|
||||||
|
ubuf += PAGE_SIZE;
|
||||||
|
|
||||||
|
if ((error = uvm_map(&p->p_vmspace->vm_map, &ubuf,
|
||||||
|
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)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if ((error = copyout_proc(p, kaddr, (void *)ubuf, size)) != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
#ifdef KTRACE
|
||||||
|
if (size > PAGE_SIZE)
|
||||||
|
size = PAGE_SIZE;
|
||||||
|
if ((flags & MACH_OOL_TRACE) && KTRPOINT(p, KTR_MOOL))
|
||||||
|
ktrmool(p, kaddr, size, (void *)ubuf);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (flags & MACH_OOL_FREE)
|
||||||
|
free(kaddr, M_EMULDATA);
|
||||||
|
|
||||||
|
if (error == 0)
|
||||||
|
*uaddr = (void *)ubuf;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
mach_message_init(void)
|
mach_message_init(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: mach_message.h,v 1.21 2003/12/08 12:02:24 manu Exp $ */
|
/* $NetBSD: mach_message.h,v 1.22 2003/12/08 19:27:38 manu Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2001-2003 The NetBSD Foundation, Inc.
|
* Copyright (c) 2001-2003 The NetBSD Foundation, Inc.
|
||||||
|
@ -153,6 +153,7 @@ typedef unsigned int mach_msg_descriptor_type_t;
|
||||||
#define MACH_MSG_OOL_VOLATILE_DESCRIPTOR 3
|
#define MACH_MSG_OOL_VOLATILE_DESCRIPTOR 3
|
||||||
|
|
||||||
#define MACH_MAX_MSG_LEN 65536
|
#define MACH_MAX_MSG_LEN 65536
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
mach_msg_bits_t msgh_bits;
|
mach_msg_bits_t msgh_bits;
|
||||||
mach_msg_size_t msgh_size;
|
mach_msg_size_t msgh_size;
|
||||||
|
@ -220,7 +221,7 @@ struct mach_complex_msg {
|
||||||
union {
|
union {
|
||||||
mach_msg_type_descriptor_t mcm_desc[1];
|
mach_msg_type_descriptor_t mcm_desc[1];
|
||||||
mach_msg_port_descriptor_t mcm_port_desc[1];
|
mach_msg_port_descriptor_t mcm_port_desc[1];
|
||||||
mach_msg_ool_ports_descriptor_t mcm_ool_port_desc[1];
|
mach_msg_ool_ports_descriptor_t mcm_ool_ports_desc[1];
|
||||||
mach_msg_ool_descriptor_t mcm_ool_desc[1];
|
mach_msg_ool_descriptor_t mcm_ool_desc[1];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -256,6 +257,13 @@ struct mach_message {
|
||||||
struct lwp *mm_l; /* The thread that sent it */
|
struct lwp *mm_l; /* The thread that sent it */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Flags for mach_ool_copy{in|out} */
|
||||||
|
#define MACH_OOL_NONE 0x0
|
||||||
|
#define MACH_OOL_FREE 0x1 /* Free kernel buffer after copyout */
|
||||||
|
#define MACH_OOL_TRACE 0x2 /* ktrace OOL data */
|
||||||
|
|
||||||
|
inline int mach_ool_copyin(struct proc *, const void *, void **, size_t, int);
|
||||||
|
inline int mach_ool_copyout(struct proc *, void *, void **, size_t, int);
|
||||||
void mach_message_init(void);
|
void mach_message_init(void);
|
||||||
struct mach_message *mach_message_get(mach_msg_header_t *,
|
struct mach_message *mach_message_get(mach_msg_header_t *,
|
||||||
size_t, struct mach_port *, struct lwp *);
|
size_t, struct mach_port *, struct lwp *);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: mach_task.c,v 1.47 2003/12/08 12:03:16 manu Exp $ */
|
/* $NetBSD: mach_task.c,v 1.48 2003/12/08 19:27:38 manu Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
|
* Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
#include "opt_compat_darwin.h"
|
#include "opt_compat_darwin.h"
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: mach_task.c,v 1.47 2003/12/08 12:03:16 manu Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: mach_task.c,v 1.48 2003/12/08 19:27:38 manu Exp $");
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
@ -139,10 +139,11 @@ mach_ports_lookup(args)
|
||||||
size_t *msglen = args->rsize;
|
size_t *msglen = args->rsize;
|
||||||
struct lwp *l = args->l;
|
struct lwp *l = args->l;
|
||||||
struct lwp *tl = args->tl;
|
struct lwp *tl = args->tl;
|
||||||
|
struct proc *p = l->l_proc;
|
||||||
struct mach_emuldata *med;
|
struct mach_emuldata *med;
|
||||||
struct mach_right *mr;
|
struct mach_right *mr;
|
||||||
mach_port_name_t mnp[7];
|
mach_port_name_t mnp[7];
|
||||||
vaddr_t va;
|
void *uaddr;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -151,12 +152,6 @@ mach_ports_lookup(args)
|
||||||
* filled. We have to see more of this in order to fully understand
|
* filled. We have to see more of this in order to fully understand
|
||||||
* how this trap works.
|
* how this trap works.
|
||||||
*/
|
*/
|
||||||
va = vm_map_min(&l->l_proc->p_vmspace->vm_map);
|
|
||||||
if ((error = uvm_map(&l->l_proc->p_vmspace->vm_map, &va, 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);
|
|
||||||
|
|
||||||
med = (struct mach_emuldata *)tl->l_proc->p_emuldata;
|
med = (struct mach_emuldata *)tl->l_proc->p_emuldata;
|
||||||
mnp[0] = (mach_port_name_t)MACH_PORT_DEAD;
|
mnp[0] = (mach_port_name_t)MACH_PORT_DEAD;
|
||||||
mnp[3] = (mach_port_name_t)MACH_PORT_DEAD;
|
mnp[3] = (mach_port_name_t)MACH_PORT_DEAD;
|
||||||
|
@ -173,13 +168,11 @@ mach_ports_lookup(args)
|
||||||
/*
|
/*
|
||||||
* On Darwin, the data seems always null...
|
* On Darwin, the data seems always null...
|
||||||
*/
|
*/
|
||||||
if ((error = copyout(mnp, (void *)va, sizeof(mnp))) != 0)
|
uaddr = NULL;
|
||||||
|
if ((error = mach_ool_copyout(p, &mnp[0],
|
||||||
|
&uaddr, sizeof(mnp), MACH_OOL_TRACE)) != 0)
|
||||||
return mach_msg_error(args, error);
|
return mach_msg_error(args, error);
|
||||||
|
|
||||||
#ifdef KTRACE
|
|
||||||
if (KTRPOINT(l->l_proc, KTR_MOOL) && error == 0)
|
|
||||||
ktrmool(l->l_proc, mnp, sizeof(mnp), (void *)va);
|
|
||||||
#endif
|
|
||||||
rep->rep_msgh.msgh_bits =
|
rep->rep_msgh.msgh_bits =
|
||||||
MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE) |
|
MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE) |
|
||||||
MACH_MSGH_BITS_COMPLEX;
|
MACH_MSGH_BITS_COMPLEX;
|
||||||
|
@ -187,7 +180,7 @@ mach_ports_lookup(args)
|
||||||
rep->rep_msgh.msgh_local_port = req->req_msgh.msgh_local_port;
|
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_msgh.msgh_id = req->req_msgh.msgh_id + 100;
|
||||||
rep->rep_msgh_body.msgh_descriptor_count = 1;
|
rep->rep_msgh_body.msgh_descriptor_count = 1;
|
||||||
rep->rep_init_port_set.address = (void *)va;
|
rep->rep_init_port_set.address = uaddr;
|
||||||
rep->rep_init_port_set.count = 3; /* XXX should be 7? */
|
rep->rep_init_port_set.count = 3; /* XXX should be 7? */
|
||||||
rep->rep_init_port_set.copy = MACH_MSG_ALLOCATE;
|
rep->rep_init_port_set.copy = MACH_MSG_ALLOCATE;
|
||||||
rep->rep_init_port_set.disposition = MACH_MSG_TYPE_MOVE_SEND;
|
rep->rep_init_port_set.disposition = MACH_MSG_TYPE_MOVE_SEND;
|
||||||
|
@ -301,39 +294,27 @@ mach_task_threads(args)
|
||||||
struct proc *tp = tl->l_proc;
|
struct proc *tp = tl->l_proc;
|
||||||
struct mach_emuldata *med;
|
struct mach_emuldata *med;
|
||||||
int error;
|
int error;
|
||||||
vaddr_t va;
|
void *uaddr;
|
||||||
size_t size;
|
size_t size;
|
||||||
int i;
|
int i;
|
||||||
struct mach_right *mr;
|
struct mach_right *mr;
|
||||||
mach_port_name_t *mnp;
|
mach_port_name_t *mnp;
|
||||||
|
|
||||||
med = tp->p_emuldata;
|
med = tp->p_emuldata;
|
||||||
|
|
||||||
size = tp->p_nlwps * sizeof(*mnp);
|
size = tp->p_nlwps * sizeof(*mnp);
|
||||||
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);
|
|
||||||
|
|
||||||
mnp = malloc(size, M_TEMP, M_WAITOK);
|
mnp = malloc(size, M_TEMP, M_WAITOK);
|
||||||
for (i = 0; i < l->l_proc->p_nlwps; i++) {
|
uaddr = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < tp->p_nlwps; i++) {
|
||||||
/* XXX each thread should have a kernel port */
|
/* XXX each thread should have a kernel port */
|
||||||
mr = mach_right_get(med->med_kernel, l, MACH_PORT_TYPE_SEND, 0);
|
mr = mach_right_get(med->med_kernel, l, MACH_PORT_TYPE_SEND, 0);
|
||||||
mnp[i] = mr->mr_name;
|
mnp[i] = mr->mr_name;
|
||||||
}
|
}
|
||||||
if ((error = copyout(mnp, (void *)va, size)) != 0) {
|
|
||||||
free(mnp, M_TEMP);
|
|
||||||
return mach_msg_error(args, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef KTRACE
|
/* This will free mnp */
|
||||||
if (KTRPOINT(l->l_proc, KTR_MOOL) && error == 0)
|
if ((error = mach_ool_copyout(l->l_proc, mnp, &uaddr,
|
||||||
ktrmool(l->l_proc, mnp, size, (void *)va);
|
size, MACH_OOL_TRACE|MACH_OOL_FREE)) != 0)
|
||||||
#endif
|
return mach_msg_error(args, error);
|
||||||
free(mnp, M_TEMP);
|
|
||||||
|
|
||||||
rep->rep_msgh.msgh_bits =
|
rep->rep_msgh.msgh_bits =
|
||||||
MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE) |
|
MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE) |
|
||||||
|
@ -342,7 +323,7 @@ mach_task_threads(args)
|
||||||
rep->rep_msgh.msgh_local_port = req->req_msgh.msgh_local_port;
|
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_msgh.msgh_id = req->req_msgh.msgh_id + 100;
|
||||||
rep->rep_body.msgh_descriptor_count = 1;
|
rep->rep_body.msgh_descriptor_count = 1;
|
||||||
rep->rep_list.address = (void *)va;
|
rep->rep_list.address = uaddr;
|
||||||
rep->rep_list.count = tp->p_nlwps;
|
rep->rep_list.count = tp->p_nlwps;
|
||||||
rep->rep_list.copy = MACH_MSG_ALLOCATE;
|
rep->rep_list.copy = MACH_MSG_ALLOCATE;
|
||||||
rep->rep_list.disposition = MACH_MSG_TYPE_MOVE_SEND;
|
rep->rep_list.disposition = MACH_MSG_TYPE_MOVE_SEND;
|
||||||
|
|
Loading…
Reference in New Issue