Loading...
iokit/Kernel/IOUserClient.cpp xnu-12377.101.15 xnu-8792.61.2
--- xnu/xnu-12377.101.15/iokit/Kernel/IOUserClient.cpp
+++ xnu/xnu-8792.61.2/iokit/Kernel/IOUserClient.cpp
@@ -48,8 +48,6 @@
 #include <sys/proc.h>
 #include <sys/kauth.h>
 #include <sys/codesign.h>
-#include <sys/code_signing.h>
-#include <vm/vm_kern_xnu.h>
 
 #include <mach/sdt.h>
 #include <os/hash.h>
@@ -136,67 +134,44 @@
 
 extern "C" {
 #include <mach/mach_traps.h>
-#include <vm/vm_map_xnu.h>
+#include <vm/vm_map.h>
 } /* extern "C" */
 
 struct IOMachPortHashList;
 
+static_assert(IKOT_MAX_TYPE <= 255);
+
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 // IOMachPort maps OSObjects to ports, avoiding adding an ivar to OSObject.
-class IOMachPort final : public OSObject
+class IOMachPort : public OSObject
 {
 	OSDeclareDefaultStructors(IOMachPort);
 public:
-	bool        hashed;
 	SLIST_ENTRY(IOMachPort) link;
 	ipc_port_t  port;
-	OSObject*   XNU_PTRAUTH_SIGNED_PTR("IOMachPort.object") object;
-
-	static IOMachPort* withObject(OSObject *obj);
-
-	static IOMachPortHashList* bucketForObject(OSObject *obj);
+	OSObject*   object;
+	UInt32      mscount;
+	UInt8       holdDestroy;
+	UInt8       type;
+
+	static IOMachPort* withObjectAndType(OSObject *obj, ipc_kobject_type_t type);
+
+	static IOMachPortHashList* bucketForObject(OSObject *obj,
+	    ipc_kobject_type_t type);
 
 	static LIBKERN_RETURNS_NOT_RETAINED IOMachPort* portForObjectInBucket(IOMachPortHashList *bucket, OSObject *obj, ipc_kobject_type_t type);
 
-	static IOMachPort *noMoreSenders( ipc_port_t port,
-	    ipc_kobject_type_t type, mach_port_mscount_t mscount );
+	static bool noMoreSendersForObject( OSObject * obj,
+	    ipc_kobject_type_t type, mach_port_mscount_t * mscount );
 	static void releasePortForObject( OSObject * obj,
 	    ipc_kobject_type_t type );
+	static void setHoldDestroy( OSObject * obj, ipc_kobject_type_t type );
 
 	static mach_port_name_t makeSendRightForTask( task_t task,
 	    io_object_t obj, ipc_kobject_type_t type );
 
 	virtual void free() APPLE_KEXT_OVERRIDE;
-
-	void
-	makePort(ipc_kobject_type_t type)
-	{
-		port = iokit_alloc_object_port(this, type);
-	}
-
-	void
-	adoptPort(IOMachPort *other, ipc_kobject_type_t type)
-	{
-		port = other->port;
-		ipc_kobject_enable(port, this, IKOT_IOKIT_CONNECT);
-		other->port = NULL;
-	}
-
-	void
-	disablePort(ipc_kobject_type_t type)
-	{
-		__assert_only ipc_kobject_t kobj;
-		kobj = ipc_kobject_disable(port, type);
-		assert(kobj == this);
-	}
-
-	template<typename T>
-	inline T *
-	getAs() const
-	{
-		return OSDynamicCast(T, object);
-	}
 };
 
 #define super OSObject
@@ -228,7 +203,7 @@
 }
 
 IOMachPortHashList*
-IOMachPort::bucketForObject(OSObject *obj)
+IOMachPort::bucketForObject(OSObject *obj, ipc_kobject_type_t type )
 {
 	return &gIOMachPortHash[os_hash_kernel_pointer(obj) % PORT_HASH_SIZE];
 }
@@ -239,7 +214,7 @@
 	IOMachPort *machPort;
 
 	SLIST_FOREACH(machPort, bucket, link) {
-		if (machPort->object == obj && iokit_port_type(machPort->port) == type) {
+		if (machPort->object == obj && machPort->type == type) {
 			return machPort;
 		}
 	}
@@ -247,150 +222,183 @@
 }
 
 IOMachPort*
-IOMachPort::withObject(OSObject *obj)
+IOMachPort::withObjectAndType(OSObject *obj, ipc_kobject_type_t type)
 {
 	IOMachPort *machPort = NULL;
 
 	machPort = new IOMachPort;
-	release_assert(machPort->init());
+	if (__improbable(machPort && !machPort->init())) {
+		OSSafeReleaseNULL(machPort);
+		return NULL;
+	}
+
 	machPort->object = obj;
+	machPort->type = (typeof(machPort->type))type;
+	machPort->port = iokit_alloc_object_port(obj, type);
 
 	obj->taggedRetain(OSTypeID(OSCollection));
+	machPort->mscount++;
 
 	return machPort;
 }
 
-IOMachPort *
-IOMachPort::noMoreSenders( ipc_port_t port, ipc_kobject_type_t type,
-    mach_port_mscount_t mscount )
-{
-	IOUserClient *uc = NULL;
-	IOMachPort   *machPort;
-	bool          destroyed;
+bool
+IOMachPort::noMoreSendersForObject( OSObject * obj,
+    ipc_kobject_type_t type, mach_port_mscount_t * mscount )
+{
+	IOMachPort *machPort = NULL;
+	IOUserClient *uc;
+	OSAction *action;
+	bool destroyed = true;
+
+	IOMachPortHashList *bucket = IOMachPort::bucketForObject(obj, type);
+
+	obj->retain();
 
 	lck_mtx_lock(gIOObjectPortLock);
 
-	iokit_lock_port(port);
-	machPort  = (IOMachPort *)ipc_kobject_get_locked(port, type);
-	destroyed = ipc_kobject_is_mscount_current_locked(port, mscount);
-	iokit_unlock_port(port);
+	machPort = IOMachPort::portForObjectInBucket(bucket, obj, type);
+
+	if (machPort) {
+		destroyed = (machPort->mscount <= *mscount);
+		if (!destroyed) {
+			*mscount = machPort->mscount;
+			lck_mtx_unlock(gIOObjectPortLock);
+		} else {
+			if ((IKOT_IOKIT_CONNECT == type) && (uc = OSDynamicCast(IOUserClient, obj))) {
+				uc->noMoreSenders();
+			}
+			SLIST_REMOVE(bucket, machPort, IOMachPort, link);
+
+			lck_mtx_unlock(gIOObjectPortLock);
+
+			OS_ANALYZER_SUPPRESS("77508635") OSSafeReleaseNULL(machPort);
+
+			obj->taggedRelease(OSTypeID(OSCollection));
+		}
+	} else {
+		lck_mtx_unlock(gIOObjectPortLock);
+	}
+
+	if ((IKOT_UEXT_OBJECT == type) && (action = OSDynamicCast(OSAction, obj))) {
+		action->Aborted();
+	}
+
+	if (IKOT_UEXT_OBJECT == type && IOUserServer::shouldLeakObjects()) {
+		// Leak object
+		obj->retain();
+	}
+
+	obj->release();
+
+	return destroyed;
+}
+
+void
+IOMachPort::releasePortForObject( OSObject * obj,
+    ipc_kobject_type_t type )
+{
+	IOMachPort *machPort;
+	IOMachPortHashList *bucket = IOMachPort::bucketForObject(obj, type);
+
+	assert(IKOT_IOKIT_CONNECT != type);
+
+	lck_mtx_lock(gIOObjectPortLock);
+
+	machPort = IOMachPort::portForObjectInBucket(bucket, obj, type);
+
+	if (machPort && !machPort->holdDestroy) {
+		obj->retain();
+		SLIST_REMOVE(bucket, machPort, IOMachPort, link);
+
+		lck_mtx_unlock(gIOObjectPortLock);
+
+		OS_ANALYZER_SUPPRESS("77508635") OSSafeReleaseNULL(machPort);
+
+		obj->taggedRelease(OSTypeID(OSCollection));
+		obj->release();
+	} else {
+		lck_mtx_unlock(gIOObjectPortLock);
+	}
+}
+
+void
+IOMachPort::setHoldDestroy( OSObject * obj, ipc_kobject_type_t type )
+{
+	IOMachPort *        machPort;
+
+	IOMachPortHashList *bucket = IOMachPort::bucketForObject(obj, type);
+	lck_mtx_lock(gIOObjectPortLock);
+
+	machPort = IOMachPort::portForObjectInBucket(bucket, obj, type);
+
+	if (machPort) {
+		machPort->holdDestroy = true;
+	}
+
+	lck_mtx_unlock(gIOObjectPortLock);
+}
+
+void
+IOMachPortDestroyUserReferences(OSObject * obj, natural_t type)
+{
+	IOMachPort::releasePortForObject(obj, type);
+}
+
+void
+IOUserClient::destroyUserReferences( OSObject * obj )
+{
+	IOMachPort *machPort;
+
+	IOMachPort::releasePortForObject( obj, IKOT_IOKIT_OBJECT );
+
+	// panther, 3160200
+	// IOMachPort::releasePortForObject( obj, IKOT_IOKIT_CONNECT );
+
+	obj->retain();
+	IOMachPortHashList *bucket = IOMachPort::bucketForObject(obj, IKOT_IOKIT_CONNECT);
+	IOMachPortHashList *mappingBucket = NULL;
+
+	lck_mtx_lock(gIOObjectPortLock);
+
+	IOUserClient * uc = OSDynamicCast(IOUserClient, obj);
+	if (uc && uc->mappings) {
+		mappingBucket = IOMachPort::bucketForObject(uc->mappings, IKOT_IOKIT_CONNECT);
+	}
+
+	machPort = IOMachPort::portForObjectInBucket(bucket, obj, IKOT_IOKIT_CONNECT);
 
 	if (machPort == NULL) {
 		lck_mtx_unlock(gIOObjectPortLock);
-		return NULL;
-	}
-
-	assert(machPort->port == port);
-
-	if (destroyed) {
-		if (machPort->hashed) {
-			IOMachPortHashList *bucket;
-
-			bucket = IOMachPort::bucketForObject(machPort->object);
-			machPort->hashed = false;
-			SLIST_REMOVE(bucket, machPort, IOMachPort, link);
-		}
-
-		machPort->disablePort(type);
-
-		if (IKOT_IOKIT_CONNECT == type) {
-			uc = machPort->getAs<IOUserClient>();
-		}
-	}
+		goto end;
+	}
+
+	SLIST_REMOVE(bucket, machPort, IOMachPort, link);
+	obj->taggedRelease(OSTypeID(OSCollection));
 
 	if (uc) {
 		uc->noMoreSenders();
-	}
-
-	lck_mtx_unlock(gIOObjectPortLock);
-
-	if (IKOT_UEXT_OBJECT == type) {
-		if (OSAction *action = machPort->getAs<OSAction>()) {
-			action->Aborted();
-		}
-
-		if (IOUserServer::shouldLeakObjects()) {
-			// Leak object
-			machPort->object->retain();
-		}
-	}
-
-	return destroyed ? machPort : NULL;
-}
-
-void
-IOMachPort::releasePortForObject( OSObject * obj, ipc_kobject_type_t type )
-{
-	bool destroyed = false;
-	IOMachPort *machPort;
-	IOService  *service;
-	IOMachPortHashList *bucket = IOMachPort::bucketForObject(obj);
-
-	assert(IKOT_IOKIT_CONNECT != type);
-
-	lck_mtx_lock(gIOObjectPortLock);
-
-	machPort = IOMachPort::portForObjectInBucket(bucket, obj, type);
-
-	if (machPort
-	    && ((type != IKOT_IOKIT_OBJECT)
-	    || !(service = OSDynamicCast(IOService, obj))
-	    || !service->machPortHoldDestroy())) {
-		machPort->hashed = false;
-		SLIST_REMOVE(bucket, machPort, IOMachPort, link);
-		machPort->disablePort(type);
-		destroyed = true;
-	}
-
-	lck_mtx_unlock(gIOObjectPortLock);
-
-	if (destroyed) {
-		machPort->release();
-	}
-}
-
-void
-IOUserClient::destroyUserReferences( OSObject * obj )
-{
-	IOMachPort   *machPort = NULL;
-	OSObject     *mappings = NULL;
-
-	IOMachPort::releasePortForObject( obj, IKOT_IOKIT_OBJECT );
-
-	IOUserClient * uc = OSDynamicCast(IOUserClient, obj);
-	IOMachPortHashList *bucket = IOMachPort::bucketForObject(obj);
-
-	lck_mtx_lock(gIOObjectPortLock);
-
-	machPort = IOMachPort::portForObjectInBucket(bucket, obj, IKOT_IOKIT_CONNECT);
-
-	if (machPort == NULL) {
+		if (uc->mappings) {
+			uc->mappings->taggedRetain(OSTypeID(OSCollection));
+			machPort->object = uc->mappings;
+			SLIST_INSERT_HEAD(mappingBucket, machPort, link);
+			iokit_switch_object_port(machPort->port, uc->mappings, IKOT_IOKIT_CONNECT);
+
+			lck_mtx_unlock(gIOObjectPortLock);
+
+			OSSafeReleaseNULL(uc->mappings);
+		} else {
+			lck_mtx_unlock(gIOObjectPortLock);
+			OS_ANALYZER_SUPPRESS("77508635") OSSafeReleaseNULL(machPort);
+		}
+	} else {
 		lck_mtx_unlock(gIOObjectPortLock);
-		return;
-	}
-
-	machPort->hashed = false;
-	SLIST_REMOVE(bucket, machPort, IOMachPort, link);
-	machPort->disablePort(IKOT_IOKIT_CONNECT);
-
-	if (uc) {
-		mappings = uc->mappings;
-		uc->mappings = NULL;
-
-		uc->noMoreSenders();
-
-		if (mappings) {
-			IOMachPort *newPort;
-
-			newPort = IOMachPort::withObject(mappings);
-			newPort->adoptPort(machPort, IKOT_IOKIT_CONNECT);
-		}
-	}
-
-	lck_mtx_unlock(gIOObjectPortLock);
-
-	OSSafeReleaseNULL(mappings);
-	machPort->release();
+		OS_ANALYZER_SUPPRESS("77508635") OSSafeReleaseNULL(machPort);
+	}
+
+
+end:
+	OSSafeReleaseNULL(obj);
 }
 
 mach_port_name_t
@@ -404,12 +412,10 @@
 IOMachPort::free( void )
 {
 	if (port) {
-		iokit_destroy_object_port(port, iokit_port_type(port));
-	}
-	object->taggedRelease(OSTypeID(OSCollection));
+		iokit_destroy_object_port( port, type );
+	}
 	super::free();
 }
-
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
@@ -463,7 +469,11 @@
 		return false;
 	}
 
-	IOLockInlineInit(&lock);
+	lock = IOLockAlloc();
+	if (!lock) {
+		return false;
+	}
+
 	return true;
 }
 
@@ -473,17 +483,19 @@
 	if (userIteratorObject) {
 		userIteratorObject->release();
 	}
-	IOLockInlineDestroy(&lock);
+	if (lock) {
+		IOLockFree(lock);
+	}
 	OSObject::free();
 }
 
 void
 IOUserIterator::reset()
 {
-	IOLockLock(&lock);
+	IOLockLock(lock);
 	assert(OSDynamicCast(OSIterator, userIteratorObject));
 	((OSIterator *)userIteratorObject)->reset();
-	IOLockUnlock(&lock);
+	IOLockUnlock(lock);
 }
 
 bool
@@ -491,10 +503,10 @@
 {
 	bool ret;
 
-	IOLockLock(&lock);
+	IOLockLock(lock);
 	assert(OSDynamicCast(OSIterator, userIteratorObject));
 	ret = ((OSIterator *)userIteratorObject)->isValid();
-	IOLockUnlock(&lock);
+	IOLockUnlock(lock);
 
 	return ret;
 }
@@ -511,14 +523,14 @@
 {
 	OSObject * ret = NULL;
 
-	IOLockLock(&lock);
+	IOLockLock(lock);
 	if (userIteratorObject) {
 		ret = ((OSIterator *)userIteratorObject)->getNextObject();
 		if (ret) {
 			ret->retain();
 		}
 	}
-	IOLockUnlock(&lock);
+	IOLockUnlock(lock);
 
 	return ret;
 }
@@ -567,11 +579,19 @@
 // for retain and release.
 #ifndef __clang_analyzer__
 void
-iokit_add_reference( io_object_t obj )
-{
+iokit_add_reference( io_object_t obj, natural_t type )
+{
+	IOUserClient * uc;
+
 	if (!obj) {
 		return;
 	}
+
+	if ((IKOT_IOKIT_CONNECT == type)
+	    && (uc = OSDynamicCast(IOUserClient, obj))) {
+		OSIncrementAtomic(&uc->__ipc);
+	}
+
 	obj->retain();
 }
 
@@ -587,87 +607,27 @@
 void
 iokit_remove_connect_reference(LIBKERN_CONSUMED io_object_t obj )
 {
+	IOUserClient * uc;
+	bool           finalize = false;
+
 	if (!obj) {
 		return;
 	}
+
+	if ((uc = OSDynamicCast(IOUserClient, obj))) {
+		if (1 == OSDecrementAtomic(&uc->__ipc) && uc->isInactive()) {
+			IOLockLock(gIOObjectPortLock);
+			if ((finalize = uc->__ipcFinal)) {
+				uc->__ipcFinal = false;
+			}
+			IOLockUnlock(gIOObjectPortLock);
+		}
+		if (finalize) {
+			uc->scheduleFinalize(true);
+		}
+	}
+
 	obj->release();
-}
-
-enum {
-	kIPCLockNone  = 0,
-	kIPCLockRead  = 1,
-	kIPCLockWrite = 2
-};
-
-void
-IOUserClient::ipcEnter(int locking)
-{
-	switch (locking) {
-	case kIPCLockWrite:
-		IORWLockWrite(&lock);
-		break;
-	case kIPCLockRead:
-		IORWLockRead(&lock);
-		break;
-	case kIPCLockNone:
-		break;
-	default:
-		panic("ipcEnter");
-	}
-
-	OSIncrementAtomic(&__ipc);
-}
-
-void
-IOUserClient::ipcExit(int locking)
-{
-	bool finalize = false;
-
-	assert(__ipc);
-	if (1 == OSDecrementAtomic(&__ipc) && isInactive()) {
-		IOLockLock(gIOObjectPortLock);
-		if ((finalize = __ipcFinal)) {
-			__ipcFinal = false;
-		}
-		IOLockUnlock(gIOObjectPortLock);
-		if (finalize) {
-			scheduleFinalize(true);
-		}
-	}
-	switch (locking) {
-	case kIPCLockWrite:
-	case kIPCLockRead:
-		IORWLockUnlock(&lock);
-		break;
-	case kIPCLockNone:
-		break;
-	default:
-		panic("ipcExit");
-	}
-}
-
-void
-iokit_kobject_retain(io_kobject_t machPort)
-{
-	assert(OSDynamicCast(IOMachPort, machPort));
-	machPort->retain();
-}
-
-io_object_t
-iokit_copy_object_for_consumed_kobject(LIBKERN_CONSUMED io_kobject_t machPort)
-{
-	io_object_t result;
-
-	assert(OSDynamicCast(IOMachPort, machPort));
-
-	/*
-	 * IOMachPort::object is never nil-ed, so this just borrows its port
-	 * reference to make new rights.
-	 */
-	result = machPort->object;
-	iokit_add_reference(result);
-	machPort->release();
-	return result;
 }
 
 bool
@@ -687,110 +647,73 @@
 }
 
 ipc_port_t
-iokit_port_make_send_for_object( io_object_t obj, ipc_kobject_type_t type )
+iokit_port_for_object( io_object_t obj, ipc_kobject_type_t type )
 {
 	IOMachPort *machPort = NULL;
-	ipc_port_t  port = NULL;
-
-	IOMachPortHashList *bucket = IOMachPort::bucketForObject(obj);
+	ipc_port_t   port = NULL;
+
+	IOMachPortHashList *bucket = IOMachPort::bucketForObject(obj, type);
 
 	lck_mtx_lock(gIOObjectPortLock);
 
 	machPort = IOMachPort::portForObjectInBucket(bucket, obj, type);
 
 	if (__improbable(machPort == NULL)) {
-		machPort = IOMachPort::withObject(obj);
-		machPort->makePort(type);
-		machPort->hashed = true;
+		machPort = IOMachPort::withObjectAndType(obj, type);
+		if (__improbable(machPort == NULL)) {
+			goto end;
+		}
 		SLIST_INSERT_HEAD(bucket, machPort, link);
-	}
-
-	port = ipc_kobject_make_send( machPort->port, machPort, type );
-
+	} else {
+		machPort->mscount++;
+	}
+
+	iokit_retain_port(machPort->port);
+	port = machPort->port;
+
+end:
 	lck_mtx_unlock(gIOObjectPortLock);
 
 	return port;
 }
 
-/*
- * Handle the No-More_Senders notification generated from a device port destroy.
- * Since there are no longer any tasks which hold a send right to this device
- * port a NMS notification has been generated.
- */
-
-void
-iokit_ident_no_senders( ipc_port_t port, mach_port_mscount_t mscount )
-{
-	IOMachPort *machPort;
-
-	machPort = IOMachPort::noMoreSenders(port, IKOT_IOKIT_IDENT, mscount);
-
-	if (machPort) {
-		if (IOUserServerCheckInToken *token =
-		    machPort->getAs<IOUserServerCheckInToken>()) {
+kern_return_t
+iokit_client_died( io_object_t obj, ipc_port_t /* port */,
+    ipc_kobject_type_t type, mach_port_mscount_t * mscount )
+{
+	IOUserClient *      client;
+	IOMemoryMap *       map;
+	IOUserNotification * notify;
+	IOUserServerCheckInToken * token;
+
+	if (!IOMachPort::noMoreSendersForObject( obj, type, mscount )) {
+		return kIOReturnNotReady;
+	}
+
+	switch (type) {
+	case IKOT_IOKIT_CONNECT:
+		if ((client = OSDynamicCast( IOUserClient, obj ))) {
+			IOStatisticsClientCall();
+			IORWLockWrite(client->lock);
+			client->clientDied();
+			IORWLockUnlock(client->lock);
+		}
+		break;
+	case IKOT_IOKIT_OBJECT:
+		if ((map = OSDynamicCast( IOMemoryMap, obj ))) {
+			map->taskDied();
+		} else if ((notify = OSDynamicCast( IOUserNotification, obj ))) {
+			notify->setNotification( NULL );
+		}
+		break;
+	case IKOT_IOKIT_IDENT:
+		if ((token = OSDynamicCast( IOUserServerCheckInToken, obj ))) {
 			token->cancel();
 		}
-		machPort->release();
-	}
-}
-
-void
-iokit_object_no_senders( ipc_port_t port, mach_port_mscount_t mscount )
-{
-	IOMachPort *machPort;
-
-	machPort = IOMachPort::noMoreSenders(port, IKOT_IOKIT_OBJECT, mscount);
-
-	if (machPort) {
-		if (IOMemoryMap *map = machPort->getAs<IOMemoryMap>()) {
-			map->taskDied();
-		} else if (IOUserNotification *notify =
-		    machPort->getAs<IOUserNotification>()) {
-			notify->setNotification( NULL );
-		}
-		machPort->release();
-	}
-}
-
-void
-iokit_connect_no_senders( ipc_port_t port, mach_port_mscount_t mscount )
-{
-	IOMachPort *machPort;
-
-	machPort = IOMachPort::noMoreSenders(port, IKOT_IOKIT_CONNECT, mscount);
-
-	if (machPort) {
-		if (IOUserClient *client = machPort->getAs<IOUserClient>()) {
-			IOStatisticsClientCall();
-			IORWLockWrite(&client->lock);
-			client->clientDied();
-			IORWLockUnlock(&client->lock);
-		}
-		machPort->release();
-	}
-}
-
-void
-iokit_uext_no_senders( ipc_port_t port, mach_port_mscount_t mscount )
-{
-	IOMachPort *machPort;
-
-	machPort = IOMachPort::noMoreSenders(port, IKOT_UEXT_OBJECT, mscount);
-
-	if (machPort) {
-		if (IOUserClient *uc = machPort->getAs<IOUserUserClient>()) {
-			IOService *provider = NULL;
-			uc->lockForArbitration();
-			provider = uc->getProvider();
-			if (provider) {
-				provider->retain();
-			}
-			uc->unlockForArbitration();
-			uc->setTerminateDefer(provider, false);
-			OSSafeReleaseNULL(provider);
-		}
-		machPort->release();
-	}
+		break;
+	}
+
+	return kIOReturnSuccess;
 }
 };      /* extern "C" */
 
@@ -1028,7 +951,7 @@
 	bool                sendPing = false;
 	mach_msg_size_t     msgSize, payloadSize;
 
-	IOTakeLock( &lock );
+	IOTakeLock( lock );
 
 	count = newSet->getCount();
 	if (count < kMaxOutstanding) {
@@ -1038,27 +961,21 @@
 		}
 	}
 
-	IOUnlock( &lock );
+	IOUnlock( lock );
 
 	if (kIOServiceTerminatedNotificationType == msgType) {
-		lck_mtx_lock(gIOObjectPortLock);
-		newService->setMachPortHoldDestroy(true);
-		lck_mtx_unlock(gIOObjectPortLock);
+		IOMachPort::setHoldDestroy( newService, IKOT_IOKIT_OBJECT );
 	}
 
 	if (sendPing) {
-		/*
-		 * This right will be consumed when the message we form below
-		 * is sent by kernel_mach_msg_send_with_builder_internal(),
-		 * because we make the disposition for the right move-send.
-		 */
-		port = iokit_port_make_send_for_object( this, IKOT_IOKIT_OBJECT );
+		port = iokit_port_for_object( this, IKOT_IOKIT_OBJECT );
 
 		payloadSize = sizeof(PingMsgUdata) - sizeof(OSAsyncReference64) + msgReferenceSize;
 		msgSize = (mach_msg_size_t)(sizeof(PingMsgKdata) + payloadSize);
 
 		kr = kernel_mach_msg_send_with_builder_internal(0, payloadSize,
-		    MACH_SEND_KERNEL_IMPORTANCE, MACH_MSG_TIMEOUT_NONE, NULL,
+		    (MACH_SEND_MSG | MACH_SEND_ALWAYS | MACH_SEND_IMPORTANCE),
+		    MACH_MSG_TIMEOUT_NONE, NULL,
 		    ^(mach_msg_header_t *hdr, __assert_only mach_msg_descriptor_t *descs, void *payload){
 			PingMsgUdata *udata = (PingMsgUdata *)payload;
 
@@ -1066,7 +983,7 @@
 			hdr->msgh_local_port     = port;
 			hdr->msgh_bits           = MACH_MSGH_BITS(
 				MACH_MSG_TYPE_COPY_SEND /*remote*/,
-				MACH_MSG_TYPE_MOVE_SEND /*local*/);
+				MACH_MSG_TYPE_MAKE_SEND /*local*/);
 			hdr->msgh_size           = msgSize;
 			hdr->msgh_id             = kOSNotificationMessageID;
 
@@ -1080,6 +997,10 @@
 			bcopy( msgReference, udata->notifyHeader.reference, msgReferenceSize );
 		});
 
+		if (port) {
+			iokit_release_port( port );
+		}
+
 		if ((KERN_SUCCESS != kr) && !ipcLogged) {
 			ipcLogged = true;
 			IOLog("%s: kernel_mach_msg_send (0x%x)\n", __PRETTY_FUNCTION__, kr );
@@ -1101,7 +1022,7 @@
 	unsigned int        count;
 	OSObject *          result;
 
-	IOLockLock(&lock);
+	IOLockLock(lock);
 
 	count = newSet->getCount();
 	if (count) {
@@ -1113,7 +1034,7 @@
 		armed = true;
 	}
 
-	IOLockUnlock(&lock);
+	IOLockUnlock(lock);
 
 	return result;
 }
@@ -1228,16 +1149,12 @@
 	}
 	mach_msg_size_t payloadSize = thisMsgSize - sizeof(PingMsgKdata);
 
-	/*
-	 * These rights will be consumed when the message we form below
-	 * is sent by kernel_mach_msg_send_with_builder_internal(),
-	 * because we make the disposition for the rights move-send.
-	 */
-	providerPort = iokit_port_make_send_for_object( provider, IKOT_IOKIT_OBJECT );
-	thisPort = iokit_port_make_send_for_object( this, IKOT_IOKIT_OBJECT );
+	providerPort = iokit_port_for_object( provider, IKOT_IOKIT_OBJECT );
+	thisPort = iokit_port_for_object( this, IKOT_IOKIT_OBJECT );
 
 	kr = kernel_mach_msg_send_with_builder_internal(1, payloadSize,
-	    MACH_SEND_KERNEL_IMPORTANCE, MACH_MSG_TIMEOUT_NONE, NULL,
+	    (MACH_SEND_MSG | MACH_SEND_ALWAYS | MACH_SEND_IMPORTANCE),
+	    MACH_MSG_TIMEOUT_NONE, NULL,
 	    ^(mach_msg_header_t *hdr, mach_msg_descriptor_t *descs, void *payload){
 		mach_msg_port_descriptor_t *port_desc = (mach_msg_port_descriptor_t *)descs;
 		PingMsgUdata *udata = (PingMsgUdata *)payload;
@@ -1246,18 +1163,17 @@
 
 		hdr->msgh_remote_port    = remotePort;
 		hdr->msgh_local_port     = thisPort;
-		hdr->msgh_bits           = MACH_MSGH_BITS_SET(
+		hdr->msgh_bits           = MACH_MSGH_BITS_COMPLEX
+		|  MACH_MSGH_BITS(
 			MACH_MSG_TYPE_COPY_SEND /*remote*/,
-			MACH_MSG_TYPE_MOVE_SEND /*local*/,
-			MACH_MSG_TYPE_NONE /*voucher*/,
-			MACH_MSGH_BITS_COMPLEX);
+			MACH_MSG_TYPE_MAKE_SEND /*local*/);
 		hdr->msgh_size           = thisMsgSize;
 		hdr->msgh_id             = kOSNotificationMessageID;
 
 		/* body.msgh_descriptor_count is set automatically after the closure */
 
 		port_desc[0].name              = providerPort;
-		port_desc[0].disposition       = MACH_MSG_TYPE_MOVE_SEND;
+		port_desc[0].disposition       = MACH_MSG_TYPE_MAKE_SEND;
 		port_desc[0].type              = MACH_MSG_PORT_DESCRIPTOR;
 		/* End of kernel processed data */
 
@@ -1282,6 +1198,13 @@
 		}
 	});
 
+	if (thisPort) {
+		iokit_release_port( thisPort );
+	}
+	if (providerPort) {
+		iokit_release_port( providerPort );
+	}
+
 	if (kr == MACH_SEND_NO_BUFFER) {
 		return kIOReturnNoMemory;
 	}
@@ -1313,12 +1236,6 @@
 OSDefineMetaClassAndAbstractStructors( IOUserClient, IOService )
 
 IOLock       * gIOUserClientOwnersLock;
-
-static TUNABLE(bool, gEnforcePowerEntitlement, "enforce-power-entitlement", false);
-
-static_assert(offsetof(IOUserClient, __opaque_end) -
-    offsetof(IOUserClient, __opaque_start) == sizeof(void *) * 9,
-    "ABI check: Opaque ivars for IOUserClient must be 9 void * big");
 
 void
 IOUserClient::initialize( void )
@@ -1333,6 +1250,7 @@
 	IOTrackingQueueCollectUser(IOServiceMessageUserNotification::gMetaClass.getTracking());
 	IOTrackingQueueCollectUser(IOServiceUserNotification::gMetaClass.getTracking());
 	IOTrackingQueueCollectUser(IOUserClient::gMetaClass.getTracking());
+	IOTrackingQueueCollectUser(IOMachPort::gMetaClass.getTracking());
 #endif /* IOTRACKING */
 }
 
@@ -1575,33 +1493,54 @@
 IOUserClient::copyClientEntitlement( task_t task,
     const char * entitlement )
 {
-	void *entitlement_object = NULL;
-
-	if (task == NULL) {
-		task = current_task();
-	}
-
-	/* Validate input arguments */
-	if (task == kernel_task || entitlement == NULL) {
+	OSDictionary *entitlements;
+	OSObject *value;
+
+	#if PMAP_CS_ENABLE && !CONFIG_X86_64_COMPAT
+	if (pmap_cs_enabled() && amfi->query_context_to_object) {
+		struct CEQueryContext queryCtx = {};
+		size_t entlen = strlen(entitlement);
+		CEQuery_t query = {
+			/*
+			 *       We only select the dict value, if it exists this we will get
+			 *       a value CEQueryContext back to points to pmap backed memory
+			 */
+			CESelectDictValueDynamic((const uint8_t*)entitlement, entlen)
+		};
+		if (task == current_task()) {
+			// NULL task means current task, which translated to the current pmap
+			if (!pmap_query_entitlements(NULL, query, 1, &queryCtx)) {
+				return NULL;
+			}
+		} else {
+			vm_map_t task_map = get_task_map_reference(task);
+			if (task_map) {
+				pmap_t pmap = vm_map_get_pmap(task_map);
+				if (!pmap || !pmap_query_entitlements(pmap, query, 1, &queryCtx)) {
+					vm_map_deallocate(task_map);
+					return NULL;
+				}
+				vm_map_deallocate(task_map);
+			}
+		}
+		value = (OSObject*)amfi->query_context_to_object(&queryCtx);
+		return value;
+	}
+	#endif
+
+	entitlements = copyClientEntitlements(task);
+	if (entitlements == NULL) {
 		return NULL;
 	}
-	proc_t proc = (proc_t)get_bsdtask_info(task);
-
-	if (proc == NULL) {
-		return NULL;
-	}
-
-	kern_return_t ret = amfi->OSEntitlements.copyEntitlementAsOSObjectWithProc(
-		proc,
-		entitlement,
-		&entitlement_object);
-
-	if (ret != KERN_SUCCESS) {
-		return NULL;
-	}
-	assert(entitlement_object != NULL);
-
-	return (OSObject*)entitlement_object;
+
+	/* Fetch the entitlement value from the dictionary. */
+	value = entitlements->getObject(entitlement);
+	if (value != NULL) {
+		value->retain();
+	}
+
+	entitlements->release();
+	return value;
 }
 
 OSObject *
@@ -1682,8 +1621,6 @@
 	}
 	setTerminateDefer(NULL, true);
 	IOStatisticsRegisterCounter();
-	IORWLockInlineInit(&lock);
-	IOLockInlineInit(&filterLock);
 
 	return true;
 }
@@ -1817,46 +1754,16 @@
 	}
 }
 
-static kern_return_t
-iokit_task_terminate_phase1(task_t task)
-{
-	queue_head_t      * taskque;
-	IOUserClientOwner * iter;
-	OSSet             * userServers = NULL;
-
-	if (!task_is_driver(task)) {
-		return KERN_SUCCESS;
-	}
-	userServers = OSSet::withCapacity(1);
-
-	IOLockLock(gIOUserClientOwnersLock);
-
-	taskque = task_io_user_clients(task);
-	queue_iterate(taskque, iter, IOUserClientOwner *, taskLink) {
-		userServers->setObject(iter->uc);
-	}
-	IOLockUnlock(gIOUserClientOwnersLock);
-
-	if (userServers) {
-		IOUserServer * userServer;
-		while ((userServer = OSRequiredCast(IOUserServer, userServers->getAnyObject()))) {
-			userServer->clientDied();
-			userServers->removeObject(userServer);
-		}
-		userServers->release();
-	}
-	return KERN_SUCCESS;
-}
-
-static kern_return_t
-iokit_task_terminate_phase2(task_t task)
-{
-	queue_head_t      * taskque;
+extern "C" kern_return_t
+iokit_task_terminate(task_t task)
+{
 	IOUserClientOwner * owner;
 	IOUserClient      * dead;
 	IOUserClient      * uc;
+	queue_head_t      * taskque;
 
 	IOLockLock(gIOUserClientOwnersLock);
+
 	taskque = task_io_user_clients(task);
 	dead = NULL;
 	while (!queue_empty(taskque)) {
@@ -1875,6 +1782,7 @@
 		}
 		IOFreeType(owner, IOUserClientOwner);
 	}
+
 	IOLockUnlock(gIOUserClientOwnersLock);
 
 	while (dead) {
@@ -1890,19 +1798,6 @@
 	return KERN_SUCCESS;
 }
 
-extern "C" kern_return_t
-iokit_task_terminate(task_t task, int phase)
-{
-	switch (phase) {
-	case 1:
-		return iokit_task_terminate_phase1(task);
-	case 2:
-		return iokit_task_terminate_phase2(task);
-	default:
-		panic("iokit_task_terminate phase %d", phase);
-	}
-}
-
 struct IOUCFilterPolicy {
 	task_t             task;
 	io_filter_policy_t filterPolicy;
@@ -1916,7 +1811,7 @@
 	io_filter_policy_t filterPolicy;
 
 	filterPolicy = 0;
-	IOLockLock(&filterLock);
+	IOLockLock(filterLock);
 
 	for (elem = reserved->filterPolicies; elem && (elem->task != task); elem = elem->next) {
 	}
@@ -1935,7 +1830,7 @@
 		filterPolicy = addFilterPolicy;
 	}
 
-	IOLockUnlock(&filterLock);
+	IOLockUnlock(filterLock);
 	return filterPolicy;
 }
 
@@ -1944,6 +1839,12 @@
 {
 	if (mappings) {
 		mappings->release();
+	}
+	if (lock) {
+		IORWLockFree(lock);
+	}
+	if (filterLock) {
+		IOLockFree(filterLock);
 	}
 
 	IOStatisticsUnregisterCounter();
@@ -1962,8 +1863,6 @@
 			IOFreeType(elem, IOUCFilterPolicy);
 		}
 		IOFreeType(reserved, ExpansionData);
-		IORWLockInlineDestroy(&lock);
-		IOLockInlineDestroy(&filterLock);
 	}
 
 	super::free();
@@ -2076,7 +1975,7 @@
 
 	err = clientMemoryForType((UInt32) type, &options, &memory );
 
-	if ((kIOReturnSuccess == err) && memory && !memory->hasSharingContext()) {
+	if (memory && (kIOReturnSuccess == err)) {
 		FAKE_STACK_FRAME(getMetaClass());
 
 		options = (options & ~kIOMapUserOptionsMask)
@@ -2371,15 +2270,15 @@
 
 	if ((options & kIOUserNotifyOptionCanDrop) != 0) {
 		kr = mach_msg_send_from_kernel_with_options( &replyMsg.msgHdr,
-		    replyMsg.msgHdr.msgh_size, MACH64_SEND_TIMEOUT, MACH_MSG_TIMEOUT_NONE);
+		    replyMsg.msgHdr.msgh_size, MACH_SEND_TIMEOUT, MACH_MSG_TIMEOUT_NONE);
 	} else {
 		/* Fail on full queue. */
-		kr = mach_msg_send_from_kernel(&replyMsg.msgHdr,
+		kr = mach_msg_send_from_kernel_proper( &replyMsg.msgHdr,
 		    replyMsg.msgHdr.msgh_size);
 	}
 	if ((KERN_SUCCESS != kr) && (MACH_SEND_TIMED_OUT != kr) && !(kIOUCAsyncErrorLoggedFlag & reference[0])) {
 		reference[0] |= kIOUCAsyncErrorLoggedFlag;
-		IOLog("%s: mach_msg_send_from_kernel(0x%x)\n", __PRETTY_FUNCTION__, kr );
+		IOLog("%s: mach_msg_send_from_kernel_proper(0x%x)\n", __PRETTY_FUNCTION__, kr );
 	}
 	return kr;
 }
@@ -3169,6 +3068,7 @@
 	           matching, port, &ref, 1, notification );
 }
 
+
 static kern_return_t
 internal_io_service_add_interest_notification(
 	io_object_t _service,
@@ -3189,21 +3089,6 @@
 	err = kIOReturnNoResources;
 	if ((sym = OSSymbol::withCString( type_of_interest ))) {
 		do {
-#if XNU_PLATFORM_WatchOS
-			if (sym == gIOAppPowerStateInterest &&
-			    !(IOCurrentTaskHasEntitlement("com.apple.private.power.notifications") || IOCurrentTaskHasEntitlement("com.apple.private.power.notifications-temp"))) {
-				OSString * taskName = IOCopyLogNameForPID(proc_selfpid());
-				IOLog("IORegisterForSystemPower called by %s without \"com.apple.private.power.notifications\" entitlement\n",
-				    taskName ? taskName->getCStringNoCopy() : "???");
-				OSSafeReleaseNULL(taskName);
-
-				if (gEnforcePowerEntitlement) {
-					err = kIOReturnNotPermitted;
-					continue;
-				}
-			}
-#endif // XNU_PLATFORM_WatchOS
-
 			userNotify = new IOServiceMessageUserNotification;
 
 			if (userNotify && !userNotify->init( port, kIOServiceMessageNotificationType,
@@ -3308,10 +3193,10 @@
 	CHECK( IOUserClient, connection, client );
 
 	IOStatisticsClientCall();
-	client->ipcEnter(kIPCLockWrite);
+	IORWLockWrite(client->lock);
 	ret = client->getNotificationSemaphore((UInt32) notification_type,
 	    semaphore );
-	client->ipcExit(kIPCLockWrite);
+	IORWLockUnlock(client->lock);
 
 	return ret;
 }
@@ -3380,9 +3265,9 @@
 {
 	CHECKLOCKED( IORegistryIterator, iterator, iter );
 
-	IOLockLock(&oIter->lock);
+	IOLockLock(oIter->lock);
 	iter->enterEntry();
-	IOLockUnlock(&oIter->lock);
+	IOLockUnlock(oIter->lock);
 
 	return kIOReturnSuccess;
 }
@@ -3396,9 +3281,9 @@
 
 	CHECKLOCKED( IORegistryIterator, iterator, iter );
 
-	IOLockLock(&oIter->lock);
+	IOLockLock(oIter->lock);
 	didIt = iter->exitEntry();
-	IOLockUnlock(&oIter->lock);
+	IOLockUnlock(oIter->lock);
 
 	return didIt ? kIOReturnSuccess : kIOReturnNoDevice;
 }
@@ -4182,7 +4067,7 @@
 				    client = OSDynamicCast(IOUserClient, entry);
 
 				if (client && client->defaultLockingSetProperties) {
-					IORWLockWrite(&client->lock);
+					IORWLockWrite(client->lock);
 				}
 
 				if (!client && (kOSBooleanTrue == entry->getProperty(gIORegistryEntryDefaultLockingSetPropertiesKey))) {
@@ -4194,7 +4079,7 @@
 				}
 
 				if (client && client->defaultLockingSetProperties) {
-					IORWLockUnlock(&client->lock);
+					IORWLockUnlock(client->lock);
 				}
 				if (service && props && service->hasUserServer()) {
 					res = service->UserSetProperties(props);
@@ -4347,12 +4232,7 @@
 		return kr;
 	}
 
-#if defined(XNU_TARGET_OS_OSX)
 	*authorization_id = service->getAuthorizationID();
-#else /* defined(XNU_TARGET_OS_OSX) */
-	*authorization_id = 0;
-	kr = kIOReturnUnsupported;
-#endif /* defined(XNU_TARGET_OS_OSX) */
 
 	return kr;
 }
@@ -4365,11 +4245,7 @@
 {
 	CHECK( IOService, _service, service );
 
-#if defined(XNU_TARGET_OS_OSX)
 	return service->setAuthorizationID( authorization_id );
-#else /* defined(XNU_TARGET_OS_OSX) */
-	return kIOReturnUnsupported;
-#endif /* defined(XNU_TARGET_OS_OSX) */
 }
 
 /* Routine io_service_open_ndr */
@@ -4471,8 +4347,9 @@
 			if (client->sharedInstance) {
 				IOLockLock(gIOUserClientOwnersLock);
 			}
-			if (!client->opened) {
-				client->opened = true;
+			if (!client->lock) {
+				client->lock       = IORWLockAlloc();
+				client->filterLock = IOLockAlloc();
 
 				client->messageAppSuspended = (NULL != client->getProperty(kIOUserClientMessageAppSuspendedKey));
 				{
@@ -4611,7 +4488,7 @@
 /* Routine io_service_close */
 kern_return_t
 is_io_service_close(
-	io_connect_t connection )
+	io_object_t connection )
 {
 	OSSet * mappings;
 	if ((mappings = OSDynamicCast(OSSet, connection))) {
@@ -4623,9 +4500,9 @@
 	IOStatisticsClientCall();
 
 	if (client->sharedInstance || OSCompareAndSwap8(0, 1, &client->closed)) {
-		client->ipcEnter(kIPCLockWrite);
+		IORWLockWrite(client->lock);
 		client->clientClose();
-		client->ipcExit(kIPCLockWrite);
+		IORWLockUnlock(client->lock);
 	} else {
 		IOLog("ignored is_io_service_close(0x%qx,%s)\n",
 		    client->getRegistryEntryID(), client->getName());
@@ -4637,22 +4514,18 @@
 /* Routine io_connect_get_service */
 kern_return_t
 is_io_connect_get_service(
-	io_connect_t connection,
+	io_object_t connection,
 	io_object_t *service )
 {
 	IOService * theService;
 
 	CHECK( IOUserClient, connection, client );
-
-	client->ipcEnter(kIPCLockNone);
 
 	theService = client->getService();
 	if (theService) {
 		theService->retain();
 	}
 
-	client->ipcExit(kIPCLockNone);
-
 	*service = theService;
 
 	return theService ? kIOReturnSuccess : kIOReturnUnsupported;
@@ -4661,7 +4534,7 @@
 /* Routine io_connect_set_notification_port */
 kern_return_t
 is_io_connect_set_notification_port(
-	io_connect_t connection,
+	io_object_t connection,
 	uint32_t notification_type,
 	mach_port_t port,
 	uint32_t reference)
@@ -4670,19 +4543,17 @@
 	CHECK( IOUserClient, connection, client );
 
 	IOStatisticsClientCall();
-
-	client->ipcEnter(kIPCLockWrite);
+	IORWLockWrite(client->lock);
 	ret = client->registerNotificationPort( port, notification_type,
 	    (io_user_reference_t) reference );
-	client->ipcExit(kIPCLockWrite);
-
+	IORWLockUnlock(client->lock);
 	return ret;
 }
 
 /* Routine io_connect_set_notification_port */
 kern_return_t
 is_io_connect_set_notification_port_64(
-	io_connect_t connection,
+	io_object_t connection,
 	uint32_t notification_type,
 	mach_port_t port,
 	io_user_reference_t reference)
@@ -4691,107 +4562,13 @@
 	CHECK( IOUserClient, connection, client );
 
 	IOStatisticsClientCall();
-
-	client->ipcEnter(kIPCLockWrite);
+	IORWLockWrite(client->lock);
 	ret = client->registerNotificationPort( port, notification_type,
 	    reference );
-	client->ipcExit(kIPCLockWrite);
-
+	IORWLockUnlock(client->lock);
 	return ret;
 }
 
-
-/* Routine io_connect_map_shared_memory */
-kern_return_t
-is_io_connect_map_shared_memory
-(
-	io_connect_t connection,
-	uint32_t memory_type,
-	task_t into_task,
-	mach_vm_address_t *address,
-	mach_vm_size_t *size,
-	uint32_t map_flags,
-	io_name_t property_name,
-	io_struct_inband_t inband_output,
-	mach_msg_type_number_t *inband_outputCnt
-)
-{
-	IOReturn            err;
-	IOMemoryMap *       map = NULL;
-	IOOptionBits        options = 0;
-	IOMemoryDescriptor * memory = NULL;
-
-	CHECK( IOUserClient, connection, client );
-
-	if (!into_task) {
-		return kIOReturnBadArgument;
-	}
-	if (client->sharedInstance
-	    || (into_task != current_task())) {
-		return kIOReturnUnsupported;
-	}
-
-	IOStatisticsClientCall();
-
-	client->ipcEnter(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
-
-	err = client->clientMemoryForType(memory_type, &options, &memory );
-
-	if (memory && (kIOReturnSuccess == err)) {
-		OSObject * context = memory->copySharingContext(property_name);
-		OSData   * desc;
-		if (!(desc = OSDynamicCast(OSData, context))) {
-			err = kIOReturnNotReady;
-		} else {
-			if (!(kIOMapReadOnly & options)
-			    && !IOCurrentTaskHasEntitlement(kIOMapSharedMemoryWritableEntitlement)) {
-				err = kIOReturnNotPermitted;
-			} else if (desc->getLength() > *inband_outputCnt) {
-				err = kIOReturnOverrun;
-			} else {
-				memcpy(inband_output, desc->getBytesNoCopy(), desc->getLength());
-				*inband_outputCnt = desc->getLength();
-			}
-			OSSafeReleaseNULL(context);
-		}
-		if (kIOReturnSuccess == err) {
-			FAKE_STACK_FRAME(client->getMetaClass());
-
-			options = (options & ~kIOMapUserOptionsMask)
-			    | (map_flags & kIOMapUserOptionsMask)
-			    | kIOMapAnywhere;
-			map = memory->createMappingInTask( into_task, 0, options );
-
-			FAKE_STACK_FRAME_END();
-			if (!map) {
-				err = kIOReturnNotReadable;
-			}
-		}
-		memory->release();
-	}
-
-	if (map) {
-		*address = map->getAddress();
-		if (size) {
-			*size = map->getSize();
-		}
-		// keep it with the user client
-		IOLockLock( gIOObjectPortLock);
-		if (NULL == client->mappings) {
-			client->mappings = OSSet::withCapacity(2);
-		}
-		if (client->mappings) {
-			client->mappings->setObject( map);
-		}
-		IOLockUnlock( gIOObjectPortLock);
-		map->release();
-		err = kIOReturnSuccess;
-	}
-
-	client->ipcExit(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
-
-	return err;
-}
 /* Routine io_connect_map_memory_into_task */
 kern_return_t
 is_io_connect_map_memory_into_task
@@ -4814,9 +4591,13 @@
 	}
 
 	IOStatisticsClientCall();
-
-	client->ipcEnter(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
+	if (client->defaultLocking) {
+		IORWLockWrite(client->lock);
+	}
 	map = client->mapClientMemory64( memory_type, into_task, flags, *address );
+	if (client->defaultLocking) {
+		IORWLockUnlock(client->lock);
+	}
 
 	if (map) {
 		*address = map->getAddress();
@@ -4849,8 +4630,6 @@
 		err = kIOReturnBadArgument;
 	}
 
-	client->ipcExit(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
-
 	return err;
 }
 
@@ -4927,9 +4706,13 @@
 	}
 
 	IOStatisticsClientCall();
-
-	client->ipcEnter(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
+	if (client->defaultLocking) {
+		IORWLockWrite(client->lock);
+	}
 	err = client->clientMemoryForType((UInt32) memory_type, &options, &memory );
+	if (client->defaultLocking) {
+		IORWLockUnlock(client->lock);
+	}
 
 	if (memory && (kIOReturnSuccess == err)) {
 		options = (options & ~kIOMapUserOptionsMask)
@@ -4966,8 +4749,6 @@
 		}
 	}
 
-	client->ipcExit(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
-
 	return err;
 }
 
@@ -4992,7 +4773,7 @@
 /* Routine io_connect_add_client */
 kern_return_t
 is_io_connect_add_client(
-	io_connect_t connection,
+	io_object_t connection,
 	io_object_t connect_to)
 {
 	CHECK( IOUserClient, connection, client );
@@ -5001,11 +4782,13 @@
 	IOReturn ret;
 
 	IOStatisticsClientCall();
-
-	client->ipcEnter(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
+	if (client->defaultLocking) {
+		IORWLockWrite(client->lock);
+	}
 	ret = client->connectClient( to );
-	client->ipcExit(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
-
+	if (client->defaultLocking) {
+		IORWLockUnlock(client->lock);
+	}
 	return ret;
 }
 
@@ -5013,7 +4796,7 @@
 /* Routine io_connect_set_properties */
 kern_return_t
 is_io_connect_set_properties(
-	io_connect_t connection,
+	io_object_t connection,
 	io_buf_ptr_t properties,
 	mach_msg_type_number_t propertiesCnt,
 	kern_return_t * result)
@@ -6405,8 +6188,7 @@
 		unsigned int size;
 
 		size = s->getLength();
-		kr = mach_vm_allocate_kernel(kernel_map, &data, size,
-		    VM_MAP_KERNEL_FLAGS_ANYWHERE(.vm_tag = VM_KERN_MEMORY_IOKIT));
+		kr = mach_vm_allocate_kernel(kernel_map, &data, size, VM_FLAGS_ANYWHERE, VM_KERN_MEMORY_IOKIT);
 		if (kr == kIOReturnSuccess) {
 			bcopy(s->text(), (void *)data, size);
 			kr = vm_map_copyin(kernel_map, data, size, true, &copy);
@@ -6550,29 +6332,13 @@
 	boolean_t *exists )
 {
 	OSCollectionIterator *iter;
-	IORegistryEntry *entry;
-	io_name_t namebuf;
-	const char *entryname;
-	const char *propname;
 
 	if (main_port != main_device_port) {
 		return kIOReturnNotPrivileged;
 	}
 
-	if ((propname = strchr(name, ':'))) {
-		propname++;
-		strlcpy(namebuf, name, propname - name);
-		entryname = namebuf;
-	} else {
-		entryname = name;
-	}
-
-	iter = IODTFindMatchingEntries(IORegistryEntry::getRegistryRoot(), kIODTRecursive, entryname);
-	if (iter && (entry = (IORegistryEntry *) iter->getNextObject())) {
-		*exists = !propname || entry->propertyExists(propname);
-	} else {
-		*exists = FALSE;
-	}
+	iter = IODTFindMatchingEntries(IORegistryEntry::getRegistryRoot(), kIODTRecursive, name);
+	*exists = iter && iter->getNextObject();
 	OSSafeReleaseNULL(iter);
 
 	return kIOReturnSuccess;
@@ -6584,14 +6350,21 @@
 {
 	IOReturn ret;
 
-	ipcEnter(defaultLocking ? (defaultLockingSingleThreadExternalMethod ? kIPCLockWrite : kIPCLockRead) : kIPCLockNone);
+	if (defaultLocking) {
+		if (defaultLockingSingleThreadExternalMethod) {
+			IORWLockWrite(lock);
+		} else {
+			IORWLockRead(lock);
+		}
+	}
 	if (uc2022) {
 		ret = ((IOUserClient2022 *) this)->externalMethod(selector, (IOExternalMethodArgumentsOpaque *) args);
 	} else {
 		ret = externalMethod(selector, args);
 	}
-	ipcExit(defaultLocking ? (defaultLockingSingleThreadExternalMethod ? kIPCLockWrite : kIPCLockRead) : kIPCLockNone);
-
+	if (defaultLocking) {
+		IORWLockUnlock(lock);
+	}
 	return ret;
 }