*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
-#include <zone_debug.h>
#include <mach/boolean.h>
#include <mach/kern_return.h>
#include <mach/mig_errors.h>
#include <kern/clock.h>
#include <kern/spl.h>
-#include <kern/counters.h>
#include <kern/queue.h>
#include <kern/zalloc.h>
#include <kern/thread.h>
#define EXTERN
#define MIGEXTERN
+LCK_GRP_DECLARE(dev_lck_grp, "device");
+LCK_MTX_DECLARE(iokit_obj_to_port_binding_lock, &dev_lck_grp);
+
/*
* Lookup a device by its port.
* Doesn't consume the naked send right; produces a device reference.
*/
-static io_object_t
+io_object_t
iokit_lookup_io_object(ipc_port_t port, ipc_kobject_type_t type)
{
io_object_t obj;
iokit_lock_port(port);
if (ip_active(port) && (ip_kotype(port) == type)) {
- obj = (io_object_t) port->ip_kobject;
+ obj = (io_object_t) ip_get_kobject(port);
iokit_add_reference( obj, type );
} else {
obj = NULL;
return iokit_lookup_io_object(port, IKOT_IOKIT_CONNECT);
}
+MIGEXTERN io_object_t
+iokit_lookup_uext_object_port(
+ ipc_port_t port)
+{
+ return iokit_lookup_io_object(port, IKOT_UEXT_OBJECT);
+}
+
static io_object_t
iokit_lookup_object_in_space_with_port_name(mach_port_name_t name, ipc_kobject_type_t type, ipc_space_t space)
{
ipc_port_t port;
kern_return_t kr;
- kr = ipc_object_translate(space, name, MACH_PORT_RIGHT_SEND, (ipc_object_t *)&port);
+ kr = ipc_port_translate_send(space, name, &port);
if (kr == KERN_SUCCESS) {
assert(IP_VALID(port));
-
+ require_ip_active(port);
ip_reference(port);
ip_unlock(port);
iokit_lock_port(port);
- if (ip_active(port) && (ip_kotype(port) == type)) {
- obj = (io_object_t) port->ip_kobject;
+ if (ip_kotype(port) == type) {
+ obj = (io_object_t) ip_get_kobject(port);
iokit_add_reference(obj, type);
}
iokit_unlock_port(port);
return iokit_lookup_object_in_space_with_port_name(name, IKOT_IOKIT_CONNECT, current_space());
}
+EXTERN io_object_t
+iokit_lookup_uext_ref_current_task(mach_port_name_t name)
+{
+ return iokit_lookup_object_in_space_with_port_name(name, IKOT_UEXT_OBJECT, current_space());
+}
+
EXTERN void
iokit_retain_port( ipc_port_t port )
{
ipc_port_release( port );
}
+EXTERN void
+iokit_make_port_send( ipc_port_t port )
+{
+ ipc_port_make_send( port );
+}
+
EXTERN void
iokit_release_port_send( ipc_port_t port )
{
ipc_port_release_send( port );
}
-extern lck_mtx_t iokit_obj_to_port_binding_lock;
-
EXTERN void
iokit_lock_port( __unused ipc_port_t port )
{
EXTERN ipc_port_t
iokit_alloc_object_port( io_object_t obj, ipc_kobject_type_t type )
{
- ipc_port_t notify;
- ipc_port_t port;
-
- do {
- /* Allocate port, keeping a reference for it. */
- port = ipc_port_alloc_kernel();
- if (port == IP_NULL) {
- continue;
- }
-
- /* set kobject & type */
- ipc_kobject_set( port, (ipc_kobject_t) obj, type);
-
- /* Request no-senders notifications on the port. */
- ip_lock( port);
- notify = ipc_port_make_sonce_locked( port);
- ipc_port_nsrequest( port, 1, notify, ¬ify);
- /* port unlocked */
- assert( notify == IP_NULL);
- gIOKitPortCount++;
- } while (FALSE);
-
- return port;
+ /* Allocate port, keeping a reference for it. */
+ gIOKitPortCount++;
+ ipc_kobject_alloc_options_t options = IPC_KOBJECT_ALLOC_NSREQUEST;
+ if (type == IKOT_IOKIT_CONNECT) {
+ options |= IPC_KOBJECT_ALLOC_IMMOVABLE_SEND;
+ }
+ if (type == IKOT_UEXT_OBJECT) {
+ ipc_label_t label = IPC_LABEL_DEXT;
+ return ipc_kobject_alloc_labeled_port((ipc_kobject_t) obj, type, label, options);
+ } else {
+ return ipc_kobject_alloc_port((ipc_kobject_t) obj, type, options);
+ }
}
-
EXTERN kern_return_t
iokit_destroy_object_port( ipc_port_t port )
{
if (IP_VALID( sendPort )) {
kern_return_t kr;
- kr = ipc_object_copyout( task->itk_space, (ipc_object_t) sendPort,
- MACH_MSG_TYPE_PORT_SEND, TRUE, &name);
+ // Remove once <rdar://problem/45522961> is fixed.
+ // We need to make ith_knote NULL as ipc_object_copyout() uses
+ // thread-argument-passing and its value should not be garbage
+ current_thread()->ith_knote = ITH_KNOTE_NULL;
+ kr = ipc_object_copyout( task->itk_space, ip_to_object(sendPort),
+ MACH_MSG_TYPE_PORT_SEND, IPC_OBJECT_COPYOUT_FLAGS_NONE, NULL, NULL, &name);
if (kr != KERN_SUCCESS) {
- ipc_port_release_send( sendPort );
name = MACH_PORT_NULL;
}
} else if (sendPort == IP_NULL) {
ipc_kobject_type_t type = IKOT_NONE;
ipc_port_t notify;
- port = (ipc_port_t) notification->not_header.msgh_remote_port;
+ port = 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;
+ obj = (io_object_t) ip_get_kobject(port);
type = ip_kotype( port );
if ((IKOT_IOKIT_OBJECT == type)
|| (IKOT_IOKIT_CONNECT == type)
- || (IKOT_IOKIT_IDENT == type)) {
+ || (IKOT_IOKIT_IDENT == type)
+ || (IKOT_UEXT_OBJECT == type)) {
iokit_add_reference( obj, IKOT_IOKIT_OBJECT );
} else {
obj = NULL;
}
}
+kern_return_t
+iokit_label_dext_task(task_t task)
+{
+ return ipc_space_add_label(task->itk_space, IPC_LABEL_DEXT);
+}
+
/* need to create a pmap function to generalize */
unsigned int
IODefaultCacheBits(addr64_t pa)
case kIOMapPostedWrite:
flags = VM_WIMG_POSTED;
break;
+
+ case kIOMapRealTimeCache:
+ flags = VM_WIMG_RT;
+ break;
}
pmap_set_cache_attributes(pagenum, flags);
case kIOMapPostedWrite:
flags = VM_WIMG_POSTED;
break;
+
+ case kIOMapRealTimeCache:
+ flags = VM_WIMG_RT;
+ break;
}
pmap_flush_context_init(&pmap_flush_context_storage);