]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IOInterruptEventSource.cpp
xnu-7195.101.1.tar.gz
[apple/xnu.git] / iokit / Kernel / IOInterruptEventSource.cpp
index 19d5d597d754de689c67150a5506f32eea344ab8..a720e9a301b9c547d0b8b0330836125e72c154b7 100644 (file)
@@ -26,6 +26,9 @@
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
+#define IOKIT_ENABLE_SHARED_PTR
+
+#include <ptrauth.h>
 #include <IOKit/IOInterruptEventSource.h>
 #include <IOKit/IOKitDebug.h>
 #include <IOKit/IOLib.h>
 #include <IOKit/IOInterruptEventSource.h>
 #include <IOKit/IOKitDebug.h>
 #include <IOKit/IOLib.h>
@@ -34,6 +37,7 @@
 #include <IOKit/IOTimeStamp.h>
 #include <IOKit/IOWorkLoop.h>
 #include <IOKit/IOInterruptAccountingPrivate.h>
 #include <IOKit/IOTimeStamp.h>
 #include <IOKit/IOWorkLoop.h>
 #include <IOKit/IOInterruptAccountingPrivate.h>
+#include <libkern/Block_private.h>
 
 #if IOKITSTATS
 
 
 #if IOKITSTATS
 
@@ -208,29 +212,28 @@ IOInterruptEventSource::unregisterInterruptHandler(IOService *inProvider,
 }
 
 
 }
 
 
-IOInterruptEventSource *
+OSSharedPtr<IOInterruptEventSource>
 IOInterruptEventSource::interruptEventSource(OSObject *inOwner,
     Action inAction,
     IOService *inProvider,
     int inIntIndex)
 {
 IOInterruptEventSource::interruptEventSource(OSObject *inOwner,
     Action inAction,
     IOService *inProvider,
     int inIntIndex)
 {
-       IOInterruptEventSource *me = new IOInterruptEventSource;
+       OSSharedPtr<IOInterruptEventSource> me = OSMakeShared<IOInterruptEventSource>();
 
        if (me && !me->init(inOwner, inAction, inProvider, inIntIndex)) {
 
        if (me && !me->init(inOwner, inAction, inProvider, inIntIndex)) {
-               me->release();
-               return 0;
+               return nullptr;
        }
 
        return me;
 }
 
        }
 
        return me;
 }
 
-IOInterruptEventSource *
+OSSharedPtr<IOInterruptEventSource>
 IOInterruptEventSource::interruptEventSource(OSObject *inOwner,
     IOService *inProvider,
     int inIntIndex,
     ActionBlock inAction)
 {
 IOInterruptEventSource::interruptEventSource(OSObject *inOwner,
     IOService *inProvider,
     int inIntIndex,
     ActionBlock inAction)
 {
-       IOInterruptEventSource * ies;
+       OSSharedPtr<IOInterruptEventSource> ies;
        ies = IOInterruptEventSource::interruptEventSource(inOwner, (Action) NULL, inProvider, inIntIndex);
        if (ies) {
                ies->setActionBlock((IOEventSource::ActionBlock) inAction);
        ies = IOInterruptEventSource::interruptEventSource(inOwner, (Action) NULL, inProvider, inIntIndex);
        if (ies) {
                ies->setActionBlock((IOEventSource::ActionBlock) inAction);
@@ -331,16 +334,24 @@ IOInterruptEventSource::checkForWork()
        uint64_t endCPUTime = 0;
        unsigned int cacheProdCount = producerCount;
        int numInts = cacheProdCount - consumerCount;
        uint64_t endCPUTime = 0;
        unsigned int cacheProdCount = producerCount;
        int numInts = cacheProdCount - consumerCount;
-       IOInterruptEventAction intAction = (IOInterruptEventAction) action;
+       IOEventSource::Action intAction = action;
        ActionBlock intActionBlock = (ActionBlock) actionBlock;
        ActionBlock intActionBlock = (ActionBlock) actionBlock;
+       void *address;
        bool trace = (gIOKitTrace & kIOTraceIntEventSource) ? true : false;
 
        bool trace = (gIOKitTrace & kIOTraceIntEventSource) ? true : false;
 
+       if (kActionBlock & flags) {
+               address = ptrauth_nop_cast(void *, _Block_get_invoke_fn((struct Block_layout *)intActionBlock));
+       } else {
+               address = ptrauth_nop_cast(void *, intAction);
+       }
+
        IOStatisticsCheckForWork();
 
        if (numInts > 0) {
                if (trace) {
                        IOTimeStampStartConstant(IODBG_INTES(IOINTES_ACTION),
        IOStatisticsCheckForWork();
 
        if (numInts > 0) {
                if (trace) {
                        IOTimeStampStartConstant(IODBG_INTES(IOINTES_ACTION),
-                           VM_KERNEL_ADDRHIDE(intAction), VM_KERNEL_ADDRHIDE(owner),
+                           VM_KERNEL_ADDRHIDE(address),
+                           VM_KERNEL_ADDRHIDE(owner),
                            VM_KERNEL_ADDRHIDE(this), VM_KERNEL_ADDRHIDE(workLoop));
                }
 
                            VM_KERNEL_ADDRHIDE(this), VM_KERNEL_ADDRHIDE(workLoop));
                }
 
@@ -358,7 +369,7 @@ IOInterruptEventSource::checkForWork()
                if (kActionBlock & flags) {
                        (intActionBlock)(this, numInts);
                } else {
                if (kActionBlock & flags) {
                        (intActionBlock)(this, numInts);
                } else {
-                       (*intAction)(owner, this, numInts);
+                       ((IOInterruptEventAction)intAction)(owner, this, numInts);
                }
 
                if (reserved->statistics) {
                }
 
                if (reserved->statistics) {
@@ -379,7 +390,8 @@ IOInterruptEventSource::checkForWork()
 
                if (trace) {
                        IOTimeStampEndConstant(IODBG_INTES(IOINTES_ACTION),
 
                if (trace) {
                        IOTimeStampEndConstant(IODBG_INTES(IOINTES_ACTION),
-                           VM_KERNEL_ADDRHIDE(intAction), VM_KERNEL_ADDRHIDE(owner),
+                           VM_KERNEL_ADDRHIDE(address),
+                           VM_KERNEL_ADDRHIDE(owner),
                            VM_KERNEL_ADDRHIDE(this), VM_KERNEL_ADDRHIDE(workLoop));
                }
 
                            VM_KERNEL_ADDRHIDE(this), VM_KERNEL_ADDRHIDE(workLoop));
                }
 
@@ -390,7 +402,8 @@ IOInterruptEventSource::checkForWork()
        } else if (numInts < 0) {
                if (trace) {
                        IOTimeStampStartConstant(IODBG_INTES(IOINTES_ACTION),
        } else if (numInts < 0) {
                if (trace) {
                        IOTimeStampStartConstant(IODBG_INTES(IOINTES_ACTION),
-                           VM_KERNEL_ADDRHIDE(intAction), VM_KERNEL_ADDRHIDE(owner),
+                           VM_KERNEL_ADDRHIDE(address),
+                           VM_KERNEL_ADDRHIDE(owner),
                            VM_KERNEL_ADDRHIDE(this), VM_KERNEL_ADDRHIDE(workLoop));
                }
 
                            VM_KERNEL_ADDRHIDE(this), VM_KERNEL_ADDRHIDE(workLoop));
                }
 
@@ -408,7 +421,7 @@ IOInterruptEventSource::checkForWork()
                if (kActionBlock & flags) {
                        (intActionBlock)(this, numInts);
                } else {
                if (kActionBlock & flags) {
                        (intActionBlock)(this, numInts);
                } else {
-                       (*intAction)(owner, this, numInts);
+                       ((IOInterruptEventAction)intAction)(owner, this, numInts);
                }
 
                if (reserved->statistics) {
                }
 
                if (reserved->statistics) {
@@ -429,7 +442,8 @@ IOInterruptEventSource::checkForWork()
 
                if (trace) {
                        IOTimeStampEndConstant(IODBG_INTES(IOINTES_ACTION),
 
                if (trace) {
                        IOTimeStampEndConstant(IODBG_INTES(IOINTES_ACTION),
-                           VM_KERNEL_ADDRHIDE(intAction), VM_KERNEL_ADDRHIDE(owner),
+                           VM_KERNEL_ADDRHIDE(address),
+                           VM_KERNEL_ADDRHIDE(owner),
                            VM_KERNEL_ADDRHIDE(this), VM_KERNEL_ADDRHIDE(workLoop));
                }
 
                            VM_KERNEL_ADDRHIDE(this), VM_KERNEL_ADDRHIDE(workLoop));
                }
 
@@ -456,6 +470,9 @@ IOInterruptEventSource::normalInterruptOccurred
        }
 
        if (reserved->statistics) {
        }
 
        if (reserved->statistics) {
+               if (reserved->statistics->enablePrimaryTimestamp) {
+                       reserved->statistics->primaryTimestamp = mach_absolute_time();
+               }
                if (IA_GET_STATISTIC_ENABLED(kInterruptAccountingFirstLevelCountIndex)) {
                        IA_ADD_VALUE(&reserved->statistics->interruptStatistics[kInterruptAccountingFirstLevelCountIndex], 1);
                }
                if (IA_GET_STATISTIC_ENABLED(kInterruptAccountingFirstLevelCountIndex)) {
                        IA_ADD_VALUE(&reserved->statistics->interruptStatistics[kInterruptAccountingFirstLevelCountIndex], 1);
                }
@@ -484,6 +501,9 @@ IOInterruptEventSource::disableInterruptOccurred
        }
 
        if (reserved->statistics) {
        }
 
        if (reserved->statistics) {
+               if (reserved->statistics->enablePrimaryTimestamp) {
+                       reserved->statistics->primaryTimestamp = mach_absolute_time();
+               }
                if (IA_GET_STATISTIC_ENABLED(kInterruptAccountingFirstLevelCountIndex)) {
                        IA_ADD_VALUE(&reserved->statistics->interruptStatistics[kInterruptAccountingFirstLevelCountIndex], 1);
                }
                if (IA_GET_STATISTIC_ENABLED(kInterruptAccountingFirstLevelCountIndex)) {
                        IA_ADD_VALUE(&reserved->statistics->interruptStatistics[kInterruptAccountingFirstLevelCountIndex], 1);
                }
@@ -498,12 +518,12 @@ IOInterruptEventSource::disableInterruptOccurred
 
 void
 IOInterruptEventSource::interruptOccurred
 
 void
 IOInterruptEventSource::interruptOccurred
-(void *refcon, IOService *prov, int source)
+(void *_refcon, IOService *prov, int source)
 {
        if (autoDisable && prov) {
 {
        if (autoDisable && prov) {
-               disableInterruptOccurred(refcon, prov, source);
+               disableInterruptOccurred(_refcon, prov, source);
        } else {
        } else {
-               normalInterruptOccurred(refcon, prov, source);
+               normalInterruptOccurred(_refcon, prov, source);
        }
 }
 
        }
 }
 
@@ -513,3 +533,20 @@ IOInterruptEventSource::warmCPU
 {
        return ml_interrupt_prewarm(abstime);
 }
 {
        return ml_interrupt_prewarm(abstime);
 }
+
+void
+IOInterruptEventSource::enablePrimaryInterruptTimestamp(bool enable)
+{
+       if (reserved->statistics) {
+               reserved->statistics->enablePrimaryTimestamp = enable;
+       }
+}
+
+uint64_t
+IOInterruptEventSource::getPrimaryInterruptTimestamp()
+{
+       if (reserved->statistics && reserved->statistics->enablePrimaryTimestamp) {
+               return reserved->statistics->primaryTimestamp;
+       }
+       return -1ULL;
+}