First attempt with task_suspend/task_resume, but we hit some bugs somewhere

else in our code.
This commit is contained in:
manu 2003-04-06 17:58:49 +00:00
parent 972480b272
commit 0479104b05
5 changed files with 156 additions and 8 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: mach_exec.c,v 1.28 2003/03/29 11:04:08 manu Exp $ */
/* $NetBSD: mach_exec.c,v 1.29 2003/04/06 17:58:49 manu Exp $ */
/*-
* Copyright (c) 2001-2003 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mach_exec.c,v 1.28 2003/03/29 11:04:08 manu Exp $");
__KERNEL_RCSID(0, "$NetBSD: mach_exec.c,v 1.29 2003/04/06 17:58:49 manu Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -261,6 +261,7 @@ mach_e_proc_init(p, vmspace)
bzero(med->med_exc, sizeof(med->med_exc));
med->med_dirty_thid = 1;
med->med_suspend = 0;
return;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: mach_exec.h,v 1.16 2003/03/29 11:04:09 manu Exp $ */
/* $NetBSD: mach_exec.h,v 1.17 2003/04/06 17:58:49 manu Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -59,6 +59,7 @@ struct mach_emuldata {
struct mach_port *med_exc[MACH_EXC_MAX]; /* Exception ports */
int med_dirty_thid; /* Thread id not yet initialized */
int med_suspend; /* Suspend semaphore */
};

View File

@ -1,4 +1,4 @@
/* $NetBSD: mach_namemap.c,v 1.22 2003/04/05 21:18:02 manu Exp $ */
/* $NetBSD: mach_namemap.c,v 1.23 2003/04/06 17:58:50 manu Exp $ */
/*-
* Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mach_namemap.c,v 1.22 2003/04/05 21:18:02 manu Exp $");
__KERNEL_RCSID(0, "$NetBSD: mach_namemap.c,v 1.23 2003/04/06 17:58:50 manu Exp $");
#include <sys/types.h>
#include <sys/param.h>
@ -108,6 +108,8 @@ struct mach_subsystem_namemap mach_namemap[] = {
{ 3402, mach_task_threads, "task_threads" },
{ 3404, mach_ports_lookup, "ports_lookup" },
{ 3405, mach_task_info, "task_info" },
{ 3407, mach_task_suspend, "task_suspend" },
{ 3408, mach_task_resume, "task_resume" },
{ 3409, mach_task_get_special_port, "task_get_special_port" },
{ 3410, mach_task_set_special_port, "task_set_special_port" },
{ 3412, mach_thread_create_running, "thread_create_running" },

View File

@ -1,4 +1,4 @@
/* $NetBSD: mach_task.c,v 1.23 2003/04/05 21:18:02 manu Exp $ */
/* $NetBSD: mach_task.c,v 1.24 2003/04/06 17:58:50 manu Exp $ */
/*-
* Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
@ -39,7 +39,7 @@
#include "opt_compat_darwin.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mach_task.c,v 1.23 2003/04/05 21:18:02 manu Exp $");
__KERNEL_RCSID(0, "$NetBSD: mach_task.c,v 1.24 2003/04/06 17:58:50 manu Exp $");
#include <sys/types.h>
#include <sys/param.h>
@ -479,6 +479,122 @@ mach_task_info(args)
return 0;
}
int
mach_task_suspend(args)
struct mach_trap_args *args;
{
mach_task_suspend_request_t *req = args->smsg;
mach_task_suspend_reply_t *rep = args->rmsg;
size_t *msglen = args->rsize;
mach_port_t mn;
struct mach_right *mr;
struct lwp *l;
struct proc *p;
struct mach_emuldata *med;
int s;
/*
* XXX Two bugs when gdb calls this function:
* - gdb uses a port it never allocated (apparently)
* - this makes mach_right_check panic because of the lock operation
* on a draining lock.
*/
return mach_msg_error(args, 0);
/* XXX more permission checks nescessary here? */
mn = req->req_msgh.msgh_remote_port;
if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == 0)
return mach_msg_error(args, EINVAL);
if ((mr->mr_port == NULL) || (mr->mr_port->mp_recv == NULL)) {
#ifdef DEBUG_MACH
printf("mach_task_suspend: port = %p, recv = %p\n",
mr->mr_port, mr->mr_port->mp_recv);
#endif
return mach_msg_error(args, EINVAL);
}
l = mr->mr_port->mp_recv->mr_lwp;
p = l->l_proc;
med = p->p_emuldata;
med->med_suspend++; /* XXX Mach also has a per thread semaphore */
if (p->p_stat == SACTIVE) {
sigminusset(&contsigmask, &p->p_sigctx.ps_siglist);
SCHED_LOCK(s);
p->p_stat = SSTOP;
l->l_stat = LSSTOP;
p->p_nrlwps--;
mi_switch(l, NULL);
SCHED_ASSERT_UNLOCKED();
splx(s);
}
rep->rep_msgh.msgh_bits =
MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE);
rep->rep_msgh.msgh_size = sizeof(*rep) - sizeof(rep->rep_trailer);
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_trailer.msgh_trailer_size = 8;
*msglen = sizeof(*rep);
return 0;
}
int
mach_task_resume(args)
struct mach_trap_args *args;
{
mach_task_resume_request_t *req = args->smsg;
mach_task_resume_reply_t *rep = args->rmsg;
size_t *msglen = args->rsize;
mach_port_t mn;
struct mach_right *mr;
struct lwp *l;
struct proc *p;
struct mach_emuldata *med;
int s;
/* XXX more permission checks nescessary here? */
mn = req->req_msgh.msgh_remote_port;
if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == 0)
return mach_msg_error(args, EINVAL);
if ((mr->mr_port == NULL) || (mr->mr_port->mp_recv == NULL)) {
#ifdef DEBUG_MACH
printf("mach_task_resume: port = %p, recv = %p\n",
mr->mr_port, mr->mr_port->mp_recv);
#endif
return mach_msg_error(args, EINVAL);
}
l = mr->mr_port->mp_recv->mr_lwp;
p = l->l_proc;
med = p->p_emuldata;
med->med_suspend--; /* XXX Mach also has a per thread semaphore */
if (med->med_suspend > 0)
return mach_msg_error(args, 0); /* XXX error code */
/* XXX We should also wake up the stopped thread... */
if (p->p_stat == SSTOP) {
sigminusset(&stopsigmask, &p->p_sigctx.ps_siglist);
SCHED_LOCK(s);
p->p_stat = SACTIVE;
SCHED_ASSERT_UNLOCKED();
splx(s);
}
rep->rep_msgh.msgh_bits =
MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE);
rep->rep_msgh.msgh_size = sizeof(*rep) - sizeof(rep->rep_trailer);
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_trailer.msgh_trailer_size = 8;
*msglen = sizeof(*rep);
return 0;
}
int
mach_sys_task_for_pid(l, v, retval)
struct lwp *l;

View File

@ -1,4 +1,4 @@
/* $NetBSD: mach_task.h,v 1.7 2003/04/05 21:18:02 manu Exp $ */
/* $NetBSD: mach_task.h,v 1.8 2003/04/06 17:58:50 manu Exp $ */
/*-
* Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
@ -192,6 +192,32 @@ typedef struct {
mach_msg_trailer_t rep_trailer;
} mach_task_info_reply_t;
/* task_suspend */
typedef struct {
mach_msg_header_t req_msgh;
} mach_task_suspend_request_t;
typedef struct {
mach_msg_header_t rep_msgh;
mach_ndr_record_t rep_ndr;
mach_kern_return_t rep_retval;
mach_msg_trailer_t rep_trailer;
} mach_task_suspend_reply_t;
/* task_resume */
typedef struct {
mach_msg_header_t req_msgh;
} mach_task_resume_request_t;
typedef struct {
mach_msg_header_t rep_msgh;
mach_ndr_record_t rep_ndr;
mach_kern_return_t rep_retval;
mach_msg_trailer_t rep_trailer;
} mach_task_resume_reply_t;
int mach_task_get_special_port(struct mach_trap_args *);
int mach_ports_lookup(struct mach_trap_args *);
int mach_task_set_special_port(struct mach_trap_args *);
@ -199,5 +225,7 @@ int mach_task_threads(struct mach_trap_args *);
int mach_task_get_exception_ports(struct mach_trap_args *);
int mach_task_set_exception_ports(struct mach_trap_args *);
int mach_task_info(struct mach_trap_args *);
int mach_task_suspend(struct mach_trap_args *);
int mach_task_resume(struct mach_trap_args *);
#endif /* _MACH_TASK_H_ */