feat(wifi): implement concrete allocIO80211RecursiveLock override and granular Skywalk substep tracing
- Reverse Engineering Breakthrough:
* Identified that IO80211PeerManager::initWithInterface() called by IO80211SkywalkInterface::createPeerManager()
invokes controller->allocIO80211RecursiveLock() at vtable slot 435 (vptr + 0xd88).
* Implemented a concrete override for allocIO80211RecursiveLock in QualcommWifi that delegates to super
and includes an emergency fallback to IORecursiveLockAlloc() if super returns NULL.
* Replaced in-memory IODTPlane options logging with real persistent NVRAM writes via PEWriteNVRAMProperty()
so the exact last executed checkpoint persists across reboot/bootloop cycles.
- Granular Sub-Step Tracing:
* Introduced 'qcom_substep' boot-arg:
- qcom_substep=1: 10-second observation pause BEFORE fSkywalkInterface->start(this).
- qcom_substep=2: 10-second observation pause AFTER fSkywalkInterface->start(this) succeeds.
* Instrumented all Skywalk/Controller callbacks (getWorkQueue, allocIO80211RecursiveLock, setPowerState,
getLogger, getFaultReporterFromDriver, handleCardSpecific, outputPacket, enable, disable).
* Hardened setPowerState against potential null dereferences in whatDevice->getName().
- Validation:
* Recompiled with ./build_wifi.sh.
* Verified 100% against kmutil libraries and BootKernelExtensions.kc.
This commit is contained in:
1 parent
6a1af27d4f
commit
e21d212096
2 files changed
+68
-14
No files matched your search
@@ -16,9 +16,14 @@ extern "C" {
|
||||
|
||||
#include <pexpert/pexpert.h>
|
||||
#include <IOKit/IODeviceTreeSupport.h>
|
||||
#include <IOKit/IOPlatformExpert.h>
|
||||
#include <IOKit/IOLocks.h>
|
||||
|
||||
static inline void logNvramStage(const char *tag) {
|
||||
IOLog("QualcommWifi: >>> [STAGE] %s <<<\n", tag);
|
||||
if (tag) {
|
||||
PEWriteNVRAMProperty("qcom_stage", tag, (unsigned int)strlen(tag));
|
||||
}
|
||||
IORegistryEntry *options = IORegistryEntry::fromPath("/options", gIODTPlane);
|
||||
if (options) {
|
||||
options->setProperty("qcom_stage", tag);
|
||||
@@ -842,19 +847,45 @@ bool QualcommWifi::start(IOService *provider) {
|
||||
fSkywalkAttached = true;
|
||||
IOLog("QualcommWifi: fSkywalkInterface->attach(this) réussi !\n");
|
||||
if (skywalk_step >= 6) {
|
||||
logNvramStage("skywalk_start");
|
||||
if (fSkywalkInterface->start(this)) {
|
||||
int substep = 0;
|
||||
PE_parse_boot_argn("qcom_substep", &substep, sizeof(substep));
|
||||
|
||||
logNvramStage("s6_0_before_start");
|
||||
IOLog("QualcommWifi: ========================================================\n");
|
||||
IOLog("QualcommWifi: >>> ETAPE 6 : Appel de fSkywalkInterface->start(this) (substep=%d) <<<\n", substep);
|
||||
IOLog("QualcommWifi: ========================================================\n");
|
||||
|
||||
if (substep == 1) {
|
||||
IOLog("QualcommWifi: [SUBSTEP 1] PAUSE de 10s AVANT start(this) pour lecture visuelle...\n");
|
||||
IOSleep(10000);
|
||||
}
|
||||
|
||||
logNvramStage("s6_1_calling_start");
|
||||
bool startRes = fSkywalkInterface->start(this);
|
||||
|
||||
if (startRes) {
|
||||
fSkywalkStarted = true;
|
||||
IOLog("QualcommWifi: fSkywalkInterface->start(this) démarré avec succès !\n");
|
||||
logNvramStage("s6_2_start_ok");
|
||||
IOLog("QualcommWifi: ========================================================\n");
|
||||
IOLog("QualcommWifi: >>> [SUCCES] fSkywalkInterface->start(this) A REUSSI ! <<<\n");
|
||||
IOLog("QualcommWifi: ========================================================\n");
|
||||
|
||||
if (substep == 2) {
|
||||
IOLog("QualcommWifi: [SUBSTEP 2] PAUSE de 10s APRES start(this) reussi pour observation...\n");
|
||||
IOSleep(10000);
|
||||
}
|
||||
|
||||
if (skywalk_step >= 7) {
|
||||
logNvramStage("skywalk_register");
|
||||
logNvramStage("s7_0_before_register");
|
||||
fSkywalkInterface->registerService();
|
||||
logNvramStage("s7_1_register_done");
|
||||
IOLog("QualcommWifi: fSkywalkInterface->registerService() publié !\n");
|
||||
}
|
||||
} else {
|
||||
logNvramStage("skywalk_start_err");
|
||||
logNvramStage("s6_2_start_err");
|
||||
IOLog("QualcommWifi: AVERTISSEMENT - fSkywalkInterface->start(this) a echoue (interface preservee pour diagnostic) !\n");
|
||||
}
|
||||
logNvramStage("s6_3_post_start");
|
||||
}
|
||||
} else {
|
||||
logNvramStage("skywalk_attach_err");
|
||||
@@ -954,9 +985,25 @@ bool QualcommWifi::createWorkQueue(void) {
|
||||
}
|
||||
|
||||
IO80211WorkQueue* QualcommWifi::getWorkQueue(void) const {
|
||||
logNvramStage("cb_getWorkQueue");
|
||||
IOLog("QualcommWifi: >>> CALLBACK getWorkQueue() -> 0x%p <<<\n", fWorkQueue);
|
||||
return fWorkQueue;
|
||||
}
|
||||
|
||||
IORecursiveLock* QualcommWifi::allocIO80211RecursiveLock(void) {
|
||||
logNvramStage("cb_allocLock");
|
||||
IOLog("QualcommWifi: >>> CALLBACK allocIO80211RecursiveLock() <<<\n");
|
||||
IORecursiveLock *lock = super::allocIO80211RecursiveLock();
|
||||
IOLog("QualcommWifi: super::allocIO80211RecursiveLock() = 0x%p\n", lock);
|
||||
if (!lock) {
|
||||
logNvramStage("cb_allocLock_null");
|
||||
IOLog("QualcommWifi: AVERTISSEMENT - allocIO80211RecursiveLock a renvoye NULL, repli sur IORecursiveLockAlloc()...\n");
|
||||
lock = IORecursiveLockAlloc();
|
||||
IOLog("QualcommWifi: IORecursiveLockAlloc() = 0x%p\n", lock);
|
||||
}
|
||||
return lock;
|
||||
}
|
||||
|
||||
bool QualcommWifi::createWorkLoop(void) {
|
||||
logNvramStage("createWorkLoop");
|
||||
if (fWorkLoop) {
|
||||
@@ -978,28 +1025,29 @@ IOWorkLoop* QualcommWifi::getWorkLoop(void) const {
|
||||
}
|
||||
|
||||
IOReturn QualcommWifi::getHardwareAddress(IOEthernetAddress *addrP) {
|
||||
logNvramStage("getHardwareAddress");
|
||||
logNvramStage("cb_getHwAddr");
|
||||
if (!addrP) return kIOReturnBadArgument;
|
||||
bcopy(&fMacAddress, addrP, sizeof(IOEthernetAddress));
|
||||
return kIOReturnSuccess;
|
||||
}
|
||||
|
||||
IOReturn QualcommWifi::enable(IONetworkInterface *netif) {
|
||||
logNvramStage("netif_enable");
|
||||
IOLog("QualcommWifi: Interface reseau activee par macOS.\n");
|
||||
logNvramStage("cb_netif_enable");
|
||||
IOLog("QualcommWifi: >>> CALLBACK netif enable() <<<\n");
|
||||
const IONetworkMedium *medium = getSelectedMedium();
|
||||
setLinkStatus(kIONetworkLinkValid | kIONetworkLinkActive, medium);
|
||||
return kIOReturnSuccess;
|
||||
}
|
||||
|
||||
IOReturn QualcommWifi::disable(IONetworkInterface *netif) {
|
||||
logNvramStage("netif_disable");
|
||||
IOLog("QualcommWifi: Interface reseau desactivee par macOS.\n");
|
||||
logNvramStage("cb_netif_disable");
|
||||
IOLog("QualcommWifi: >>> CALLBACK netif disable() <<<\n");
|
||||
setLinkStatus(kIONetworkLinkValid, nullptr);
|
||||
return kIOReturnSuccess;
|
||||
}
|
||||
|
||||
UInt32 QualcommWifi::outputPacket(mbuf_t m, void *param) {
|
||||
logNvramStage("cb_outputPacket");
|
||||
if (m) {
|
||||
freePacket(m);
|
||||
}
|
||||
@@ -1007,19 +1055,23 @@ UInt32 QualcommWifi::outputPacket(mbuf_t m, void *param) {
|
||||
}
|
||||
|
||||
void QualcommWifi::dataLinkLayerAttachComplete(void) {
|
||||
logNvramStage("dataLinkAttachDone");
|
||||
IOLog("QualcommWifi: dataLinkLayerAttachComplete (Skywalk Tahoe).\n");
|
||||
logNvramStage("cb_dataLinkAttachDone");
|
||||
IOLog("QualcommWifi: >>> CALLBACK dataLinkLayerAttachComplete (Skywalk Tahoe) <<<\n");
|
||||
}
|
||||
|
||||
IOReturn QualcommWifi::handleCardSpecific(IO80211SkywalkInterface *iface, unsigned long req_type, void *req_data, bool isSet) {
|
||||
logNvramStage("cb_cardSpecific");
|
||||
IOLog("QualcommWifi: >>> CALLBACK handleCardSpecific(req=0x%lx, isSet=%d) <<<\n", req_type, isSet);
|
||||
return (IOReturn)handleApple80211Request((unsigned int)req_type, isSet ? 1 : 0, req_data);
|
||||
}
|
||||
|
||||
void* QualcommWifi::getLogger(void) const {
|
||||
logNvramStage("cb_getLogger");
|
||||
return (void*)fLogger;
|
||||
}
|
||||
|
||||
void* QualcommWifi::getFaultReporterFromDriver(void) {
|
||||
logNvramStage("cb_getFaultReporter");
|
||||
return (void*)fFaultReporter;
|
||||
}
|
||||
|
||||
@@ -1295,7 +1347,8 @@ SInt32 QualcommWifi::handleApple80211Request(unsigned int req_type, int req_val,
|
||||
}
|
||||
|
||||
IOReturn QualcommWifi::setPowerState(unsigned long powerStateOrdinal, IOService *whatDevice) {
|
||||
IOLog("QualcommWifi: setPowerState(ordinal=%lu, device=%s)\n",
|
||||
powerStateOrdinal, whatDevice ? whatDevice->getName() : "null");
|
||||
logNvramStage(powerStateOrdinal == 1 ? "cb_pm_on" : "cb_pm_off");
|
||||
IOLog("QualcommWifi: >>> CALLBACK setPowerState(ordinal=%lu, whatDevice=0x%p) <<<\n",
|
||||
powerStateOrdinal, whatDevice);
|
||||
return IOPMAckImplied;
|
||||
}
|
||||
@@ -265,6 +265,7 @@ public:
|
||||
virtual IOReturn setGET_DEBUG_INFO(IO80211SkywalkInterface *iface, apple80211_debug_command *dbg) override { return kIOReturnSuccess; }
|
||||
virtual void* getLogger(void) const override;
|
||||
virtual void* getFaultReporterFromDriver(void) override;
|
||||
virtual IORecursiveLock* allocIO80211RecursiveLock(void) override;
|
||||
virtual UInt32 getActionFramePoolCapacity(void) override;
|
||||
|
||||
// Dispatcher de requêtes Apple80211 / airportd
|
||||
|
||||
Reference in new issue
Block a user