Several things:

1) rights should be shared by the threads within a process. While it would
be easier to handle this with the struct proc/struct lwp split, we attempt to
do this now by sharing the right lists. Because each right holds a reference
to struct proc, this might cause some problems later.
2) in pthread_exit, really exit the thread. Also reintialize the righ tlist to
make sure we will not destroy the parent's right list
3) rights can hold multiple permissions on a port (ie: send and receive). Fix th
is.
4) first attempt on right carried by messages. We still have to do rights carrie
d in the message body (complex messages).
This commit is contained in:
manu 2002-12-27 09:59:24 +00:00
parent 1a8833b7c1
commit f464631d66
13 changed files with 313 additions and 191 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: mach_machdep.c,v 1.6 2002/12/12 17:42:10 christos Exp $ */ /* $NetBSD: mach_machdep.c,v 1.7 2002/12/27 09:59:24 manu Exp $ */
/*- /*-
* Copyright (c) 2000 The NetBSD Foundation, Inc. * Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mach_machdep.c,v 1.6 2002/12/12 17:42:10 christos Exp $"); __KERNEL_RCSID(0, "$NetBSD: mach_machdep.c,v 1.7 2002/12/27 09:59:24 manu Exp $");
#if defined(_KERNEL_OPT) #if defined(_KERNEL_OPT)
#include "opt_vm86.h" #include "opt_vm86.h"
@ -144,6 +144,10 @@ void
mach_create_thread_child(arg) mach_create_thread_child(arg)
void *arg; void *arg;
{ {
/*
* This is a plain copy of the powerpc version.
* It should be converted to i386 MD bits.
*/
#ifdef notyet #ifdef notyet
struct mach_create_thread_child_args *mctc; struct mach_create_thread_child_args *mctc;
struct proc *p; struct proc *p;
@ -151,6 +155,7 @@ mach_create_thread_child(arg)
struct exec_macho_powerpc_thread_state *regs; struct exec_macho_powerpc_thread_state *regs;
mctc = (struct mach_create_thread_child_args *)arg; mctc = (struct mach_create_thread_child_args *)arg;
p = *mctc->mctc_proc;
if (mctc->mctc_flavor != MACHO_POWERPC_THREAD_STATE) { if (mctc->mctc_flavor != MACHO_POWERPC_THREAD_STATE) {
mctc->mctc_child_done = 1; mctc->mctc_child_done = 1;
@ -158,7 +163,12 @@ mach_create_thread_child(arg)
killproc(p, "mach_create_thread_child: unknown flavor"); killproc(p, "mach_create_thread_child: unknown flavor");
} }
p = *mctc->mctc_proc; /*
* Copy right from parent. Will disaprear
* the day we will have struct lwp.
*/
mach_copy_right(p->p_pptr, p);
tf = trapframe(p); tf = trapframe(p);
regs = (struct exec_macho_powerpc_thread_state *)mctc->mctc_state; regs = (struct exec_macho_powerpc_thread_state *)mctc->mctc_state;

View File

@ -1,4 +1,4 @@
/* $NetBSD: mach_machdep.c,v 1.7 2002/12/12 08:23:27 manu Exp $ */ /* $NetBSD: mach_machdep.c,v 1.8 2002/12/27 09:59:25 manu Exp $ */
/*- /*-
* Copyright (c) 2002 The NetBSD Foundation, Inc. * Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mach_machdep.c,v 1.7 2002/12/12 08:23:27 manu Exp $"); __KERNEL_RCSID(0, "$NetBSD: mach_machdep.c,v 1.8 2002/12/27 09:59:25 manu Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -122,6 +122,7 @@ mach_create_thread_child(arg)
struct exec_macho_powerpc_thread_state *regs; struct exec_macho_powerpc_thread_state *regs;
mctc = (struct mach_create_thread_child_args *)arg; mctc = (struct mach_create_thread_child_args *)arg;
p = *mctc->mctc_proc;
if (mctc->mctc_flavor != MACHO_POWERPC_THREAD_STATE) { if (mctc->mctc_flavor != MACHO_POWERPC_THREAD_STATE) {
mctc->mctc_child_done = 1; mctc->mctc_child_done = 1;
@ -129,7 +130,12 @@ mach_create_thread_child(arg)
killproc(p, "mach_create_thread_child: unknown flavor"); killproc(p, "mach_create_thread_child: unknown flavor");
} }
p = *mctc->mctc_proc; /*
* Copy right from parent. Will disaprear the
* day we will have struct lwp.
*/
mach_copy_right(p->p_pptr, p);
tf = trapframe(p); tf = trapframe(p);
regs = (struct exec_macho_powerpc_thread_state *)mctc->mctc_state; regs = (struct exec_macho_powerpc_thread_state *)mctc->mctc_state;

View File

@ -1,4 +1,4 @@
/* $NetBSD: darwin_thread.c,v 1.2 2002/12/26 14:41:06 manu Exp $ */ /* $NetBSD: darwin_thread.c,v 1.3 2002/12/27 09:59:27 manu Exp $ */
/*- /*-
* Copyright (c) 2002 The NetBSD Foundation, Inc. * Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: darwin_thread.c,v 1.2 2002/12/26 14:41:06 manu Exp $"); __KERNEL_RCSID(0, "$NetBSD: darwin_thread.c,v 1.3 2002/12/27 09:59:27 manu Exp $");
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
@ -49,6 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: darwin_thread.c,v 1.2 2002/12/26 14:41:06 manu Exp $
#include <sys/syscallargs.h> #include <sys/syscallargs.h>
#include <compat/mach/mach_types.h> #include <compat/mach/mach_types.h>
#include <compat/mach/mach_exec.h>
#include <compat/mach/mach_vm.h> #include <compat/mach/mach_vm.h>
#include <compat/darwin/darwin_signal.h> #include <compat/darwin/darwin_signal.h>
@ -97,14 +98,21 @@ darwin_sys_pthread_exit(p, v, retval)
void *v; void *v;
register_t *retval; register_t *retval;
{ {
#ifdef notyet
struct darwin_sys_pthread_exit_args /* { struct darwin_sys_pthread_exit_args /* {
syscallarg(void *) value_ptr; syscallarg(void *) value_ptr;
} */ *uap = v; } */ *uap = v;
#endif struct sys_exit_args cup;
/* struct mach_emuldata *med;
* This is called on thread termination. We should make value_ptr int error;
* available to other threads doing a join operation.
*/ /* Get the status or use zero if it is not possible */
return 0; if ((error = copyin(SCARG(uap, value_ptr), &SCARG(&cup, rval),
sizeof(void *))) != 0)
SCARG(&cup, rval) = 0;
/* Avoid destroying the parent's rights in mach_e_proc_exit */
med = (struct mach_emuldata *)p->p_emuldata;
LIST_INIT(&med->med_right);
return sys_exit(p, &cup, retval);
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: mach_exec.c,v 1.18 2002/12/26 13:45:18 manu Exp $ */ /* $NetBSD: mach_exec.c,v 1.19 2002/12/27 09:59:25 manu Exp $ */
/*- /*-
* Copyright (c) 2001 The NetBSD Foundation, Inc. * Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mach_exec.c,v 1.18 2002/12/26 13:45:18 manu Exp $"); __KERNEL_RCSID(0, "$NetBSD: mach_exec.c,v 1.19 2002/12/27 09:59:25 manu Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -271,15 +271,14 @@ mach_e_proc_exit(p)
mach_right_put_exclocked(mr); mach_right_put_exclocked(mr);
lockmgr(&mach_right_list_lock, LK_RELEASE, NULL); lockmgr(&mach_right_list_lock, LK_RELEASE, NULL);
med->med_bootstrap->mp_refcount--; if (--med->med_bootstrap->mp_refcount == 0)
med->med_kernel->mp_refcount--; mach_port_put(med->med_bootstrap);
med->med_host->mp_refcount--; if (--med->med_kernel->mp_refcount == 0)
med->med_exception->mp_refcount--; mach_port_put(med->med_kernel);
if (--med->med_host->mp_refcount == 0)
mach_port_put(med->med_bootstrap); mach_port_put(med->med_host);
mach_port_put(med->med_kernel); if (--med->med_exception->mp_refcount == 0)
mach_port_put(med->med_host); mach_port_put(med->med_exception);
mach_port_put(med->med_exception);
free(med, M_EMULDATA); free(med, M_EMULDATA);
p->p_emuldata = NULL; p->p_emuldata = NULL;

View File

@ -1,4 +1,4 @@
/* $NetBSD: mach_exec.h,v 1.10 2002/12/19 22:23:06 manu Exp $ */ /* $NetBSD: mach_exec.h,v 1.11 2002/12/27 09:59:25 manu Exp $ */
/*- /*-
* Copyright (c) 2001 The NetBSD Foundation, Inc. * Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -51,7 +51,7 @@ struct mach_emuldata {
* list for all process, which is protected by a lock. This * list for all process, which is protected by a lock. This
* lock protects the per processes lists. * lock protects the per processes lists.
*/ */
LIST_HEAD(med_rights, mach_right) med_right; LIST_HEAD(med_right, mach_right) med_right;
struct mach_port *med_bootstrap;/* task bootstrap port */ struct mach_port *med_bootstrap;/* task bootstrap port */
struct mach_port *med_kernel; /* task kernel port */ struct mach_port *med_kernel; /* task kernel port */

View File

@ -1,4 +1,4 @@
/* $NetBSD: mach_host.c,v 1.17 2002/12/26 13:45:18 manu Exp $ */ /* $NetBSD: mach_host.c,v 1.18 2002/12/27 09:59:26 manu Exp $ */
/*- /*-
* Copyright (c) 2002 The NetBSD Foundation, Inc. * Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mach_host.c,v 1.17 2002/12/26 13:45:18 manu Exp $"); __KERNEL_RCSID(0, "$NetBSD: mach_host.c,v 1.18 2002/12/27 09:59:26 manu Exp $");
#include <sys/types.h> #include <sys/types.h>
#include <sys/malloc.h> #include <sys/malloc.h>
@ -159,7 +159,7 @@ mach_host_get_clock_service(args)
struct proc *p = args->p; struct proc *p = args->p;
struct mach_right *mr; struct mach_right *mr;
mr = mach_right_get(mach_clock_port, p, MACH_PORT_RIGHT_SEND); mr = mach_right_get(mach_clock_port, p, MACH_PORT_TYPE_SEND);
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) |

View File

@ -1,4 +1,4 @@
/* $NetBSD: mach_message.c,v 1.11 2002/12/26 13:45:18 manu Exp $ */ /* $NetBSD: mach_message.c,v 1.12 2002/12/27 09:59:26 manu Exp $ */
/*- /*-
* Copyright (c) 2002 The NetBSD Foundation, Inc. * Copyright (c) 2002 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.11 2002/12/26 13:45:18 manu Exp $"); __KERNEL_RCSID(0, "$NetBSD: mach_message.c,v 1.12 2002/12/27 09:59:26 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> */
@ -65,6 +65,9 @@ __KERNEL_RCSID(0, "$NetBSD: mach_message.c,v 1.11 2002/12/26 13:45:18 manu Exp $
/* Mach message pool */ /* Mach message pool */
static struct pool mach_message_pool; static struct pool mach_message_pool;
static int mach_move_right(int, mach_msg_header_t *, struct mach_right *,
struct mach_right *, struct proc *);
int int
mach_sys_msg_overwrite_trap(p, v, retval) mach_sys_msg_overwrite_trap(p, v, retval)
struct proc *p; struct proc *p;
@ -82,19 +85,11 @@ mach_sys_msg_overwrite_trap(p, v, retval)
syscallarg(mach_msg_header_t *) rcv_msg; syscallarg(mach_msg_header_t *) rcv_msg;
syscallarg(mach_msg_size_t) scatter_list_size; syscallarg(mach_msg_size_t) scatter_list_size;
} */ *uap = v; } */ *uap = v;
int error = 0;
struct mach_subsystem_namemap *map;
struct mach_trap_args args;
struct mach_emuldata *med; struct mach_emuldata *med;
mach_msg_header_t *sm;
mach_msg_header_t *rm;
mach_msg_header_t *urm;
size_t send_size, rcv_size; size_t send_size, rcv_size;
struct mach_port *mp; struct mach_port *mp;
struct mach_message *mm;
struct mach_right *mr; struct mach_right *mr;
struct mach_right *cmr; int error = 0;
int timeout;
/* /*
* If neither send nor recieve, do nothing. * If neither send nor recieve, do nothing.
@ -121,6 +116,12 @@ mach_sys_msg_overwrite_trap(p, v, retval)
* send fail, then we skip recieve. * send fail, then we skip recieve.
*/ */
if (SCARG(uap, option) & MACH_SEND_MSG) { if (SCARG(uap, option) & MACH_SEND_MSG) {
mach_msg_header_t *sm;
struct mach_subsystem_namemap *map;
struct mach_right *lr;
struct mach_right *rr;
int bits, rights;
if (SCARG(uap, msg) == NULL) { if (SCARG(uap, msg) == NULL) {
*retval = MACH_SEND_INVALID_DATA; *retval = MACH_SEND_INVALID_DATA;
return 0; return 0;
@ -141,19 +142,31 @@ mach_sys_msg_overwrite_trap(p, v, retval)
if (KTRPOINT(p, KTR_MMSG)) if (KTRPOINT(p, KTR_MMSG))
ktrmmsg(p, (char *)sm, send_size); ktrmmsg(p, (char *)sm, send_size);
#endif #endif
/*
* Handle rights in the message
*/
lr = (struct mach_right *)sm->msgh_local_port;
rr = (struct mach_right *)sm->msgh_remote_port;
if (mach_right_check_all(rr, MACH_PORT_TYPE_ALL_RIGHTS) == 0) {
*retval = MACH_SEND_INVALID_DEST;
goto out1;
}
bits = MACH_MSGH_LOCAL_BITS(sm->msgh_bits);
if ((*retval = mach_move_right(bits, sm, lr, rr, p)) != 0)
goto out1;
bits = MACH_MSGH_REMOTE_BITS(sm->msgh_bits);
if ((*retval = mach_move_right(bits, sm, rr, rr, p)) != 0)
goto out1;
/* /*
* Check that the process has send a send right on * Check that the process has send a send right on
* the remote port. * the remote port.
*/ */
if (mach_right_check((struct mach_right *)sm->msgh_remote_port, rights = (MACH_PORT_TYPE_SEND | MACH_PORT_TYPE_SEND_ONCE);
p, MACH_PORT_TYPE_SEND | MACH_PORT_TYPE_SEND_ONCE) == 0) { if (mach_right_check(rr, p, rights) == 0) {
*retval = MACH_SEND_INVALID_RIGHT;
goto out1;
}
if (mach_right_check((struct mach_right *)sm->msgh_local_port,
p, MACH_PORT_TYPE_RECEIVE) == 0) {
*retval = MACH_SEND_INVALID_RIGHT; *retval = MACH_SEND_INVALID_RIGHT;
goto out1; goto out1;
} }
@ -163,10 +176,13 @@ mach_sys_msg_overwrite_trap(p, v, retval)
* clock), the message will be handled by the kernel. * clock), the message will be handled by the kernel.
*/ */
med = (struct mach_emuldata *)p->p_emuldata; med = (struct mach_emuldata *)p->p_emuldata;
mp = ((struct mach_right *)sm->msgh_remote_port)->mr_port; mp = rr->mr_port;
if ((mp == med->med_host) || if ((mp == med->med_host) ||
(mp == med->med_kernel) || (mp == med->med_kernel) ||
(mp == mach_clock_port)) { (mp == mach_clock_port)) {
struct mach_trap_args args;
mach_msg_header_t *rm;
/* /*
* Look for the function that will handle it, * Look for the function that will handle it,
* using the message id. * using the message id.
@ -220,8 +236,7 @@ mach_sys_msg_overwrite_trap(p, v, retval)
/* /*
* Queue the reply * Queue the reply
*/ */
mr = (struct mach_right *)sm->msgh_local_port; mp = lr->mr_port;
mp = mr->mr_port;
(void)mach_message_get(rm, rcv_size, mp); (void)mach_message_get(rm, rcv_size, mp);
#ifdef DEBUG_MACH #ifdef DEBUG_MACH
printf("pid %d: message queued on port %p (id %d)\n", printf("pid %d: message queued on port %p (id %d)\n",
@ -237,8 +252,7 @@ out3: free(sm, M_EMULDATA);
* Queue the message in the remote port, and wakeup * Queue the message in the remote port, and wakeup
* any process that would be sleeping for it. * any process that would be sleeping for it.
*/ */
mr = (struct mach_right *)sm->msgh_remote_port; mp = rr->mr_port;
mp = mr->mr_port;
(void)mach_message_get(sm, send_size, mp); (void)mach_message_get(sm, send_size, mp);
#ifdef DEBUG_MACH #ifdef DEBUG_MACH
printf("pid %d: message queued on port %p (%d)\n", printf("pid %d: message queued on port %p (%d)\n",
@ -265,6 +279,11 @@ out1:
* Receiving messages. * Receiving messages.
*/ */
if (SCARG(uap, option) & MACH_RCV_MSG) { if (SCARG(uap, option) & MACH_RCV_MSG) {
struct mach_message *mm;
struct mach_right *cmr;
mach_msg_header_t *urm;
int timeout;
/* /*
* Find a buffer for the reply * Find a buffer for the reply
*/ */
@ -329,7 +348,8 @@ out1:
printf("pid %d: wait on port %p\n", printf("pid %d: wait on port %p\n",
p->p_pid, mp); p->p_pid, mp);
#endif #endif
error = tsleep(mr, PZERO, "mach_msg", timeout); error = tsleep(mr, PZERO|PCATCH,
"mach_msg", timeout);
if ((error == ERESTART) || (error == EINTR)) { if ((error == ERESTART) || (error == EINTR)) {
*retval = MACH_RCV_INTERRUPTED; *retval = MACH_RCV_INTERRUPTED;
return 0; return 0;
@ -383,7 +403,8 @@ out1:
printf("pid %d: wait on port %p\n", p->p_pid, mp); printf("pid %d: wait on port %p\n", p->p_pid, mp);
#endif #endif
if (mp->mp_count == 0) { if (mp->mp_count == 0) {
error = tsleep(mr, PZERO, "mach_msg", timeout); error = tsleep(mr, PZERO|PCATCH, "mach_msg",
timeout);
if ((error == ERESTART) || (error == EINTR)) { if ((error == ERESTART) || (error == EINTR)) {
*retval = MACH_RCV_INTERRUPTED; *retval = MACH_RCV_INTERRUPTED;
return 0; return 0;
@ -557,3 +578,87 @@ mach_message_put_exclocked(mm)
return; return;
} }
/*
* Move port according to what was specified in the message.
* NB: tr has been sanity checked, not mr
*/
static int
mach_move_right(bits, msgh, mr, tr, p)
int bits;
mach_msg_header_t *msgh;
struct mach_right *mr;
struct mach_right *tr;
struct proc *p;
{
struct mach_port *mp;
struct proc *tp;
int rights;
if ((tr->mr_port == NULL) ||
(tr->mr_port->mp_recv == NULL) ||
(tr->mr_port->mp_recv->mr_p == NULL))
return 0;
tp = tr->mr_port->mp_recv->mr_p;
switch (bits) {
case MACH_MSG_TYPE_MAKE_SEND_ONCE:
case MACH_MSG_TYPE_MAKE_SEND:
case MACH_MSG_TYPE_MOVE_RECEIVE:
rights = MACH_PORT_TYPE_RECEIVE;
break;
case MACH_MSG_TYPE_COPY_SEND:
rights = (MACH_PORT_TYPE_SEND | MACH_PORT_TYPE_DEAD_NAME);
break;
case MACH_MSG_TYPE_MOVE_SEND:
rights = (MACH_PORT_TYPE_SEND | MACH_PORT_TYPE_DEAD_NAME);
break;
case MACH_MSG_TYPE_MOVE_SEND_ONCE:
rights = (MACH_PORT_TYPE_SEND_ONCE | MACH_PORT_TYPE_DEAD_NAME);
break;
default:
return MACH_SEND_INVALID_HEADER;
break;
}
if (mach_right_check(mr, p, rights) == 0)
return 0;
mp = mr->mr_port;
switch (bits) {
case MACH_MSG_TYPE_MAKE_SEND:
case MACH_MSG_TYPE_COPY_SEND:
(void)mach_right_get(mp, tp, MACH_PORT_TYPE_SEND);
break;
case MACH_MSG_TYPE_MOVE_SEND:
(void)mach_right_get(mp, tp, MACH_PORT_TYPE_SEND);
mach_right_put(mr);
break;
case MACH_MSG_TYPE_MAKE_SEND_ONCE:
(void)mach_right_get(mp, tp, MACH_PORT_TYPE_SEND_ONCE);
break;
case MACH_MSG_TYPE_MOVE_SEND_ONCE:
(void)mach_right_get(mp, tp, MACH_PORT_TYPE_SEND_ONCE);
mach_right_put(mr);
break;
case MACH_MSG_TYPE_MOVE_RECEIVE:
(void)mach_right_get(mp, tp, MACH_PORT_TYPE_RECEIVE);
mach_right_put(mr);
break;
default:
return MACH_SEND_INVALID_HEADER;
break;
}
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: mach_port.c,v 1.20 2002/12/26 11:41:46 manu Exp $ */ /* $NetBSD: mach_port.c,v 1.21 2002/12/27 09:59:26 manu Exp $ */
/*- /*-
* Copyright (c) 2002 The NetBSD Foundation, Inc. * Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mach_port.c,v 1.20 2002/12/26 11:41:46 manu Exp $"); __KERNEL_RCSID(0, "$NetBSD: mach_port.c,v 1.21 2002/12/27 09:59:26 manu Exp $");
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
@ -70,7 +70,7 @@ mach_sys_reply_port(p, v, retval)
{ {
struct mach_right *mr; struct mach_right *mr;
mr = mach_right_get(mach_port_get(), p, MACH_PORT_RIGHT_RECEIVE); mr = mach_right_get(mach_port_get(), p, MACH_PORT_TYPE_RECEIVE);
*retval = (register_t)mr; *retval = (register_t)mr;
return 0; return 0;
@ -90,7 +90,7 @@ mach_sys_thread_self_trap(p, v, retval)
* awaiting for struct lwp ... * awaiting for struct lwp ...
*/ */
med = (struct mach_emuldata *)p->p_emuldata; med = (struct mach_emuldata *)p->p_emuldata;
mr = mach_right_get(med->med_kernel, p, MACH_PORT_RIGHT_SEND); mr = mach_right_get(med->med_kernel, p, MACH_PORT_TYPE_SEND);
*retval = (register_t)mr; *retval = (register_t)mr;
return 0; return 0;
@ -107,7 +107,7 @@ mach_sys_task_self_trap(p, v, retval)
struct mach_right *mr; struct mach_right *mr;
med = (struct mach_emuldata *)p->p_emuldata; med = (struct mach_emuldata *)p->p_emuldata;
mr = mach_right_get(med->med_kernel, p, MACH_PORT_RIGHT_SEND); mr = mach_right_get(med->med_kernel, p, MACH_PORT_TYPE_SEND);
*retval = (register_t)mr; *retval = (register_t)mr;
return 0; return 0;
@ -124,7 +124,7 @@ mach_sys_host_self_trap(p, v, retval)
struct mach_right *mr; struct mach_right *mr;
med = (struct mach_emuldata *)p->p_emuldata; med = (struct mach_emuldata *)p->p_emuldata;
mr = mach_right_get(med->med_host, p, MACH_PORT_RIGHT_SEND); mr = mach_right_get(med->med_host, p, MACH_PORT_TYPE_SEND);
*retval = (register_t)mr; *retval = (register_t)mr;
return 0; return 0;
@ -169,15 +169,15 @@ mach_port_allocate(args)
switch (req->req_right) { switch (req->req_right) {
case MACH_PORT_RIGHT_RECEIVE: case MACH_PORT_RIGHT_RECEIVE:
mr = mach_right_get(mach_port_get(), p, req->req_right); mr = mach_right_get(mach_port_get(), p, MACH_PORT_TYPE_RECEIVE);
break; break;
case MACH_PORT_RIGHT_DEAD_NAME: case MACH_PORT_RIGHT_DEAD_NAME:
mr = mach_right_get(NULL, p, req->req_right); mr = mach_right_get(NULL, p, MACH_PORT_TYPE_DEAD_NAME);
break; break;
case MACH_PORT_RIGHT_PORT_SET: case MACH_PORT_RIGHT_PORT_SET:
mr = mach_right_get(NULL, p, req->req_right); mr = mach_right_get(NULL, p, MACH_PORT_TYPE_PORT_SET);
break; break;
default: default:
@ -207,7 +207,6 @@ mach_port_insert_right(args)
size_t *msglen = args->rsize; size_t *msglen = args->rsize;
struct proc *p = args->p; struct proc *p = args->p;
struct mach_right *mr; struct mach_right *mr;
struct mach_right *tmr;
struct mach_right *nmr; struct mach_right *nmr;
struct proc *tp; struct proc *tp;
@ -217,15 +216,10 @@ mach_port_insert_right(args)
/* /*
* Sanity check: does tmr exist in another process? * Sanity check: does tmr exist in another process?
*/ */
lockmgr(&mach_right_list_lock, LK_SHARED, NULL); if (mach_right_check_all(mr, MACH_PORT_TYPE_ALL_RIGHTS) == 0)
LIST_FOREACH(tmr, &mach_right_list, mr_listall)
if (tmr == (struct mach_right *)req->req_msgh.msgh_local_port)
break;
lockmgr(&mach_right_list_lock, LK_RELEASE, NULL);
if (tmr != (struct mach_right *)req->req_msgh.msgh_local_port)
return mach_msg_error(args, EPERM); return mach_msg_error(args, EPERM);
tp = tmr->mr_p; /* The target process */ tp = mr->mr_p; /* The target process */
switch (req->req_poly.disposition) { switch (req->req_poly.disposition) {
case MACH_MSG_TYPE_MAKE_SEND: case MACH_MSG_TYPE_MAKE_SEND:
@ -237,7 +231,7 @@ mach_port_insert_right(args)
*/ */
if (mach_right_check(mr, p, MACH_PORT_TYPE_PORT_RIGHTS) == 0) if (mach_right_check(mr, p, MACH_PORT_TYPE_PORT_RIGHTS) == 0)
return mach_msg_error(args, EPERM); return mach_msg_error(args, EPERM);
nmr = mach_right_get(mr->mr_port, tp, MACH_PORT_RIGHT_SEND); nmr = mach_right_get(mr->mr_port, tp, MACH_PORT_TYPE_SEND);
break; break;
case MACH_MSG_TYPE_MAKE_SEND_ONCE: case MACH_MSG_TYPE_MAKE_SEND_ONCE:
@ -249,7 +243,7 @@ mach_port_insert_right(args)
if (mach_right_check(mr, p, MACH_PORT_TYPE_PORT_RIGHTS) == 0) if (mach_right_check(mr, p, MACH_PORT_TYPE_PORT_RIGHTS) == 0)
return mach_msg_error(args, EPERM); return mach_msg_error(args, EPERM);
nmr = mach_right_get(mr->mr_port, nmr = mach_right_get(mr->mr_port,
tp, MACH_PORT_RIGHT_SEND_ONCE); tp, MACH_PORT_TYPE_SEND_ONCE);
break; break;
case MACH_MSG_TYPE_MOVE_RECEIVE: case MACH_MSG_TYPE_MOVE_RECEIVE:
@ -259,7 +253,7 @@ mach_port_insert_right(args)
*/ */
if (mach_right_check(mr, p, MACH_PORT_TYPE_PORT_RIGHTS) == 0) if (mach_right_check(mr, p, MACH_PORT_TYPE_PORT_RIGHTS) == 0)
return mach_msg_error(args, EPERM); return mach_msg_error(args, EPERM);
nmr = mach_right_get(mr->mr_port, tp, MACH_PORT_RIGHT_RECEIVE); nmr = mach_right_get(mr->mr_port, tp, MACH_PORT_TYPE_RECEIVE);
break; break;
default: default:
@ -429,8 +423,8 @@ mach_port_put(mp)
struct mach_message *mm; struct mach_message *mm;
if (mp->mp_refcount != 0) { if (mp->mp_refcount != 0) {
uprintf("mach_port_put: freeing a referenced port\n"); uprintf("mach_port_put: trying to free a referenced port\n");
wakeup(mp); return;
} }
lockmgr(&mp->mp_msglock, LK_EXCLUSIVE, NULL); lockmgr(&mp->mp_msglock, LK_EXCLUSIVE, NULL);
@ -452,44 +446,22 @@ mach_right_get(mp, p, type)
{ {
struct mach_right *mr; struct mach_right *mr;
struct mach_emuldata *med; struct mach_emuldata *med;
int rights;
#ifdef DEBUG_MACH
printf("pid %d: get ", p->p_pid);
switch (type) {
case MACH_PORT_RIGHT_SEND:
printf("send right on port %p", mp);
break;
case MACH_PORT_RIGHT_RECEIVE:
printf("receive right on port %p", mp);
break;
case MACH_PORT_RIGHT_SEND_ONCE:
printf("send once right on port %p", mp);
break;
case MACH_PORT_RIGHT_PORT_SET:
printf("port set");
break;
case MACH_PORT_RIGHT_DEAD_NAME:
printf("dead name");
break;
default:
printf("unknown right");
break;
}
#endif
med = (struct mach_emuldata *)p->p_emuldata; med = (struct mach_emuldata *)p->p_emuldata;
/* Send and receive right must return an existing right */ /* Send and receive right must return an existing right */
if ((type == MACH_PORT_RIGHT_SEND) || rights = (MACH_PORT_TYPE_SEND | MACH_PORT_TYPE_RECEIVE);
(type == MACH_PORT_RIGHT_RECEIVE)) { if (type & rights) {
lockmgr(&mach_right_list_lock, LK_EXCLUSIVE, NULL); lockmgr(&mach_right_list_lock, LK_SHARED, NULL);
LIST_FOREACH(mr, &med->med_right, mr_list) LIST_FOREACH(mr, &med->med_right, mr_list) {
if ((mr->mr_port == mp) && if ((mr->mr_port == mp) && (mr->mr_type & rights))
(mr->mr_type == type))
break; break;
}
lockmgr(&mach_right_list_lock, LK_RELEASE, NULL); lockmgr(&mach_right_list_lock, LK_RELEASE, NULL);
if (mr != NULL) { if (mr != NULL) {
mr->mr_type |= type;
mr->mr_refcount++; mr->mr_refcount++;
goto out; goto out;
} }
@ -502,29 +474,21 @@ mach_right_get(mp, p, type)
mr->mr_type = type; mr->mr_type = type;
mr->mr_sethead = NULL; mr->mr_sethead = NULL;
mr->mr_refcount = 1; mr->mr_refcount = 1;
LIST_INIT(&mr->mr_set); /* Usefull only for a right on a port set */ LIST_INIT(&mr->mr_set); /* Usefull only for a right on a port set */
if (mp != NULL) if (mp != NULL)
mp->mp_refcount++; mp->mp_refcount++;
/* Insert the right in one of the process right lists */ /* Insert the right in one of the process right lists */
switch (type) { if (type & MACH_PORT_TYPE_PORT_OR_DEAD) {
case MACH_PORT_RIGHT_PORT_SET:
case MACH_PORT_RIGHT_DEAD_NAME:
case MACH_PORT_RIGHT_SEND:
case MACH_PORT_RIGHT_SEND_ONCE:
lockmgr(&mach_right_list_lock, LK_EXCLUSIVE, NULL); lockmgr(&mach_right_list_lock, LK_EXCLUSIVE, NULL);
LIST_INSERT_HEAD(&med->med_right, mr, mr_list); LIST_INSERT_HEAD(&med->med_right, mr, mr_list);
LIST_INSERT_HEAD(&mach_right_list, mr, mr_listall); LIST_INSERT_HEAD(&mach_right_list, mr, mr_listall);
lockmgr(&mach_right_list_lock, LK_RELEASE, NULL); lockmgr(&mach_right_list_lock, LK_RELEASE, NULL);
break; }
case MACH_PORT_RIGHT_RECEIVE: if (type & MACH_PORT_TYPE_RECEIVE) {
lockmgr(&mach_right_list_lock, LK_EXCLUSIVE, NULL);
LIST_INSERT_HEAD(&med->med_right, mr, mr_list);
LIST_INSERT_HEAD(&mach_right_list, mr, mr_listall);
lockmgr(&mach_right_list_lock, LK_RELEASE, NULL);
/* /*
* Destroy the former receive right on this port, and * Destroy the former receive right on this port, and
* register the new right. * register the new right.
@ -532,16 +496,8 @@ mach_right_get(mp, p, type)
if (mr->mr_port->mp_recv != NULL) if (mr->mr_port->mp_recv != NULL)
mach_right_put(mr->mr_port->mp_recv); mach_right_put(mr->mr_port->mp_recv);
mr->mr_port->mp_recv = mr; mr->mr_port->mp_recv = mr;
break;
default:
uprintf("mach_right_get: unknown right %d\n", type);
break;
} }
out: out:
#ifdef DEBUG_MACH
printf(": right %p\n", mr);
#endif
return mr; return mr;
} }
@ -549,30 +505,6 @@ void
mach_right_put(mr) mach_right_put(mr)
struct mach_right *mr; struct mach_right *mr;
{ {
#ifdef DEBUG_MACH
printf("pid %d: drop ", mr->mr_p->p_pid);
switch (mr->mr_type) {
case MACH_PORT_RIGHT_SEND:
printf("send right on port %p", mr->mr_port);
break;
case MACH_PORT_RIGHT_RECEIVE:
printf("receive right on port %p", mr->mr_port);
break;
case MACH_PORT_RIGHT_SEND_ONCE:
printf("send once right on port %p", mr->mr_port);
break;
case MACH_PORT_RIGHT_PORT_SET:
printf("port set");
break;
case MACH_PORT_RIGHT_DEAD_NAME:
printf("dead name");
break;
default:
printf("unknown right");
break;
}
printf(": right %p\n", mr);
#endif
lockmgr(&mach_right_list_lock, LK_EXCLUSIVE, NULL); lockmgr(&mach_right_list_lock, LK_EXCLUSIVE, NULL);
mach_right_put_exclocked(mr); mach_right_put_exclocked(mr);
lockmgr(&mach_right_list_lock, LK_RELEASE, NULL); lockmgr(&mach_right_list_lock, LK_RELEASE, NULL);
@ -601,28 +533,19 @@ mach_right_put_exclocked(mr)
if (mr->mr_refcount != 0) if (mr->mr_refcount != 0)
return; return;
switch(mr->mr_type) { if (mr->mr_type & MACH_PORT_TYPE_PORT_SET) {
case MACH_PORT_RIGHT_PORT_SET:
while((cmr = LIST_FIRST(&mr->mr_set)) != NULL) while((cmr = LIST_FIRST(&mr->mr_set)) != NULL)
mach_right_put_exclocked(cmr); mach_right_put_exclocked(cmr);
/* FALLBACK */ }
case MACH_PORT_RIGHT_SEND: if (mr->mr_type & MACH_PORT_TYPE_ALL_RIGHTS) {
case MACH_PORT_RIGHT_SEND_ONCE:
case MACH_PORT_RIGHT_RECEIVE:
case MACH_PORT_RIGHT_DEAD_NAME:
LIST_REMOVE(mr, mr_list); LIST_REMOVE(mr, mr_list);
LIST_REMOVE(mr, mr_listall); LIST_REMOVE(mr, mr_listall);
break;
default:
uprintf("mach_right_put: unknown right %d\n", mr->mr_type);
break;
} }
if (mr->mr_port != NULL) { if (mr->mr_port != NULL) {
mr->mr_port->mp_refcount--; mr->mr_port->mp_refcount--;
if (mr->mr_port->mp_refcount <= 0) if (mr->mr_port->mp_refcount == 0)
mach_port_put(mr->mr_port); mach_port_put(mr->mr_port);
} }
@ -631,8 +554,7 @@ mach_right_put_exclocked(mr)
} }
/* /*
* Check that a process do have a given right. Beware that type is * Check that a process do have a given right
* MACH_PORT_TYPE_*, and not MACH_PORT_RIGHT_*
*/ */
int int
mach_right_check(mr, p, type) mach_right_check(mr, p, type)
@ -642,23 +564,47 @@ mach_right_check(mr, p, type)
{ {
struct mach_right *cmr; struct mach_right *cmr;
struct mach_emuldata *med; struct mach_emuldata *med;
int found;
med = (struct mach_emuldata *)p->p_emuldata; med = (struct mach_emuldata *)p->p_emuldata;
found = 0;
lockmgr(&mach_right_list_lock, LK_SHARED, NULL); lockmgr(&mach_right_list_lock, LK_SHARED, NULL);
LIST_FOREACH(cmr, &med->med_right, mr_list) { LIST_FOREACH(cmr, &med->med_right, mr_list) {
if (cmr != mr) if (cmr != mr)
continue; continue;
if ((type & (1 << (cmr->mr_type + 16))) != 0) if (type & cmr->mr_type)
found = 1; break;
} }
lockmgr(&mach_right_list_lock, LK_RELEASE, NULL); lockmgr(&mach_right_list_lock, LK_RELEASE, NULL);
return found; if (cmr != NULL)
return 1;
return 0;
}
/*
* Check for a right in any process
*/
int
mach_right_check_all(mr, type)
struct mach_right *mr;
int type;
{
struct mach_right *cmr;
lockmgr(&mach_right_list_lock, LK_SHARED, NULL);
LIST_FOREACH(cmr, &mach_right_list, mr_listall)
if ((cmr == mr) && (mr->mr_type & type))
break;
lockmgr(&mach_right_list_lock, LK_RELEASE, NULL);
if (cmr == NULL)
return 0;
return 1;
} }
#ifdef DEBUG_MACH #ifdef DEBUG_MACH
@ -683,7 +629,7 @@ mach_debug_port(p, more)
printf(" count = %d\n", mr->mr_port->mp_count); printf(" count = %d\n", mr->mr_port->mp_count);
printf(" refcount = %d\n", mr->mr_port->mp_refcount); printf(" refcount = %d\n", mr->mr_port->mp_refcount);
printf(" proc = %p\n", mr->mr_p); printf(" proc = %p\n", mr->mr_p);
printf(" type = %d\n\n", mr->mr_type); printf(" type = 0x%x\n\n", mr->mr_type);
} }
return; return;
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: mach_port.h,v 1.10 2002/12/19 22:23:07 manu Exp $ */ /* $NetBSD: mach_port.h,v 1.11 2002/12/27 09:59:26 manu Exp $ */
/*- /*-
* Copyright (c) 2002 The NetBSD Foundation, Inc. * Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -234,6 +234,7 @@ void mach_right_put(struct mach_right *);
void mach_right_put_shlocked(struct mach_right *); void mach_right_put_shlocked(struct mach_right *);
void mach_right_put_exclocked(struct mach_right *); void mach_right_put_exclocked(struct mach_right *);
int mach_right_check(struct mach_right *, struct proc *, int); int mach_right_check(struct mach_right *, struct proc *, int);
int mach_right_check_all(struct mach_right *, int);
/* In-kernel Mach port description */ /* In-kernel Mach port description */
struct mach_port { struct mach_port {

View File

@ -1,4 +1,4 @@
/* $NetBSD: mach_semaphore.c,v 1.3 2002/12/17 18:42:57 manu Exp $ */ /* $NetBSD: mach_semaphore.c,v 1.4 2002/12/27 09:59:26 manu Exp $ */
/*- /*-
* Copyright (c) 2002 The NetBSD Foundation, Inc. * Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mach_semaphore.c,v 1.3 2002/12/17 18:42:57 manu Exp $"); __KERNEL_RCSID(0, "$NetBSD: mach_semaphore.c,v 1.4 2002/12/27 09:59:26 manu Exp $");
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
@ -92,7 +92,7 @@ mach_sys_semaphore_wait_trap(p, v, retval)
if (blocked != 0) { if (blocked != 0) {
mwp = mach_waiting_proc_get(p, ms); mwp = mach_waiting_proc_get(p, ms);
while (ms->ms_value < 0) while (ms->ms_value < 0)
tsleep(mwp, PZERO, "sem_wait", 0); tsleep(mwp, PZERO|PCATCH, "sem_wait", 0);
mach_waiting_proc_put(mwp, ms, 0); mach_waiting_proc_put(mwp, ms, 0);
} }
return 0; return 0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: mach_task.c,v 1.15 2002/12/24 12:29:06 manu Exp $ */ /* $NetBSD: mach_task.c,v 1.16 2002/12/27 09:59:27 manu Exp $ */
/*- /*-
* Copyright (c) 2002 The NetBSD Foundation, Inc. * Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mach_task.c,v 1.15 2002/12/24 12:29:06 manu Exp $"); __KERNEL_RCSID(0, "$NetBSD: mach_task.c,v 1.16 2002/12/27 09:59:27 manu Exp $");
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
@ -73,16 +73,16 @@ mach_task_get_special_port(args)
switch (req->req_which_port) { switch (req->req_which_port) {
case MACH_TASK_KERNEL_PORT: case MACH_TASK_KERNEL_PORT:
mr = mach_right_get(med->med_kernel, p, MACH_PORT_RIGHT_SEND); mr = mach_right_get(med->med_kernel, p, MACH_PORT_TYPE_SEND);
break; break;
case MACH_TASK_HOST_PORT: case MACH_TASK_HOST_PORT:
mr = mach_right_get(med->med_host, p, MACH_PORT_RIGHT_SEND); mr = mach_right_get(med->med_host, p, MACH_PORT_TYPE_SEND);
break; break;
case MACH_TASK_BOOTSTRAP_PORT: case MACH_TASK_BOOTSTRAP_PORT:
mr = mach_right_get(med->med_bootstrap, mr = mach_right_get(med->med_bootstrap,
p, MACH_PORT_RIGHT_SEND); p, MACH_PORT_TYPE_SEND);
break; break;
case MACH_TASK_WIRED_LEDGER_PORT: case MACH_TASK_WIRED_LEDGER_PORT:
@ -141,11 +141,11 @@ mach_ports_lookup(args)
msp[6] = MACH_PORT_DEAD; msp[6] = MACH_PORT_DEAD;
msp[MACH_TASK_KERNEL_PORT] = msp[MACH_TASK_KERNEL_PORT] =
mach_right_get(med->med_kernel, p, MACH_PORT_RIGHT_SEND); mach_right_get(med->med_kernel, p, MACH_PORT_TYPE_SEND);
msp[MACH_TASK_HOST_PORT] = msp[MACH_TASK_HOST_PORT] =
mach_right_get(med->med_host, p, MACH_PORT_RIGHT_SEND); mach_right_get(med->med_host, p, MACH_PORT_TYPE_SEND);
msp[MACH_TASK_BOOTSTRAP_PORT] = msp[MACH_TASK_BOOTSTRAP_PORT] =
mach_right_get(med->med_bootstrap, p, MACH_PORT_RIGHT_SEND); mach_right_get(med->med_bootstrap, p, MACH_PORT_TYPE_SEND);
/* /*
* On Darwin, the data seems always null, so ifdef this out * On Darwin, the data seems always null, so ifdef this out
@ -195,7 +195,7 @@ mach_task_set_special_port(args)
if (mach_right_check(mr, p, MACH_PORT_TYPE_ALL_RIGHTS) == 0) if (mach_right_check(mr, p, MACH_PORT_TYPE_ALL_RIGHTS) == 0)
return mach_msg_error(args, EPERM); return mach_msg_error(args, EPERM);
if (mr->mr_type == MACH_PORT_RIGHT_DEAD_NAME) if (mr->mr_type == MACH_PORT_TYPE_DEAD_NAME)
return mach_msg_error(args, EINVAL); return mach_msg_error(args, EINVAL);
med = (struct mach_emuldata *)p->p_emuldata; med = (struct mach_emuldata *)p->p_emuldata;

View File

@ -1,4 +1,4 @@
/* $NetBSD: mach_thread.c,v 1.9 2002/12/21 23:57:57 gmcgarry Exp $ */ /* $NetBSD: mach_thread.c,v 1.10 2002/12/27 09:59:27 manu Exp $ */
/*- /*-
* Copyright (c) 2002 The NetBSD Foundation, Inc. * Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -37,19 +37,22 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mach_thread.c,v 1.9 2002/12/21 23:57:57 gmcgarry Exp $"); __KERNEL_RCSID(0, "$NetBSD: mach_thread.c,v 1.10 2002/12/27 09:59:27 manu Exp $");
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/kernel.h> #include <sys/kernel.h>
#include <sys/systm.h> #include <sys/systm.h>
#include <sys/signal.h> #include <sys/signal.h>
#include <sys/lock.h>
#include <sys/queue.h>
#include <sys/proc.h> #include <sys/proc.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_exec.h> #include <compat/mach/mach_exec.h>
#include <compat/mach/mach_clock.h> #include <compat/mach/mach_clock.h>
#include <compat/mach/mach_port.h>
#include <compat/mach/mach_thread.h> #include <compat/mach/mach_thread.h>
#include <compat/mach/mach_errno.h> #include <compat/mach/mach_errno.h>
#include <compat/mach/mach_syscallargs.h> #include <compat/mach/mach_syscallargs.h>
@ -84,7 +87,7 @@ mach_sys_syscall_thread_switch(p, v, retval)
case MACH_SWITCH_OPTION_WAIT: case MACH_SWITCH_OPTION_WAIT:
med->med_thpri = 1; med->med_thpri = 1;
while (med->med_thpri != 0) while (med->med_thpri != 0)
(void)tsleep(&med->med_thpri, PZERO, (void)tsleep(&med->med_thpri, PZERO|PCATCH,
"thread_switch", timeout); "thread_switch", timeout);
break; break;
@ -169,3 +172,46 @@ mach_thread_create_running(args)
*msglen = sizeof(*rep); *msglen = sizeof(*rep);
return 0; return 0;
} }
/*
* Duplicate the right of p1 into p2 on thread creation.
* This will disapear the day we will have struct lwp.
* XXX mr_p is not accurate anymore, this might introduce
* some problems.
*/
void
mach_copy_right(p1, p2)
struct proc *p1;
struct proc *p2;
{
struct mach_emuldata *med1;
struct mach_emuldata *med2;
med1 = (struct mach_emuldata *)p1->p_emuldata;
med2 = (struct mach_emuldata *)p2->p_emuldata;
/* Undo what mach_e_proc_init did */
if (--med2->med_bootstrap->mp_refcount == 0)
mach_port_put(med2->med_bootstrap);
if (--med2->med_kernel->mp_refcount == 0)
mach_port_put(med2->med_kernel);
if (--med2->med_host->mp_refcount == 0)
mach_port_put(med2->med_host);
if (--med2->med_exception->mp_refcount == 0)
mach_port_put(med2->med_exception);
/* Share ports and rights with the parent */
med2->med_right = med1->med_right;
med2->med_bootstrap->mp_refcount++;
med2->med_kernel->mp_refcount++;
med2->med_host->mp_refcount++;
med2->med_exception->mp_refcount++;
med2->med_bootstrap = med1->med_bootstrap;
med2->med_kernel = med1->med_kernel;
med2->med_host = med1->med_host;
med2->med_exception = med1->med_exception;
return;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: mach_thread.h,v 1.5 2002/12/17 18:42:57 manu Exp $ */ /* $NetBSD: mach_thread.h,v 1.6 2002/12/27 09:59:27 manu Exp $ */
/*- /*-
* Copyright (c) 2002 The NetBSD Foundation, Inc. * Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -100,5 +100,6 @@ typedef struct {
int mach_thread_policy(struct mach_trap_args *); int mach_thread_policy(struct mach_trap_args *);
int mach_thread_create_running(struct mach_trap_args *); int mach_thread_create_running(struct mach_trap_args *);
void mach_create_thread_child(void *); void mach_create_thread_child(void *);
void mach_copy_right(struct proc *, struct proc *);
#endif /* _MACH_THREAD_H_ */ #endif /* _MACH_THREAD_H_ */