LinuxovΘ noviny | Prosinec 1997 | |||||
| ||||||
V p°edchozφm Φφsle Linuxov²ch novin byla uve°ejn∞na zprßva o tom, ╛e byla objevena novß chyba v procesorech Intel Pentium. Tato chyba umo╛≥uje b∞╛nΘmu u╛ivateli zablokovat procesor tak, ╛e je nutno provΘst studen² start poΦφtaΦe. TΘto chyb∞ se zaΦalo °φkat "F00F bug" podle hodnoty prvnφch dvou bajt∙ chybnΘ instrukce. Dnes je situace podstatn∞ lep╣φ. Existuje zp∙sob, jak softwarov∞ danou chybu odstφnit. Stojφ za pov╣imnutφ, ╛e k dne╣nφmu dni (21. listopadu 1997) byla podle strßnky spoleΦnosti Intel http://support.intel.com/support/processors/pentium/ppiie/software.htm k dispozici softwarovß zßplata pouze pro Linux a BSDI. (Hovo°φm zde o systΘmech s jejich╛ v²vojß°i Intel spolupracoval. Z ostatnφch systΘm∙ mß softwarovou zßplatu na tuto chybu nap°φklad FreeBSD. Na uvedenΘ strßnce jsou zmi≥ovßny tyto systΘmy nebo tito v²robci: BSDI, IBM, Linux, Microsoft, NCR, Novell, SCO, Sequent, SunSoft a Unisys.) Ostatnφ systΘmy vΦetn∞ nap°φklad Solarisu a SCO UNIXu majφ p°φslu╣nou zßplatu pouze "ve stßdiu v²voje" nebo "test∙". Je zajφmavΘ, co se zde pφ╣e o operaΦnφch systΘmech Microsoftu:
Tedy Microsoft se z°ejm∞ vzdal my╣lenky na to, ╛e by jeho operaΦnφ systΘmy mohly b²t n∞kdy nasazeny ve vφceu╛ivatelskΘm prost°edφ. Nynφ se budu v∞novat mechanismu, jak²m chybnß instrukce pravd∞podobn∞ pracuje a navrhovan²m softwarov²m °e╣enφm. Samoz°ejm∞ nenφ v silßch jednoho Φlov∞ka pochopit mili≤ny tranzistor∙ v Pentiu, ale z chovßnφ CPU p°i tΘto chyb∞ lze leccos odpozorovat. PopisovanΘ mechanismy se tedy sna╛φ odhadnout, co se v CPU p°ibli╛n∞ d∞je p°i v²skytu tΘto instrukce. Nekladu si ╛ßdnΘ nßroky na sprßvnost nφ╛e uveden²ch mechanism∙, nicmΘn∞ s jejich vyu╛itφm se poda°ilo chybu izolovat a odstφnit. Inkriminovanou instrukci s operaΦnφm k≤dem f0 0f c7 by bylo mo╛nΘ zapsat jako lock cmpxchg8b s adresovacφm m≤dem, kter² nenφ pro tuto instrukci platn². Tato instrukce je "tΘm∞° legßlnφ". Co to znamenß? Na to, ╛e jde o neplatnou instrukci, a ╛e by se tedy m∞la vyvolat p°φslu╣nß v²jimka, procesor p°ijde a╛ pom∞rn∞ pozd∞, kdy╛ u╛ je provßd∞nφ instrukce uvnit° CPU v pokroΦilΘm stavu. Tento stav se vyznaΦuje tφm, ╛e procesor u╛ zamknul datovou sb∞rnici, jak mu p°ikazuje instrukΦnφ prefix lock. A zde prßv∞ nastßvß problΘm. Procesor zjistφ, ╛e instrukce je neplatnß, a chce vyvolat p°φslu╣nΘ p°eru╣enφ. Toto v prvnφ °ad∞ znamenß podφvat se do tabulky p°eru╣enφ (IDT, Interrupt Description Table), na kterΘ adrese zaΦφnß obsluha p°eru╣enφ "neplatnß instrukce". Pokus o p°φstup k IDT ale sel╛e, proto╛e CPU mß zamΦenou sb∞rnici! N∞kde v tomto mφst∞ se procesor zastavφ. Jak takovouto chybu o╣et°it? K p°φstupu na sb∞rnici nedochßzφ, pokud se p°φslu╣nß Φßst IDT prßv∞ nachßzφ v primßrnφ cache procesoru. Prvnφ a nejstar╣φ softwarovΘ zßplaty na tuto chybu fungovaly tak, ╛e zajistily, aby se v cache objevil ovladaΦ pro obsluhu v²jimky "neplatnß instrukce" (nap°φklad vykonßnφm n∞jakΘ skuteΦn∞ neplatnΘ instrukce), a pak zamkly obsah cache. Toto fungovalo, ale v²kon procesoru bez primßrnφ cache klesl a╛ n∞kam k pr∙m∞rn²m procesor∙m 486. Pozd∞j╣φ ·pravy vyu╛φvaly toho, ╛e jinΘ v²jimky majφ obsluhu zamΦenΘ sb∞rnice vy°e╣eny lΘpe ne╛ v²jimka "neplatnß instrukce". Pokud se nap°φklad strßnka IDT, ve kterΘ byl vektor p°eru╣enφ "neplatnß instrukce", nenachßzφ v operaΦnφ pam∞ti, Pentium toto rozpoznß a vyvolß v²jimku Φφslo 8 - "dvojit² v²padek" (double fault). Jak tohoto ale dosßhnout? StaΦφ zarovnat zaΦßtek IDT tak, aby prvnφch sedm polo╛ek IDT (pro v²jimky 0 a╛ 6, p°iΦem╛ "neplatnß instrukce" mß Φφslo 6) bylo v jednΘ strßnce a ostatnφ byly v nßsledujφcφ strßnce pam∞ti. Tedy aby tabulka IDT zaΦφnala t∞sn∞ p°ed koncem strßnky. Dßle je nutno upravit obsluhu v²jimky Φφslo 8 tak, aby byla schopna analyzovat situaci a p°φpadn∞ zavolat v²jimky Φφslo 0 a╛ 6. A poslednφ v∞c je oznaΦit prvnφ strßnku IDT jako neplatnou. V p°φpad∞ pokusu o vykonßnφ neplatnΘ instrukce se tedy zavolß v²jimka Φφslo 8 "dvojit² v²padek", kterß pak zp∞tn∞ zjistφ o co jde a zavolß p°φslu╣nou v²jimku z intervalu 0 a╛ 6. Toto m∙╛e ud∞lat dv∞ma zp∙soby. Bu∩to zjistφ p°φslu╣nou informaci z chybovΘho slova a pak zavolß p°φslu╣nou obsluhu jako funkci (co╛ byl zp∙sob, jak²m byla situace °e╣ena v Linuxu) nebo se prvnφ strßnka IDT namapuje do pam∞ti a danß instrukce se restartuje (samoz°ejm∞ a╛ po kontrole, jestli nßhodou ne╣lo o instrukci f0 0f c7 cx. Toto byl zp∙sob, jak²m doporuΦoval chybu izolovat Intel. Prvnφ zp∙sob m∞l problΘmy s obsluhou specißlnφch p°φpad∙, jako je nap°φklad ladφcφ bod na mφst∞ neplatnΘ instrukce a podobn∞. Ladφcφ a krokovacφ funkce zde nefungovaly ·pln∞ korektn∞. Naproti tomu druh² zp∙sob (navrhovan² Intelem) m∞l problΘmy se samomodifikujφcφm se k≤dem (nap°φklad na SMP stroji - dojde k p°eru╣enφ, namapuje se IDT, ale n∞kdo jin² zm∞nφ zatφm instrukci, na kterΘ do╣lo k p°eru╣enφ na f0 0f c7 cx. Restartuje se instrukce, ale IDT je namapovanß a procesor se zablokuje). Linus Torvalds napsal na linux-kernel
Obslou╛enφ chyby F00F jednφm ze dvou v²╣e popsan²ch zp∙sob∙ stßlo p°ibli╛n∞ 55 takt∙ p°i vyvolßnφ kterΘkoli z v²jimek 0 a╛ 6. Zßplaty provedenΘ tφmto zp∙sobem se objevily v Linuxu 2.0.32 (vlastn∞ ji╛ v pre-2.0.32-4) a 2.1.63. Jak je vid∞t, odstran∞nφ takovΘto chyby popisovan²m zp∙sobem nebylo nijak trivißlnφ. Na╣t∞stφ Linus ve spoluprßci s Intelem vymyslel je╣t∞ lep╣φ mechanismus odstφn∞nφ chyby. V CPU se toti╛ v pr∙b∞hu vyvolßnφ v²jimky pro neplatnou instrukci nejen neresetuje zamΦenφ sb∞rnice, ale takΘ nßsledujφcφ p°φstup do pam∞ti se provßdφ jako read-write p°esn∞ tak, jak by jej provßd∞la skuteΦnß instrukce lock cmpxchg8b. Tak╛e pokud je IDT namapovßna pouze pro Φtenφ, dojde k zavolßnφ v²jimky "poru╣enφ ochrany pam∞ti". P°φslu╣nß obslu╛nß rutina pak zjistφ, ╛e byl proveden pokus o zßpis do IDT na polo╛ku Φφslo 6 a detekuje tak jednoznaΦn∞ pokus o zneu╛itφ chyby F00F.
Tφmto zp∙sobem se kompletn∞ odstφnφ chyba F00F a navφc tato zßplata nemß ╛ßdn² vliv na v²kon systΘmu (na rozdφl od p°edchozφch °e╣enφ). V souΦasnΘ dob∞ je k dispozici zßplata na jßdro 2.0.32 i 2.1.x, vyu╛φvajφcφ tohoto mechanismu.
OperaΦnφ systΘm Linux byl jednφm z prvnφch, kterΘ m∞ly k dispozici
zßplatu na hardwarovou chybu Pentia. Tato chyba pro souΦasn² Linux
ji╛ nep°edstavuje ╛ßdnΘ nebezpeΦφ.
|