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:
Erwan committed 2026-10-18 21:32:32 +02:00
1 parent 6a1af27d4f
commit e21d212096
2 files changed
+68 -14

No files matched your search

+67 -14
View File
@@ -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;
}
+1
View File
@@ -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