fix(wifi): rétablir l'allocation dédiée IOWorkLoop et sécuriser la journalisation NVRAM

- Breakthroughs & Rétro-ingénierie :
  * Analyse de la cause racine de la bootloop observée même avec qcom_step=5 : l'alias createWorkLoop() vers createWorkQueue() retournait un IO80211WorkQueue* dans getWorkLoop(), provoquant un kernel panic immédiat dans IONetworkController::start(provider) par déréférencement de vtable invalide.
  * Confirmation matérielle NVRAM : la variable UEFI 'qcom_stage' valait exactement 'createWorkQueue', prouvant que l'échec survenait à la première seconde de boot avant même d'arriver au Stade 1.
  * Confirmation de la non-volatilité : le passage sous Linux n'efface absolument pas la NVRAM SPI Flash de la carte mère.
  * Suppression de kprintf() qui pouvait engendrer des traps/spinlocks en early boot.

- Modifications apportées :
  * QualcommWifi/QualcommWifi.cpp : réintégration de l'allocation dédiée fWorkLoop = IOWorkLoop::workLoop() et du getter getWorkLoop(), suppression de kprintf dans logNvramStage().

- Validation :
  * Compilation sans erreur avec ./build_wifi.sh.
  * Validation kmutil libraries réussie à 100% contre BootKernelExtensions.kc.
This commit is contained in:
Erwan committed 2026-10-18 23:56:32 +02:00
1 parent e0414a948e
commit 92ce7e7839
1 file changed
+14 -6
+14 -6
View File
@@ -19,11 +19,8 @@ extern "C" {
#include <IOKit/IOPlatformExpert.h> #include <IOKit/IOPlatformExpert.h>
#include <IOKit/IOLocks.h> #include <IOKit/IOLocks.h>
extern "C" void kprintf(const char *format, ...);
static inline void logNvramStage(const char *tag) { static inline void logNvramStage(const char *tag) {
IOLog("QualcommWifi: >>> [STAGE] %s <<<\n", tag); IOLog("QualcommWifi: >>> [STAGE] %s <<<\n", tag);
kprintf("QualcommWifi: >>> [STAGE] %s <<<\n", tag);
if (tag) { if (tag) {
PEWriteNVRAMProperty("qcom_stage", tag, (unsigned int)strlen(tag)); PEWriteNVRAMProperty("qcom_stage", tag, (unsigned int)strlen(tag));
} }
@@ -1013,12 +1010,23 @@ IORecursiveLock* QualcommWifi::allocIO80211RecursiveLock(void) {
} }
bool QualcommWifi::createWorkLoop(void) { bool QualcommWifi::createWorkLoop(void) {
logNvramStage("createWorkLoop_alias"); logNvramStage("createWorkLoop");
return createWorkQueue(); if (fWorkLoop) {
return true;
}
fWorkLoop = IOWorkLoop::workLoop();
if (!fWorkLoop) {
logNvramStage("workLoop_alloc_failed");
IOLog("QualcommWifi: Erreur - Impossible d'allouer IOWorkLoop !\n");
return false;
}
logNvramStage("workLoop_ok");
IOLog("QualcommWifi: IOWorkLoop allouee avec succes (0x%p) !\n", fWorkLoop);
return true;
} }
IOWorkLoop* QualcommWifi::getWorkLoop(void) const { IOWorkLoop* QualcommWifi::getWorkLoop(void) const {
return (IOWorkLoop*)fWorkQueue; return fWorkLoop ? fWorkLoop : (getProvider() ? getProvider()->getWorkLoop() : nullptr);
} }
IOReturn QualcommWifi::getHardwareAddress(IOEthernetAddress *addrP) { IOReturn QualcommWifi::getHardwareAddress(IOEthernetAddress *addrP) {