Esempio n. 1
0
void
ipc_task_init(
	task_t		task,
	task_t		parent)
{
	ipc_space_t space;
	ipc_port_t kport;
	kern_return_t kr;
	int i;


	kr = ipc_space_create(&space);
	if (kr != KERN_SUCCESS)
		panic("ipc_task_init");


	kport = ipc_port_alloc_kernel();
	if (kport == IP_NULL)
		panic("ipc_task_init");

	itk_lock_init(task);
	task->itk_self = kport;
	task->itk_sself = ipc_port_make_send(kport);
	task->itk_space = space;

	if (parent == TASK_NULL) {
		task->itk_exception = IP_NULL;
		task->itk_bootstrap = IP_NULL;
		for (i = 0; i < TASK_PORT_REGISTER_MAX; i++)
			task->itk_registered[i] = IP_NULL;
	} else {
		itk_lock(parent);
		assert(parent->itk_self != IP_NULL);

		/* inherit registered ports */

		for (i = 0; i < TASK_PORT_REGISTER_MAX; i++)
			task->itk_registered[i] =
				ipc_port_copy_send(parent->itk_registered[i]);

		/* inherit exception and bootstrap ports */

		task->itk_exception =
			ipc_port_copy_send(parent->itk_exception);
		task->itk_bootstrap =
			ipc_port_copy_send(parent->itk_bootstrap);

		itk_unlock(parent);
	}
}
Esempio n. 2
0
void
ipc_task_init(
	task_t		task,
	task_t		parent)
{
	ipc_space_t space;
	ipc_port_t kport;
	ipc_port_t nport;
	kern_return_t kr;
	int i;


	kr = ipc_space_create(&ipc_table_entries[0], &space);
	if (kr != KERN_SUCCESS)
		panic("ipc_task_init");

	space->is_task = task;

	kport = ipc_port_alloc_kernel();
	if (kport == IP_NULL)
		panic("ipc_task_init");

	nport = ipc_port_alloc_kernel();
	if (nport == IP_NULL)
		panic("ipc_task_init");

	itk_lock_init(task);
	task->itk_self = kport;
	task->itk_nself = nport;
	task->itk_resume = IP_NULL; /* Lazily allocated on-demand */
	task->itk_sself = ipc_port_make_send(kport);
	task->itk_debug_control = IP_NULL;
	task->itk_space = space;

	if (parent == TASK_NULL) {
		ipc_port_t port;

		for (i = FIRST_EXCEPTION; i < EXC_TYPES_COUNT; i++) {
			task->exc_actions[i].port = IP_NULL;
		}/* for */
		
		kr = host_get_host_port(host_priv_self(), &port);
		assert(kr == KERN_SUCCESS);
		task->itk_host = port;

		task->itk_bootstrap = IP_NULL;
		task->itk_seatbelt = IP_NULL;
		task->itk_gssd = IP_NULL;
		task->itk_task_access = IP_NULL;

		for (i = 0; i < TASK_PORT_REGISTER_MAX; i++)
			task->itk_registered[i] = IP_NULL;
	} else {
		itk_lock(parent);
		assert(parent->itk_self != IP_NULL);

		/* inherit registered ports */

		for (i = 0; i < TASK_PORT_REGISTER_MAX; i++)
			task->itk_registered[i] =
				ipc_port_copy_send(parent->itk_registered[i]);

		/* inherit exception and bootstrap ports */

		for (i = FIRST_EXCEPTION; i < EXC_TYPES_COUNT; i++) {
		    task->exc_actions[i].port =
		  		ipc_port_copy_send(parent->exc_actions[i].port);
		    task->exc_actions[i].flavor =
				parent->exc_actions[i].flavor;
		    task->exc_actions[i].behavior = 
				parent->exc_actions[i].behavior;
		    task->exc_actions[i].privileged =
				parent->exc_actions[i].privileged;
		}/* for */
		task->itk_host =
			ipc_port_copy_send(parent->itk_host);

		task->itk_bootstrap =
			ipc_port_copy_send(parent->itk_bootstrap);

		task->itk_seatbelt =
			ipc_port_copy_send(parent->itk_seatbelt);

		task->itk_gssd =
			ipc_port_copy_send(parent->itk_gssd);

		task->itk_task_access =
			ipc_port_copy_send(parent->itk_task_access);

		itk_unlock(parent);
	}
}
Esempio n. 3
0
kern_return_t
norma_task_common(
	task_t		parent_task,
	boolean_t	inherit_memory,
	boolean_t	clone,
	boolean_t	kill_parent,
	int		child_node,
	task_t		*child_task)
{
	ipc_port_t remote_task, remote_host;
	task_t new_task;
	kern_return_t kr;
	int vector_start;
	unsigned int entry_vector_count;
	ipc_port_t bootstrap;
	emulation_vector_t entry_vector;
	ipc_port_t registered[TASK_PORT_REGISTER_MAX];
	exception_mask_t exc_masks[EXC_TYPES_COUNT];
	ipc_port_t exc_ports[EXC_TYPES_COUNT];
	exception_behavior_t exc_behaviors[EXC_TYPES_COUNT];
	thread_state_flavor_t exc_flavors[EXC_TYPES_COUNT];
	unsigned count, exc_count;

#if	DIPC
	if (!dipc_node_is_valid (child_node)) {
		return KERN_INVALID_ARGUMENT;
	}

	if (child_node == dipc_node_self()) {
		if (clone) {
			/*
			 * Cloning: easy if kill_parent;
			 * (currently) impossible otherwise.
			 */
			if (kill_parent) {
				/*
				 * Just return the parent -- nothing says that
				 * the clone has to be a different task.
				 */
				*child_task = parent_task;
				return KERN_SUCCESS;
			} else {
				/*
				 * XXX
				 * There is no local call we can use with the
				 * same memory semantics -- we'd have to
				 * modify task_create_local, and vm_map_fork.
				 * Not hard, just probably unnecessary except
				 * for orthogonality.
				 */
				return KERN_INVALID_ARGUMENT;
			}
		} else {
			/*
			 * Not cloning: just use task_create_local,
			 * and task_terminate if appropriate.
			 */
			kr = task_create_local(parent_task, inherit_memory,
					       FALSE, child_task);
			if (kr != KERN_SUCCESS) {
				return kr;
			}
			if (kill_parent) {
				kr = task_terminate(parent_task);
				if (kr != KERN_SUCCESS) {
					/* cleanup */
					(void) task_terminate(*child_task);
					return kr;
				}
			}
			return KERN_SUCCESS;
		}
	}

	kr = task_get_emulation_vector(parent_task, &vector_start,
				       &entry_vector, &entry_vector_count);
	if (kr != KERN_SUCCESS) {
		printf("task_get_emulation_vector failed: kr %d %x\n", kr, kr);
		return kr;
	}

	kr = task_get_inherited_ports(parent_task, &bootstrap, registered,
				      &count, exc_masks, &exc_count,
				      exc_ports, exc_behaviors, exc_flavors);
	if (kr != KERN_SUCCESS) {
		printf("task_get_inherited_ports failed: kr %d %x\n", kr, kr);
		return kr;
	}

	remote_host = dipc_host_priv_port(child_node);
	if (remote_host == IP_NULL) {
		panic("norma_task_create:  no priv port for node %d\n",
		      child_node);
		return KERN_INVALID_ARGUMENT;
	}

	kr = r_norma_task_allocate(remote_host, vector_start, entry_vector,
				   entry_vector_count, bootstrap,
				   registered, count, exc_masks, exc_count,
				   exc_ports, exc_behaviors, exc_flavors,
				   &remote_task);
	if (kr != KERN_SUCCESS) {
		return kr;
	}

	if (inherit_memory) {
		task_copy_vm(remote_host, parent_task->map, clone,
			     kill_parent, remote_task);
	}

	if (kill_parent) {
		(void) task_terminate(parent_task);
	}

	/*
	 * Create a placeholder task for the benefit of convert_task_to_port.
	 * Set new_task->map to VM_MAP_NULL so that task_deallocate will
	 * know that this is only a placeholder task.
	 */
	new_task = (task_t) zalloc(task_zone);
	if (new_task == TASK_NULL) {
		panic("task_create: no memory for task structure");
	}

#if     MCMSG
	new_task->mcmsg_task = 0;
#endif  /* MCMSG */

	/* only one ref, for our caller */
	new_task->ref_count = 1;

	new_task->map = VM_MAP_NULL;
	new_task->itk_self = remote_task;
	mutex_init(&new_task->lock, ETAP_NORMA_TASK);
	itk_lock_init(new_task);

	*child_task = new_task;
	return(KERN_SUCCESS);
#else	/* DIPC */
	printf("norma_task_common:  no underlying transport!\n");
	return KERN_INVALID_ARGUMENT;
#endif	/* DIPC */
}