Beispiel #1
0
void
ipc_kobject_destroy(
	ipc_port_t	port)
{
	switch (ip_kotype(port)) {
	    case IKOT_PAGER:
		vm_object_destroy(port);
		break;

	    case IKOT_PAGER_TERMINATING:
		vm_object_pager_wakeup(port);
		break;

	    case IKOT_DEVICE:
	    case IKOT_SEMAPHORE:
	    case IKOT_LOCK_SET:
		break;

	    default:
#if	MACH_ASSERT
		printf("ipc_kobject_destroy: port 0x%x, kobj 0x%x, type %d\n",
		       port, port->ip_kobject, ip_kotype(port));
#endif	/* MACH_ASSERT */
		break;
	}
}
Beispiel #2
0
void
host_notify_port_destroy(
	ipc_port_t			port)
{
	host_notify_t		entry;

	mutex_lock(&host_notify_lock);

	ip_lock(port);
	if (ip_kotype(port) == IKOT_HOST_NOTIFY) {
		entry = (host_notify_t)port->ip_kobject;
		assert(entry != NULL);
		ipc_kobject_set_atomically(port, IKO_NULL, IKOT_NONE);
		ip_unlock(port);

		assert(entry->port == port);
		remqueue(NULL, (queue_entry_t)entry);
		mutex_unlock(&host_notify_lock);
		zfree(host_notify_zone, (vm_offset_t)entry);

		ipc_port_release_sonce(port);
		return;
	}
	ip_unlock(port);

	mutex_unlock(&host_notify_lock);
}
Beispiel #3
0
boolean_t
ipc_kobject_notify(
	mach_msg_header_t *request_header,
	mach_msg_header_t *reply_header)
{
	ipc_port_t port = (ipc_port_t) request_header->msgh_remote_port;

	((mig_reply_error_t *) reply_header)->RetCode = MIG_NO_REPLY;
	switch (request_header->msgh_id) {
		case MACH_NOTIFY_PORT_DELETED:
		case MACH_NOTIFY_PORT_DESTROYED:
		case MACH_NOTIFY_NO_SENDERS:
		case MACH_NOTIFY_SEND_ONCE:
		case MACH_NOTIFY_DEAD_NAME:
		break;

		default:
		return FALSE;
	}
	switch (ip_kotype(port)) {
		case IKOT_DEVICE:
		return ds_notify(request_header);

		case IKOT_MASTER_DEVICE:
		return ds_master_notify(request_header);

		default:
                return FALSE;
        }
}
Beispiel #4
0
/*
 *	Routine:	convert_port_to_mig_object [interface]
 *	Purpose:
 *		Base implementation of MIG intrans routine to convert from
 *		an incoming port reference to a new reference on the
 *		underlying object. A new reference must be created, because
 *		the port's reference could go away asynchronously.
 *	Returns:
 *		NULL - Not an active MIG object port or iid not supported
 *		Otherwise, a reference to the underlying MIG interface
 *	Conditions:
 *		Nothing locked.
 */
mig_object_t
convert_port_to_mig_object(
	ipc_port_t	port,
	const MIGIID	*iid)
{
	mig_object_t	mig_object;
	void 		*ppv;

	if (!IP_VALID(port))
		return NULL;

	ip_lock(port);
	if (!ip_active(port) || (ip_kotype(port) != IKOT_MIG)) {
		ip_unlock(port);
		return NULL;
	}

	/*
	 * Our port points to some MIG object interface.  Now
	 * query it to get a reference to the desired interface.
	 */
	ppv = NULL;
	mig_object = (mig_object_t)port->ip_kobject;
	mig_object->pVtbl->QueryInterface((IMIGObject *)mig_object, iid, &ppv);
	ip_unlock(port);
	return (mig_object_t)ppv;
}
Beispiel #5
0
void
mk_timer_port_destroy(
	ipc_port_t			port)
{
	mk_timer_t			timer = NULL;

	ip_lock(port);
	if (ip_kotype(port) == IKOT_TIMER) {
		timer = (mk_timer_t)port->ip_kobject;
		assert(timer != NULL);
		ipc_kobject_set_atomically(port, IKO_NULL, IKOT_NONE);
		simple_lock(&timer->lock);
		assert(timer->port == port);
	}
	ip_unlock(port);

	if (timer != NULL) {
		if (thread_call_cancel(&timer->call_entry))
			timer->active--;
		timer->is_armed = FALSE;

		timer->is_dead = TRUE;
		if (timer->active == 0) {
			simple_unlock(&timer->lock);
			zfree(mk_timer_zone, timer);

			ipc_port_release_send(port);
			return;
		}

		simple_unlock(&timer->lock);
	}
}
Beispiel #6
0
/*
 *	Routine: convert_port_to_locked_task
 *	Purpose:
 *		Internal helper routine to convert from a port to a locked
 *		task.  Used by several routines that try to convert from a
 *		task port to a reference on some task related object.
 *	Conditions:
 *		Nothing locked, blocking OK.
 */
task_t
convert_port_to_locked_task(ipc_port_t port)
{
        int try_failed_count = 0;

	while (IP_VALID(port)) {
		task_t task;

		ip_lock(port);
		if (!ip_active(port) || (ip_kotype(port) != IKOT_TASK)) {
			ip_unlock(port);
			return TASK_NULL;
		}
		task = (task_t) port->ip_kobject;
		assert(task != TASK_NULL);

		/*
		 * Normal lock ordering puts task_lock() before ip_lock().
		 * Attempt out-of-order locking here.
		 */
		if (task_lock_try(task)) {
			ip_unlock(port);
			return(task);
		}
		try_failed_count++;

		ip_unlock(port);
		mutex_pause(try_failed_count);
	}
	return TASK_NULL;
}
Beispiel #7
0
EXTERN io_object_t
iokit_lookup_connect_ref(io_object_t connectRef, ipc_space_t space)
{
	io_object_t obj = NULL;

	if (connectRef && MACH_PORT_VALID(CAST_MACH_PORT_TO_NAME(connectRef))) {
		ipc_port_t port;
		kern_return_t kr;

		kr = ipc_object_translate(space, CAST_MACH_PORT_TO_NAME(connectRef), MACH_PORT_RIGHT_SEND, (ipc_object_t *)&port);

		if (kr == KERN_SUCCESS) {
			assert(IP_VALID(port));

			ip_reference(port);
			ip_unlock(port);

			iokit_lock_port(port);
			if (ip_active(port) && (ip_kotype(port) == IKOT_IOKIT_CONNECT)) {
				obj = (io_object_t) port->ip_kobject;
				iokit_add_connect_reference(obj);
			}
			iokit_unlock_port(port);

			ip_release(port);
		}
	}

	return obj;
}
Beispiel #8
0
/*
 * fileport_notify
 *
 * Description: Handle a no-senders notification for a fileport.  Unless
 * 		the message is spoofed, destroys the port and releases
 * 		its reference on the fileglob.
 *
 * Parameters: msg		A Mach no-senders notification message.
 */
void
fileport_notify(mach_msg_header_t *msg)
{
	mach_no_senders_notification_t *notification = (void *)msg;
	ipc_port_t port = notification->not_header.msgh_remote_port;
	struct fileglob *fg = NULL;

	if (!IP_VALID(port))
		panic("Invalid port passed to fileport_notify()\n");

	ip_lock(port);

	fg = (struct fileglob *)port->ip_kobject;

	if (!ip_active(port)) 
		panic("Inactive port passed to fileport_notify()\n");
	if (ip_kotype(port) != IKOT_FILEPORT) 
		panic("Port of type other than IKOT_FILEPORT passed to fileport_notify()\n");
	if (fg == NULL) 
		panic("fileport without an assocated fileglob\n");

	if (port->ip_srights == 0) {
		ip_unlock(port);

		fileport_releasefg(fg);
		ipc_port_dealloc_kernel(port);
	} else {
		ip_unlock(port);
	}

	return;
}
Beispiel #9
0
void
ipc_kobject_destroy(
	ipc_port_t		port)
{
	switch (ip_kotype(port)) {

	case IKOT_TIMER:
		mk_timer_port_destroy(port);
		break;

	case IKOT_NAMED_ENTRY:
		mach_destroy_memory_entry(port);
		break;

	case IKOT_HOST_NOTIFY:
		host_notify_port_destroy(port);
		break;

#if CONFIG_MACF_MACH
	case IKOT_LABELH:
		labelh_destroy(port);
		break;
#endif

	default:
		break;
	}
}
Beispiel #10
0
/*
 *	Routine:	convert_port_to_clock
 *	Purpose:
 *		Convert from a port to a clock.
 *		Doesn't consume the port ref; produces a clock ref,
 *		which may be null.
 *	Conditions:
 *		Nothing locked.
 */
clock_t
convert_port_to_clock(
	ipc_port_t	port)
{
	clock_t		clock = CLOCK_NULL;

	if (IP_VALID(port)) {
		ip_lock(port);
		if (ip_active(port) &&
		    ((ip_kotype(port) == IKOT_CLOCK) ||
		     (ip_kotype(port) == IKOT_CLOCK_CTRL))) {
			clock = (clock_t) port->ip_kobject;
		}
		ip_unlock(port);
	}
	return (clock);
}
Beispiel #11
0
boolean_t
ref_pset_port_locked(ipc_port_t port, boolean_t matchn, processor_set_t *ppset)
{
	processor_set_t pset;

	pset = PROCESSOR_SET_NULL;
	if (ip_active(port) &&
		((ip_kotype(port) == IKOT_PSET) ||
			(matchn && (ip_kotype(port) == IKOT_PSET_NAME)))) {
		pset = (processor_set_t) port->ip_kobject;
	}

	*ppset = pset;
	ip_unlock(port);

	return (TRUE);
}
Beispiel #12
0
host_t
convert_port_to_host(
	ipc_port_t	port)
{
	host_t host = HOST_NULL;

	if (IP_VALID(port)) {
		ip_lock(port);
		if (ip_active(port) &&
		    ((ip_kotype(port) == IKOT_HOST) ||
		     (ip_kotype(port) == IKOT_HOST_PRIV)))
			host = (host_t) port->ip_kobject;
		ip_unlock(port);
	}

	return host;
}
Beispiel #13
0
processor_set_t
convert_port_to_pset_name(
	ipc_port_t	port)
{
	processor_set_t pset = PROCESSOR_SET_NULL;

	if (IP_VALID(port)) {
		ip_lock(port);
		if (ip_active(port) &&
		    ((ip_kotype(port) == IKOT_PSET) ||
		     (ip_kotype(port) == IKOT_PSET_NAME))) {
			pset = (processor_set_t) port->ip_kobject;
			pset_reference(pset);
		}
		ip_unlock(port);
	}

	return pset;
}
Beispiel #14
0
kern_return_t
xmm_object_reference(
	ipc_port_t	memory_object)
{
	ipc_port_t	xmm_object;
#if	DIPC
	node_name	node;
#endif	/* DIPC */

	ip_lock(memory_object);

	/* We shouldn't ever be doing remote xmm_object refs */
	assert(!IP_WAS_REMOTE(memory_object));
	if (IP_WAS_REMOTE(memory_object)) {
#if	DIPC
		node = DIPC_ORIGIN_NODE(memory_object);
		ip_unlock(memory_object);
		return r_xmm_remote_object_reference(dipc_host_priv_port(node),
					      memory_object);
#else	/* DIPC */
		panic("xmm_object_reference:  no transport");
#endif	/* DIPC */
	}

	/*
	 * return error if XMM object is terminating or terminated.
	 */
	if (((int)memory_object->ip_norma_xmm_object | 1) ==
	    ((int)memory_object | 1) ||
	    (xmm_object = memory_object->ip_norma_xmm_object) == IP_NULL) {
		ip_unlock(memory_object);
		assert(!IP_IS_REMOTE(xmm_object));
		return KERN_ABORTED;
	}

	assert(!IP_IS_REMOTE(xmm_object));
	assert(ip_kotype(xmm_object) == IKOT_XMM_OBJECT);
	assert((memory_object->ip_norma_xmm_object_refs > 0) ||
		(ip_kotype(memory_object) == IKOT_NONE));
	memory_object->ip_norma_xmm_object_refs++;
	ip_unlock(memory_object);
	return KERN_SUCCESS;
}
Beispiel #15
0
struct label *io_getlabel (ipc_object_t objp)
{
	ipc_port_t port = (ipc_port_t)objp;

	assert(io_otype(objp) == IOT_PORT);

	if (ip_kotype(port) == IKOT_LABELH)
		return &((ipc_labelh_t) port->ip_kobject)->lh_label;
	else
		return &port->ip_label;
}
Beispiel #16
0
/*
 * Routine:	semaphore_notify
 * Purpose:
 *	Called whenever the Mach port system detects no-senders
 *	on the semaphore port.
 *
 *	When a send-right is first created, a no-senders
 *	notification is armed (and a semaphore reference is donated).
 *
 *	A no-senders notification will be posted when no one else holds a
 *	send-right (reference) to the semaphore's port. This notification function
 *	will consume the semaphore reference donated to the extant collection of
 *	send-rights.
 */
void
semaphore_notify(mach_msg_header_t *msg)
{
	mach_no_senders_notification_t *notification = (void *)msg;
	ipc_port_t port = notification->not_header.msgh_remote_port;
	semaphore_t semaphore;

	assert(ip_active(port));
	assert(IKOT_SEMAPHORE == ip_kotype(port));
	semaphore = (semaphore_t)port->ip_kobject;

	semaphore_dereference(semaphore);
}
Beispiel #17
0
boolean_t
ref_pset_port_locked(ipc_port_t port, boolean_t matchn, processor_set_t *ppset)
{
	processor_set_t pset;

	pset = PROCESSOR_SET_NULL;
	if (ip_active(port) &&
		((ip_kotype(port) == IKOT_PSET) ||
		 (matchn && (ip_kotype(port) == IKOT_PSET_NAME)))) {
		pset = (processor_set_t) port->ip_kobject;
		if (!pset_lock_try(pset)) {
			ip_unlock(port);
			mutex_pause();
			return (FALSE);
		}
		pset->ref_count++;
		pset_unlock(pset);
	}
	*ppset = pset;
	ip_unlock(port);
	return (TRUE);
}
Beispiel #18
0
/*
 *	Routine:	convert_port_to_task_name
 *	Purpose:
 *		Convert from a port to a task name.
 *		Doesn't consume the port ref; produces a task name ref,
 *		which may be null.
 *	Conditions:
 *		Nothing locked.
 */
task_name_t
convert_port_to_task_name(
	ipc_port_t		port)
{
	task_name_t		task = TASK_NULL;

	if (IP_VALID(port)) {
		ip_lock(port);

		if (	ip_active(port)					&&
				(ip_kotype(port) == IKOT_TASK	||
				 ip_kotype(port) == IKOT_TASK_NAME)) {
			task = (task_name_t)port->ip_kobject;
			assert(task != TASK_NAME_NULL);

			task_reference_internal(task);
		}

		ip_unlock(port);
	}

	return (task);
}
Beispiel #19
0
static void
host_notify_all(
	host_flavor_t		notify_type,
	mach_msg_header_t	*msg,
	mach_msg_size_t		msg_size)
{
	queue_t		notify_queue = &host_notify_queue[notify_type];

	mutex_lock(&host_notify_lock);

	if (!queue_empty(notify_queue)) {
		queue_head_t		send_queue;
		host_notify_t		entry;

		send_queue = *notify_queue;
		queue_init(notify_queue);

		send_queue.next->prev = &send_queue;
		send_queue.prev->next = &send_queue;

		msg->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0);
		msg->msgh_local_port = MACH_PORT_NULL;
		msg->msgh_id = host_notify_replyid[notify_type];
		msg->msgh_reserved = 0;

		while ((entry = (host_notify_t)dequeue(&send_queue)) != NULL) {
			ipc_port_t		port;

			port = entry->port;
			assert(port != IP_NULL);

			ip_lock(port);
			assert(ip_kotype(port) == IKOT_HOST_NOTIFY);
			assert(port->ip_kobject == (ipc_kobject_t)entry);
			ipc_kobject_set_atomically(port, IKO_NULL, IKOT_NONE);
			ip_unlock(port);

			mutex_unlock(&host_notify_lock);
			zfree(host_notify_zone, (vm_offset_t)entry);

			msg->msgh_remote_port = port;

			(void) mach_msg_send_from_kernel(msg, msg_size);

			mutex_lock(&host_notify_lock);
		}
	}

	mutex_unlock(&host_notify_lock);
}
Beispiel #20
0
kern_return_t
mach_port_kobject(
	ipc_space_t			space,
	mach_port_name_t		name,
	natural_t			*typep,
	mach_vm_address_t		*addrp)
{
	ipc_entry_t entry;
	ipc_port_t port;
	kern_return_t kr;
	mach_vm_address_t kaddr;

	if (space == IS_NULL)
		return KERN_INVALID_TASK;

	kr = ipc_right_lookup_read(space, name, &entry);
	if (kr != KERN_SUCCESS)
		return kr;
	/* space is read-locked and active */

	if ((entry->ie_bits & MACH_PORT_TYPE_SEND_RECEIVE) == 0) {
		is_read_unlock(space);
		return KERN_INVALID_RIGHT;
	}

	__IGNORE_WCASTALIGN(port = (ipc_port_t) entry->ie_object);
	assert(port != IP_NULL);

	ip_lock(port);
	is_read_unlock(space);

	if (!ip_active(port)) {
		ip_unlock(port);
		return KERN_INVALID_RIGHT;
	}

	*typep = (unsigned int) ip_kotype(port);
	kaddr = (mach_vm_address_t)port->ip_kobject;
	ip_unlock(port);

#if (DEVELOPMENT || DEBUG)
	if (0 != kaddr && is_ipc_kobject(*typep))
		*addrp = VM_KERNEL_UNSLIDE_OR_PERM(kaddr);
	else
#endif
		*addrp = 0;

	return KERN_SUCCESS;
}
Beispiel #21
0
/*
 * fileport_get_fileglob
 *
 * Description: Obtain the fileglob associated with a given port.
 *
 * Parameters: port		A Mach port of type IKOT_FILEPORT.
 *
 * Returns:    NULL		The given Mach port did not reference a
 *				fileglob.
 *	       !NULL		The fileglob that is associated with the
 *				Mach port.
 *
 * Notes: The caller must have a reference on the fileport.
 */
struct fileglob *
fileport_port_to_fileglob(ipc_port_t port)
{
	struct fileglob *fg = NULL;

	if (!IP_VALID(port))
		return NULL;

	ip_lock(port);
	if (ip_active(port) && IKOT_FILEPORT == ip_kotype(port))
		fg = (void *)port->ip_kobject;
	ip_unlock(port);

	return fg;
}
Beispiel #22
0
void
ipc_kobject_set(
	ipc_port_t		port,
	ipc_kobject_t		kobject,
	ipc_kobject_type_t	type)
{
	ip_lock(port);
	assert(ip_active(port) || (ip_kotype(port) == IKOT_PAGER_TERMINATING));
#if	MACH_ASSERT
	port->ip_spares[2] = (port->ip_bits & IO_BITS_KOTYPE);
#endif	/* MACH_ASSERT */
	port->ip_bits = (port->ip_bits &~ IO_BITS_KOTYPE) | type;
	port->ip_kobject = kobject;
	ip_unlock(port);
}
Beispiel #23
0
ledger_t
convert_port_to_ledger(
		       ipc_port_t port)
{
	ledger_t ledger = LEDGER_NULL;

	if (IP_VALID(port)) {
		ip_lock(port);
		if (ip_active(port) &&
		    (ip_kotype(port) == IKOT_LEDGER))
			ledger = (ledger_t) port->ip_kobject;
		ip_unlock(port);
	}

	return ledger;
}
Beispiel #24
0
host_t
convert_port_to_host_security(
	ipc_port_t port)
{
	host_t host = HOST_NULL;

	if (IP_VALID(port)) {
		ip_lock(port);
		if (ip_active(port) &&
		    (ip_kotype(port) == IKOT_HOST_SECURITY))
			host = (host_t) port->ip_kobject;
		ip_unlock(port);
	}

	return host;
}
Beispiel #25
0
processor_t
convert_port_to_processor(
	ipc_port_t	port)
{
	processor_t processor = PROCESSOR_NULL;

	if (IP_VALID(port)) {
		ip_lock(port);
		if (ip_active(port) &&
		    (ip_kotype(port) == IKOT_PROCESSOR))
			processor = (processor_t) port->ip_kobject;
		ip_unlock(port);
	}

	return processor;
}
Beispiel #26
0
static void
iokit_no_senders( mach_no_senders_notification_t * notification )
{
    ipc_port_t		port;
    io_object_t		obj = NULL;
    ipc_kobject_type_t	type = IKOT_NONE;
    ipc_port_t		notify;

    port = (ipc_port_t) notification->not_header.msgh_remote_port;

    // convert a port to io_object_t.
    if( IP_VALID(port)) {
        iokit_lock_port(port);
        if( ip_active(port)) {
            obj = (io_object_t) port->ip_kobject;
	    type = ip_kotype( port );
            if( (IKOT_IOKIT_OBJECT  == type)
	     || (IKOT_IOKIT_CONNECT == type))
                iokit_add_reference( obj );
            else
                obj = NULL;
	}
        iokit_unlock_port(port);

        if( obj ) {

	    mach_port_mscount_t mscount = notification->not_count;

            if( KERN_SUCCESS != iokit_client_died( obj, port, type, &mscount ))
	    {
		/* Re-request no-senders notifications on the port (if still active) */
		ip_lock(port);
		if (ip_active(port)) {
			notify = ipc_port_make_sonce_locked(port);
			ipc_port_nsrequest( port, mscount + 1, notify, &notify);
			/* port unlocked */
			if ( notify != IP_NULL)
				ipc_port_release_sonce(notify);
		} else {
			ip_unlock(port);
		}
	    }
            iokit_remove_reference( obj );
        }
    }
}
Beispiel #27
0
void
xmm_object_set(
	ipc_port_t	memory_object,
	ipc_port_t	xmm_object,
	boolean_t	make_copy)
{
	assert(! IP_IS_REMOTE(xmm_object));
	assert(ip_kotype(xmm_object) == IKOT_XMM_OBJECT);
	assert(memory_object->ip_norma_xmm_object == IP_NULL);
	memory_object->ip_norma_xmm_object = ipc_port_make_send(xmm_object);
	if (make_copy) {
		memory_object->ip_norma_xmm_object_refs = 1;
		ipc_port_copy_send(xmm_object);
	} else {
		memory_object->ip_norma_xmm_object_refs = 0;
	}
}
Beispiel #28
0
kern_return_t
mk_timer_cancel_trap(
	struct mk_timer_cancel_trap_args *args)
{
	mach_port_name_t	name = args->name;
	mach_vm_address_t	result_time_addr = args->result_time; 
	uint64_t			armed_time = 0;
	mk_timer_t			timer;
	ipc_space_t			myspace = current_space();
	ipc_port_t			port;
	kern_return_t		result;

	result = ipc_port_translate_receive(myspace, name, &port);
	if (result != KERN_SUCCESS)
		return (result);

	if (ip_kotype(port) == IKOT_TIMER) {
		timer = (mk_timer_t)port->ip_kobject;
		assert(timer != NULL);
		simple_lock(&timer->lock);
		assert(timer->port == port);
		ip_unlock(port);

		if (timer->is_armed) {
			armed_time = timer->call_entry.deadline;
			if (thread_call_cancel(&timer->call_entry))
				timer->active--;
			timer->is_armed = FALSE;
		}

		simple_unlock(&timer->lock);
	}
	else {
		ip_unlock(port);
		result = KERN_INVALID_ARGUMENT;
	}

	if (result == KERN_SUCCESS)
		if (	result_time_addr != 0										&&
				copyout((void *)&armed_time, result_time_addr,
								sizeof (armed_time)) != 0					)
			result = KERN_FAILURE;

	return (result);
}
Beispiel #29
0
void
xmm_object_nuke(
	ipc_port_t	xmm_object)
{
	xmm_obj_t mobj;

	/*
	 * Get and disassociate mobj from xmm object port.
	 */
	assert(!IP_IS_REMOTE(xmm_object));
	assert(ip_kotype(xmm_object) == IKOT_XMM_OBJECT);
	mobj = (xmm_obj_t) xmm_object->ip_kobject;
	ipc_kobject_set(xmm_object, IKO_NULL, IKOT_NONE);
	/*
	 * Destroy xmm object port and mobj.
	 */
	xmm_object_destroy(xmm_object, mobj);
}
Beispiel #30
0
/*
 *	Routine:	port_name_to_clock
 *	Purpose:
 *		Convert from a clock name to a clock pointer.
 */
clock_t
port_name_to_clock(
	mach_port_name_t clock_name)
{
	clock_t		clock = CLOCK_NULL;
	ipc_space_t	space;
	ipc_port_t	port;

	if (clock_name == 0)
		return (clock);
	space = current_space();
	if (ipc_port_translate_send(space, clock_name, &port) != KERN_SUCCESS)
		return (clock);
	if (ip_active(port) && (ip_kotype(port) == IKOT_CLOCK))
		clock = (clock_t) port->ip_kobject;
	ip_unlock(port);
	return (clock);
}