Jak se tohoto problému zbavit.
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
I just found the last bug.
Pokud se teď těšíte, jak budete pomocí malého prográmku z
předchozího článku otravovat sysopy, musím vás zklamat. Nové verze
Linuxu už obsahují kód, který tuto chybu odstraní.
Nejdříve je nutné se zamyslet, co se asi stalo. Není to příliš
jasné. Jedna z teorií je asi následující: instrukce cmpxchg změnila
během vývoje svůj opcode. Opcode používaný ve starých 486 kolidoval
z nejakým starým software a tak se opcod změnil. Navíc instrukce
cmpxchg bere jako vstup pouze adresu a z té toho čte neobvykle
mnoho. Proto pentium narazí na podivnou intrukci - cmpxchg8b
použitou s registrem, pokusí se tedy vyvolat Invalid instruction,
ale protože je tam lock (který by sám o sobě nevadil) a navíc ale se
stalo něco špatného v CPU (což o jecho architektuře nevěstí nic
dobrého), nepovede se a pentium zamrzne.
Tato buga se vstahuje na všechny procerory Pentium a Pentium
MMX. Pentium II a PeniumPro už ji nemají. Intel, který do minulého
týdne o této chybě nevěděl (alespoň to říká), nebude procesory
vyměňovat. Odvolává se na větu ve svých specifikacích, že jejich
procesory nemusí těmto specifikacím odpovídat (tato věta tam byla
přidána kvůli slavné FDIV buze).
A jaké je tedy řešení? Celkem jednoduché. Prostě posunete IDT
tak, aby bylo na rozhraní dvou stránek asi takto:
+--------------------+
| | ... | |
| | ... | |
| | Page fault | |
| | ... | |
+----+--------------------+----+
| |Invalid instruction | |
| | ... | |
| | ... | |
+--------------------+
Tu spodní stránku potom odmapujete. A věc pak funguje asi takto:
Pentium narazí na naši instrukci neintrukci a spustí sebedestrukční
sekvenci. Dostane se na volání Invalid instruction, ale IDT je pryč,
vyvolá se tedy Page Fault (to kupodivu funguje), handler tam potom
zjistí, že procesor chtěl šahat na IDT a vyvolá handler sám. To sice
přináší zpomalení u přerušení po Invalid instruction (musí se
tahat přes Page fault) ale protože tam jsou hlavně věci jako Bus
error apod, ani to moc nevadí, že program spadne o několik
mikrosekund později.... a tak to celkem funguje.
Jednoduše řečeno - pokud vám někdo podrazí nohu, nastavíte
druhou
Nové verze Linuxu tento workaround už obsahují.
výheň