Branch target bufferissahan on myös ongelmana että nykyään se toimii myös instruction cachena, eli joissain tapauksissa hyppykäskyn suorittamat käskytkin löytyvät BTB:stä.
Tuota kutsutaan nimellä "branch folding".
Ja se oli lähinnä 1980-luvun lopun ja 1990-luvun RISC-prossujen temppu eikä juuri käytetä enää superskalaarisissa prosessoreissa:
Yksinkertaisissa In-order-prosessoreissa fetchin viivästyminen kellojaksolla tarkoitti sitä, että koko prosessorin liukuhihna hukkasi aina kellojakson. Tämän takia branch foldingia tarvittiin 1980-1990-luvuilla.
Nykyaikaisissa Out-Of-Order-prosesoreissa taas prosesorin etupää menee kaukana suorituksen edellä, ja välissä olevissa puskureissa riittää tyypillisesti hyvin käskyjä suoritettavaksi, se että fetch ei välillä tee mitään kellojakson ajan ei yleensä vielä yhtään hidasta suoritusvaihetta.
Ja jotta säästettäisiin edes kokonainen kellojakso nykyaikaisilla 4 käskyä fetchaavilla prosessoreilla, siellä BTBssä pitäisi sitten olla 4 käskyä, ei vain 1 käsky.
Ja Nykyään tähän on modernimpia ja parempiakin ratkaiuja:
Joissakin nykyaikaisissa prosessoreissa (ainakin Zen) tässä on menty vielä pidemmälle, ja haarautumisenennutimen ja fetchinkin väliin on lisätty puskurit. Haarautumisenennustin laittaa jonoon osoitteita joista fetch hakee käskyjä ja käskynhakuyksikkö hakee näistä osoitteista käskyjä, kun ehtii.
(lisäksi vielä nykyään myös decoden ja renamenkin välissä on vielä puskurit, ja superskalaarisisssa in-order-prosessoreissakin on tyypillisesti jonkinlainen käskypuskuri decoden ja suorituksen välissä, joten niissäkään se branch folding ei säästäisi keskimäärin ainakaan läheskään täyttä kellojaksoa)
Toki nykyaikaisissa prossuissa on myös micro-oppeja säilövä looppipuskuri, mutta se on sitten myös vielä oma lukunsa. Sekin on kuitenkin selvästi eri juttu kuin branch folding.
Nyt kun prosessori on flushannut TLB:nsä itse cachen data on kuitenkin tallessa ja kun spectrellä hyökätään BTB:hen sieltä löytyvät käskyt lukevat datan suoraan cachesta -> jos BTB:tä ei saada flushattua seuraava homma on kirjoittaa koko cachet yli.
Nykyaikaisilla prosssoreilla TLB tagataan, ei flushata context switchin yhteydessä (SMTn toteuttaminen vaatii tätä).
TLBn tagibiteistä nähdään, että nämä entryt ei ole tällä hetkellä/tälle käskylle voimassa, eikä niitä käytetä. Sitten myöhemmin kun prosessorin tila on jälleen vaihtunut, ne entryt on taas voimassa, eikä niitä tarvi uudestaan ladata sivutauluista asti muistista.
Spectren 2.variantin ongelma ei ole BTBssä oleva käsky vaan BTBssä oleva käskyosoite. Siellä on osoite niihin käskyihin, jonka hyökkääjä haluaa suoritettavan. Ja ne käskyt on kernelin luettavissa, koska
A) kerneliin on mäpätty koko user-prosssin muistialue samaan paikkaan. (jos ei olisi, kaikki IO kernel- ja user-tilojen välillä olisi paljon hankalampaa ja hitaampaa).
B) hyökkääjä voi hyväksikäyttää/väärinkäyttää jo kernelin omalla muistialueella olevaa koodia, kun vain tietää sen osoitteen jotenkin.
Ja ratkaisuksi ei tarvi flushata mitään, riittää se, että myös BTB tagataan. Että BTB ei toimisi sellaisten ennustusten mukaan, jotka on "opetettu" eri tilassa kuin missä prosessori nyt on.
AMDllä tilanne spectren 2.variantin suhteen on käsittääkseni se, että kernel-tilassa ei koskaan spekulatiivisesti suoriteta koodia muistista, joka on on määritelty user-tilan muistiksi. Tämäkään ei kuitenkaan suojaa siltä, että kernelin omaan muistiin on saatu se hyökkääjän koodi jotenkin ujutettua, ja hyökkäjä tietää sen osoitteen.