sys/vm/vm_vmspace.c
int
sys_vmspace_ctl(struct vmspace_ctl_args *uap)
{
	struct vkernel_proc *vkp;
	struct vkernel_lwp *vklp;
	struct vmspace_entry *ve;
	struct lwp *lp;
	struct proc *p;
	int framesz;
	int error;

	lp = curthread->td_lwp;
	p = lp->lwp_proc;

	if ((vkp = p->p_vkernel) == NULL)
		return (EINVAL);

	get_mplock();
	lwkt_gettoken(&vkp->token);
	if ((ve = vkernel_find_vmspace(vkp, uap->id)) == NULL) {
		error = ENOENT;
		goto done;
	}

	switch(uap->cmd) {
	case VMSPACE_CTL_RUN:
		/*
		 * Save the caller's register context, swap VM spaces, and
		 * install the passed register context.  Return with
		 * EJUSTRETURN so the syscall code doesn't adjust the context.
		 */
		atomic_add_int(&ve->refs, 1);
		framesz = sizeof(struct trapframe);
		if ((vklp = lp->lwp_vkernel) == NULL) {
			vklp = kmalloc(sizeof(*vklp), M_VKERNEL,
				       M_WAITOK|M_ZERO);
			lp->lwp_vkernel = vklp;
		}
		vklp->user_trapframe = uap->tframe;
		vklp->user_vextframe = uap->vframe;
		bcopy(uap->sysmsg_frame, &vklp->save_trapframe, framesz);
		bcopy(&curthread->td_tls, &vklp->save_vextframe.vx_tls,
		      sizeof(vklp->save_vextframe.vx_tls));
		error = copyin(uap->tframe, uap->sysmsg_frame, framesz);
		if (error == 0) {
			error = copyin(&uap->vframe->vx_tls,
				       &curthread->td_tls,
				       sizeof(struct savetls));
		}
		if (error == 0)
			error = cpu_sanitize_frame(uap->sysmsg_frame);
		if (error == 0)
			error = cpu_sanitize_tls(&curthread->td_tls);
		if (error) {
			bcopy(&vklp->save_trapframe, uap->sysmsg_frame,
			      framesz);
			bcopy(&vklp->save_vextframe.vx_tls, &curthread->td_tls,
			      sizeof(vklp->save_vextframe.vx_tls));
			set_user_TLS();
			atomic_subtract_int(&ve->refs, 1);
		} else {
			vklp->ve = ve;
			pmap_setlwpvm(lp, ve->vmspace);
			set_user_TLS();
			set_vkernel_fp(uap->sysmsg_frame);
			error = EJUSTRETURN;
		}
		break;
	default:
		error = EOPNOTSUPP;
		break;
	}
done:
	lwkt_reltoken(&vkp->token);
	rel_mplock();
	return(error);
}
/*
 * vmspace_ctl (void *id, int cmd, struct trapframe *tframe,
 *		struct vextframe *vframe);
 *
 * Transfer control to a VMSPACE.  Control is returned after the specified
 * number of microseconds or if a page fault, signal, trap, or system call
 * occurs.  The context is updated as appropriate.
 *
 * No requirements.
 */
vmspace_ctl (void *id, int cmd, struct trapframe *tframe,
struct vextframe *vframe).

Transfer control to a VMSPACE.  Control is returned after the specified
number of microseconds or if a page fault, signal, trap, or system call
occurs.  The context is updated as appropriate.

No requirements.
vmspace_ctl ( void * id int cmd struct trapframe * tframe struct vextframe * vframe ) . Transfer control to a VMSPACE . Control is returned after the specified number of microseconds or if a page fault signal trap or system call occurs . The context is updated as appropriate . No requirements .
int
sys_vmspace_ctl(struct vmspace_ctl_args *uap)
{
	struct vkernel_proc *vkp;
	struct vkernel_lwp *vklp;
	struct vmspace_entry *ve;
	struct lwp *lp;
	struct proc *p;
	int framesz;
	int error;
	lp = curthread->td_lwp;
	p = lp->lwp_proc;
	if ((vkp = p->p_vkernel) == NULL)
		return (EINVAL);
	get_mplock();
	lwkt_gettoken(&vkp->token);
	if ((ve = vkernel_find_vmspace(vkp, uap->id)) == NULL) {
		error = ENOENT;
		goto done;
	}
	switch(uap->cmd) {
	case VMSPACE_CTL_RUN:
		atomic_add_int(&ve->refs, 1);
		framesz = sizeof(struct trapframe);
		if ((vklp = lp->lwp_vkernel) == NULL) {
			vklp = kmalloc(sizeof(*vklp), M_VKERNEL,
				       M_WAITOK|M_ZERO);
			lp->lwp_vkernel = vklp;
		}
		vklp->user_trapframe = uap->tframe;
		vklp->user_vextframe = uap->vframe;
		bcopy(uap->sysmsg_frame, &vklp->save_trapframe, framesz);
		bcopy(&curthread->td_tls, &vklp->save_vextframe.vx_tls,
		      sizeof(vklp->save_vextframe.vx_tls));
		error = copyin(uap->tframe, uap->sysmsg_frame, framesz);
		if (error == 0) {
			error = copyin(&uap->vframe->vx_tls,
				       &curthread->td_tls,
				       sizeof(struct savetls));
		}
		if (error == 0)
			error = cpu_sanitize_frame(uap->sysmsg_frame);
		if (error == 0)
			error = cpu_sanitize_tls(&curthread->td_tls);
		if (error) {
			bcopy(&vklp->save_trapframe, uap->sysmsg_frame,
			      framesz);
			bcopy(&vklp->save_vextframe.vx_tls, &curthread->td_tls,
			      sizeof(vklp->save_vextframe.vx_tls));
			set_user_TLS();
			atomic_subtract_int(&ve->refs, 1);
		} else {
			vklp->ve = ve;
			pmap_setlwpvm(lp, ve->vmspace);
			set_user_TLS();
			set_vkernel_fp(uap->sysmsg_frame);
			error = EJUSTRETURN;
		}
		break;
	default:
		error = EOPNOTSUPP;
		break;
	}
done:
	lwkt_reltoken(&vkp->token);
	rel_mplock();
	return(error);
}
int sys_vmspace_ctl ( struct vmspace_ctl_args * uap ) { struct vkernel_proc * vkp ; struct vkernel_lwp * vklp ; struct vmspace_entry * ve ; struct lwp * lp ; struct proc * p ; int framesz ; int error ; lp = curthread -> td_lwp ; p = lp -> lwp_proc ; if ( ( vkp = p -> p_vkernel ) == NULL ) return ( EINVAL ) ; get_mplock ( ) ; lwkt_gettoken ( & vkp -> token ) ; if ( ( ve = vkernel_find_vmspace ( vkp , uap -> id ) ) == NULL ) { error = ENOENT ; goto done ; } switch ( uap -> cmd ) { case VMSPACE_CTL_RUN : atomic_add_int ( & ve -> refs , 1 ) ; framesz = sizeof ( struct trapframe ) ; if ( ( vklp = lp -> lwp_vkernel ) == NULL ) { vklp = kmalloc ( sizeof ( * vklp ) , M_VKERNEL , M_WAITOK | M_ZERO ) ; lp -> lwp_vkernel = vklp ; } vklp -> user_trapframe = uap -> tframe ; vklp -> user_vextframe = uap -> vframe ; bcopy ( uap -> sysmsg_frame , & vklp -> save_trapframe , framesz ) ; bcopy ( & curthread -> td_tls , & vklp -> save_vextframe . vx_tls , sizeof ( vklp -> save_vextframe . vx_tls ) ) ; error = copyin ( uap -> tframe , uap -> sysmsg_frame , framesz ) ; if ( error == 0 ) { error = copyin ( & uap -> vframe -> vx_tls , & curthread -> td_tls , sizeof ( struct savetls ) ) ; } if ( error == 0 ) error = cpu_sanitize_frame ( uap -> sysmsg_frame ) ; if ( error == 0 ) error = cpu_sanitize_tls ( & curthread -> td_tls ) ; if ( error ) { bcopy ( & vklp -> save_trapframe , uap -> sysmsg_frame , framesz ) ; bcopy ( & vklp -> save_vextframe . vx_tls , & curthread -> td_tls , sizeof ( vklp -> save_vextframe . vx_tls ) ) ; set_user_TLS ( ) ; atomic_subtract_int ( & ve -> refs , 1 ) ; } else { vklp -> ve = ve ; pmap_setlwpvm ( lp , ve -> vmspace ) ; set_user_TLS ( ) ; set_vkernel_fp ( uap -> sysmsg_frame ) ; error = EJUSTRETURN ; } break ; default : error = EOPNOTSUPP ; break ; } done : lwkt_reltoken ( & vkp -> token ) ; rel_mplock ( ) ; return ( error ) ; }
vmspace_ctl (void *id, int cmd, struct trapframe *tframe,
              struct vextframe *vframe);
vmspace_ctl ( void * id int cmd struct trapframe * tframe struct vextframe * vframe ) ;
/*
		 * Save the caller's register context, swap VM spaces, and
		 * install the passed register context.  Return with
		 * EJUSTRETURN so the syscall code doesn't adjust the context.
		 */