In der ersten Folge des Kernel Panic Podcasts geht es um ein Problem mit dem sich mein Kollege Ahmad Fatoum beschäftigt hat. Wie so oft beginnt die Geschichte mit einer Aufgabe, die eigentlich™ in fünf Minuten erledigt sein sollte, driftet aber rasant ab in eine Fehlersuche in den Untiefen der Systemprogrammierung. Es geht um Caches, Adressbereiche, Spekulative Ausführung von Code, um Funktionierbits und auch um Nicht-Funktionier-Bits.
In der ersten Folge des Kernel Panic Podcasts geht es um ein Problem mit dem sich mein Kollege Ahmad Fatoum beschäftigt hat. Wie so oft beginnt die Geschichte mit einer Aufgabe, die eigentlich™ in fünf Minuten erledigt sein sollte, driftet aber rasant ab in eine Fehlersuche in den Untiefen der Systemprogrammierung. Es geht um Caches, Adressbereiche, Spekulative Ausführung von Code, um Funktionierbits und auch um Nicht-Funktionier-Bits.
In wahrscheinlich jedem Berufsfeld gibt es Schauergeschichten, die man sich abends am Lagerfeuer mit einer Taschenlampe am Kinn erzählen kann. So auch in der Welt der Software. In diesem Podcast geben wir in unregelmäßigen Abständen Entwicklerinnen und Entwicklern die Möglichkeit ihre Schauergeschichten zu erzählen. Es geht um monatelange Fehlersuchen, deren Ergebnis nur eine Hand voll Zeilen falscher Code sind, um subtil fehlerhafte Hardware, die zu sporadisch auftretenden Geistern im System führt, um bröckelnde Software, deren Quellcode schon vor Jahren verloren gegangen ist, und manchmal auch um ganz was anderes.
Wer nicht die ganze Folge hören möchte kann sich an den folgenden fünf Eskalationsstufen mit ungefähren Zeitangaben orientieren:
Versucht man die Beleuchtung um Bootloader einzuschalten crashed dieser, und zwar in einem ganz anderen Bereich des Codes.
Mehr zum Thema Barebox:
Mehr dazu, was schon passiert bevor überhaupt der Bootloader startet:
Erste Vermutungen:
Neuer Lösungsansatz: Fehlersuche mit printf.
Neues Problem: mit printf verschwinden die Fehler.
Warum können Probleme durch Einfügen von printfs verschwinden?
Timing sollte eigentlich keine große Rolle spielen, da im Bootloader noch alles ohne Nebenläufigkeit eins nach dem anderen ausgeführt wird.
13:30Vermutung: DMA
Durch falsch eingestelltes DMA (Direct Memory Access) könnten auch im Bootloader Dinge im Hintergrund passieren. Im Bootloader wird DMA genutzt, um Daten aus dem NAND in den Hauptspeicher zu lesen.
15:30Vermutung: Schlecht angebundener RAM
Beim neuen Hardwaredesign könnte sich z.B. das Layout der RAM-Leitungen verschlechtert haben.
17:00Brainstorming mit den Kollegen. Sind es vielleicht die Caches?
Das DMA im verwendeten Prozessor ist nicht Cache coherent. Das heißt man muss zu den richtigen Zeiten den Inhalt der Caches wegwerfen, sonst erhält man falsche Daten.
18:00Ist es vielleicht Spekulation?
Um nicht immer darauf warten zu Müssen, dass die richtigen Daten vom Cache in den RAM geladen wurden führt der Prozessor zukünftige Operationen schon einmal "spekulativ" aus und lädt dabei Daten in die Caches. Falls falsch spekuliert wird, werden diese Daten eigentlich einfach verworfen.
Oder vielleicht nicht?
20:00Warum können auch lesende spekulative Speicherzugriffe ein Problem sein?
Nicht alles was im Adressraum des Prozessors liegt ist auch Speicher, sondern es gibt dort auch eine Vielzahl an Peripherieeinheiten.
21:30Lösungsansatz: Nicht-Speicher auch spekulative nicht ausführen.
Um zu verhindern, dass ein Adressbereich (spekulativ) ausgeführt wird kann er als nicht ausführbar markiert werden. Bei Programmen, die unter einem Betriebssystem laufen macht man das z.B. für alle Daten, die nicht Teil des Programmcodes sind, z.B. aus dem Internet geladene Dinge. Im Bootloader ist man da etwas laxer, auch weil Sachen in den Speicher zu laden und auszuführen zur Kernfunktionalität gehört.
Die entsprechende Markierung der Adressbereiche lieferte auch keine Abhilfe.
Letzter Akt der Verzweiflung: lesen des Arm Architecture Reference Manual (Seite 9198) liefert den entscheidenden Hinweis.
When using the Short-descriptor translation table format, the XN attribute is not checked for domains marked as Manager. Therefore, the system must not include read-sensitive memory in domains marked as Manager, because the XN field does not prevent speculative fetches from a Manager domain.
Im Modus "Manager" ignoriert der Prozessor die gesetzten Restriktionen für Speicherbereiche. Der Bootloader läuft im Manager-Modus.
49:00Die Codeänderung damit der Bootloader in der Client Domain und nicht in der Manager Domain läuft löst das Problem.
Außerdem: ein kleiner Ausblick darauf welche Software es sonst falsch /richtig gemacht hat.
53:00 Abschließende Worte