
Alkuvuoden polttavimmat puheenaiheet tietoturvan saralla ovat olleet Meltdown- ja Spectre-haavoittuvuudet, niiden korjaukset ja niistä aiheutuneet komplikaatiot. Etenkin Intelillä on ollut ongelmia päivitystensä kanssa, sillä ne ovat aiheuttaneet paitsi suorituskykyhävikkiä, myös uusia suoraan käyttäjille näkyviä ongelmia.
Kotikäyttäjien kannalta Intelin päivitysten vaikutus suorituskykyyn on käytännössä olematon tai lähes olematon. Päivitysten myötä syntyneet satunnaiset uudelleenkäynnistymiset ovat kuitenkin ongelma, joka näkyy helposti kotikäyttäjänkin arjessa. Intelin mukaan ongelman piti alun perin koskea vain Haswell- ja Broadwell-arkkitehtuureja, mutta sittemmin yhtiö on päivittänyt lausuntoaan koskemaan kaikkia Core-arkkitehtuureita Sandy Bridgestä lähtien.
Intelin tuoreimman lausunnon mukaan yhtiön insinöörit uskovat nyt löytäneensä perimmäisen syyn Haswell- ja Broadwell-arkkitehtuurien uudelleenkäynnistymisongelmaan ja edistyneensä jo huomattavasti sen korjaamisessa. Yhtiö ei kuitenkaan kerro, onko myös muiden Core-arkkitehtuureiden uudelleenkäynnistysongelmat kiinni samasta seikasta tai miten niiden korjaus edistyy.
Lopullista korjausta odotellessa Intel suosittelee, että OEM-valmistajat ja muut yhtiön tuotteita käyttävät palveluntarjoajat lopettavat nykyisten päivitysten jakelun ehkäistäkseen uudelleenkäynnistysongelman leviämistä. Lisäksi Intel toivoo kumppaniensa keskittyvän Haswell- ja Broadwell-prosessoreiden tulevan päivityksen esiversioiden testaamiseen, jotta lopullinen versio saataisiin jakoon mahdollisimman nopeasti.
Lisäksi Intel pyrkii tarjoamaan käyttäjille, joille järjestelmän vakaus on ensisijainen seikka, mahdollisuutta palata käyttämään edellistä versiota prosessorin mikrokoodista siihen saakka, kunnes lopullinen ja ongelmaton mikrokoodiversio on valmis. Mikäli edellinen mikrokoodiversio tuodaan saataville, se tulee asentaa BIOS-päivityksen muodossa. Edelliseen mikrokoodiversioon paluu ei vaikuta Spectren ensimmäisen variantin tai Meltdownin korjauksiin, mutta poistaa suojauksen Spectren kakkosvariantilta.
Lähde: Intel
Intelin prosessoreista löytynyt bugi vaatii suorituskykyyn vaikuttavan käyttöjärjestelmätason päivityksen
Puuttuu forum puolelta tuo päivityksen. Ei taida mahtua otsikkoon…
Niin, siinä Intel tekee turhaa työtä ja haaskaa energiaa ja muistikaistaa melko harvinaisessa tilanteessa. (ja lisäbonuksena on altis meltdownille).
Ja syynä oli se, että näin saatiin prosessorin rakenteesta yksinkertaisempi, vähemmän logiikkaa sinne latausyksiköihin. Siinä vaiheessa kun tämä ratkaisu tehtiin varmaan myös ajateltiin, että tämä tekee prosessorista luotettavamman, vähemmän paikkoja bugeille. Tämä vaan osoittautui virheelliseksi päätelmäksi.
Tämän takia pidän todennäköisempänä, että AMD on immuuni Meltdownille nimenomaan sen takia, että AMD halusi tehdä omista prossuistaan energiatehokkaampia eikä halunnut haaskata virtaa (ja kaistaa) tekemällä turhia laittomia loadeja, ja oli valmis lisäämään prosessoreihinsa monimutkaisuutta niiden laittomien latausten katkaisemiseen jo aiemmassa vaiheessa. Ja tämä sähkönkulutuksen ja muistikaistan optimointi myös teki AMDstä immuunin meltdownille. Eli että ihan virran- ja kaistansäästösyistä AMD sattui tekemään prossuistaan immuuneja meltdownille.
(en kuitenkaan ole varma tästä AMDn motivaatiosta)
Ei ne ole mitenkään "täysin rikki". Ne on täysin speksinsä mukaisia, alkuperäinen speksi vaan ei ota sivukanavahyökkäyksiä huomioon. Ja meltdowniin on olemassa softa-workaround joka suojaa siltä, siitä vaan tulee pieni suorituskykyhaitta kernel-kutsujen yhteydessä.
TLBllä ei edelleenkään ole tämän kanssa mitään tekemistä. Vaan vain sillä, koska laittomaan muistiosoitteeseen reagoidaan.
Ihan itse päättelin. Ei vaadi paljoa päättely- eikä laskutaitoa, kun ymmärtää miten välimuisti ja virtuaalimuisti toimii.
Sivutauluja kakutetaan melko normaalisti ainakin L2-kakuissa, (L1-kakuista en ole aivan varma, mutta ilmeisesti ei niissä). (*). X86-64lla sivutaulut on nykyään 4-tasoisia (mutta voidaan laajentaa 5-6 tasoon myöhemmin). Neljä riippuvaista latausta L2-kakusta tekee n. 48 kellojaksoa.
Efektiivisesti osoitteenmuunnos siis kestää n. 48 kellojaksoa ylimääräistä, jos sivutaulut tulee L2-kakuista eikä muunnostietoa löydy TLBstä.
Aivan triviaalia viivästää sitä ehdon tarkastelua tuon verran enemmän. Yksi riippuvainen haku DRAM-muistista asti sille hypyn ehdolle tekee heti yli 100 kellojaksoa.
(*)
Ja juuri tähän sivutaulujen kakuttamiseen liittyi Phenomin kuuluisa bugi, siinä ei toteutunut välimuistin koherenttius täydellisesti sivutaulujen latausten osalta ja tietyssä tilanteessa sivutauluja muuttaessa toinen prosessoriydin luki ne välimuistista väärin; workaround oli kokonaan kieltää sivutaulujen lataaminen välimuistista ja ladata ne aina DRAMilta asti)
Taidatpa vaan olla päättelyinesi yksin. Näitähän kutsutaan TLB-sidechannel hyökkäyksiksi nimenomaan sen takia että TLB:n tulokset tulevat liukuhihnalle käskyn kulkiessa, koko TLB:tä ei välttämättä dekoodata vaan vain osa jonka perusteella pystytään L1-cachesta lukemaan data, ja Intelin tapauksessa esimerkiksi se käyttöoikeus tarkastetaan vasta liukuhihnan lopussa, varmaan samalla kun tarkistetaan että osittain dekoodattu osoitemuunnos osui. Tästä sitten seuraa että aikaa ajaa spekulatiivisia käskyjä hyödyntäen on tietty osa liukuhihnan pituutta, 48 kellojaksoa (optimistinen arvio pagewalkille) on varmasti riittävän pitkä aika vesittämään tuon idean, varsinkin kun ainakaan esimerkeissä ei ole käytetty mitään poikkeuksellisen pitkiä suoritusaikoja omaavia käskyjä, kaikki tapahtunee normaalin liukuhihnan pituudella.
Saat pistää referenssiä jos joku muu on kanssasi samaa mieltä.
Pitää näköjään pitää oppitunti vielä L1-kakunkin toiminnasta…
L1n indeksoimiseen ei järkevästi toteutetulla L1D-välimuistilla tarvita YHTÄÄN bittiä sieltä TLBstä (koska VIPT). Ja intel ei ole ainakaan 486n jälkeen tehnyt muita VIPT-välimuisteja.
Virtuaalimuistisivu on 4096 tavua. Osoitteen 12 alinta bittiä(tai oikeastaan bitit 6:11, alimmat 6 voi vielä ignorata, koska välimuistilinjat) kertoo suoraan, missä indekseissä data voi välimuistissa olla. 8-tie-joukkoassosiatiivisessa välimuistissa on 8 kohtaa, joilla on tämä sama indeksi.
Näiden kahdeksan kohdan lukeminen (sekä data että tag-bitit) voidaan(*) siis aloittaa HETI odottamatta yhtään mitään TLBltä.
Eli samaan aikaan voidaan rinnakkain tehdä seuraavat asiat:
* lukea 8stä mahdollisesta (saman indeksin omaavasta kohdasta) paikasta välimuistista data ja tagit
* lukea TLB.
JA sitten seuraavalla kellojaksolla, kun nämä on tehty, tehdään tarkastus, vastaako jonkun kahdeksasta ladatusta välimuistilinjasta tag-bitit sitä arvoa, mikä TLBltä saatiin.
Ja tähän tarvitaan ihan kokonaan se fyysinen osoite.
Jos jonkun ladatun välimuistilinjan tagit osuu, sitten meillä on osuma, ja sen sisältö (alimpien kuuden osoitebitin osoittamasta kohdasta) välitetään lataukselle datana, ja muiden välimuistilinjojen data ifnorataan.
Jos taas minkään ladatun välimuistilinjan tagit ei osu, meillä on huti, ja sitten pitää lähteä huhuilemaan dataa seuraavalta välimuistitasolta.
Että mistä ihmeen osittain dekoodatusta osoitteenmuunnoksesta nyt oikein höpiset?
(*)
Käytännössä tosin virran säästämiseksi nykyään kaikista kahdeksasta ei välttämättä ainakaan dataa accessoida heti rinnakkain, vaan ehkä ensin vain kaikkien tagit sekä data vain yhdestä, jossa se todennäköisemmin on, ja sitten menee esim. ylimääräinen kellojakso jos se ei ole siellä, vaan jossain muussa (way prediction).
Mielenkiintoista keskustelua. Jotenkin tulee tämä mieleen.
![[IMG]](https://images.duckduckgo.com/iu/?u=http%3A%2F%2Ffarm4.staticflickr.com%2F3414%2F4628611135_d94357c77a_z.jpg&f=1)
😀
No kyllähän ne nyt on aika helvetin isosti rikki vaikka kuinka vänkyttäisit muuta. Lisäksi kuiske kuuluu että nuo workaroundit on jo kierretty joten seuraavaan workaroundia odotellessa ja katsotaan miten sitten taas tulee performance hittiä.
Ja vaikka sinä kuinka vänkyttäisit, niin intel ei ole rikki eikä amd ole rikki.
Jos intel on rikki, niin siitä seuraa että amd on rikki. Tästä taas seuraa että koko konsepti rikki on merkityksetön. Kaikki on aina rikki.
Jos Intelin prosessorit ei olisi isosti rikki, niin ei olisi nyt mitään meltdown fiaskoa.
Eli koko konsepti rikki on täysin hyödytön. Kaikki on rikki. Logiikallasi mikä tahansa jälkikäteen löydettävissä oleva asia tekee rikkinäiseksi, joten siitä seuraa että kaikki rikki.
Amd:stä löytyi spectre, joten sekin on rikki. Armit on rikki. Jne.
Täyttä paskaa sanon minä.
Kyllä. Lähes kaikki on rikki. Toiset enemmän toiset vähemmän.
Tässä pari huumori kuvaa, intel logo tiimi ollut selvästi aikaansa edellä. 😆
Wanhat prossut saa kuin saakin Spectre päivityksiä, hieman statustietoa täältä: https://newsroom.intel.com/wp-content/uploads/sites/11/2018/02/microcode-update-guidance.pdf
Eli siellä on jo pre-betat olemassa Sandylle ja Ivylle jne. Eli eiköhän lähikuukausina noi tule jakoon ihan suoraan käyttöjärjestelmän päivitysten mukana.
Helpompi tapa käyttää näitä reikiä https://gizmodo.com/researchers-find-new-ways-to-exploit-meltdown-and-spect-1823020029
Vaikuttaa edelleen hyvin hitaalta ja epävarmalta nyhräämiseltä..
Ja sillähän ei ole mitään väliä, koska koneen korkkaajan tarvitsee perinteisesti onnistua hommassa vain kerran jolloin omistajan peli on menetetty
Toki sillä on paljonkin väliä, miten tuota voidaan hyödyntää suuressa mittakaavassa. Hitaalla nyhräyksellä on se paha riski, että käyttäjä vittuuntuu ja siivoaa nyhräävän haitakkeen pois ja tekee myös ilmoituksen korkatuusta sivustosta ja lähettää mahdollisesti näytteen virustorjuntafirmaan joka yrittää työntää haitakkeen koneelle.
Itsekin olen jokusen ilmoituksen tehnyt. Fiksut haitakkeen työntäjät eivät tosin yritä saada samaa konetta tekemään epämääräisyyksiä montaa kertaa peräkkäin / päivä.
Optimoit sitten koko TLB:n pois, muuten hyvä mutta ilman TLB:tä cache voi osoittaa sen 12 bitin verran, 4kilotavua assosiaktiivisuudesta riippumatta, se ei liity tähän. Intelin L1D-TLB taulukko 4KB:n sivuille taitaa nykyään olla 128, eli 7 bittiä ja 8 bitin cachelinjat eli jokainen cachelinja pystytään ohjaamaan omaan osoitteeseensa TLB:n avulla. TLB sitten voidaan optimoida, eli 36 virtuaalimuistibittiä on aivan turha dekoodata, esimerkiksi 9 eli sivutaulun mukainen määrä antaa 2megatavun alueen jolle voidaan mapata 128 cachelinjaa, assosiaktiivisuus vain pilkkoo nuo pienemmiksi osiksi eli koko TLB:tä ja välimuistia ei tarvitse käydä läpi haussa, ainoastaan se assosiaktiivisuuden osa joka voi sisältää tuloksen.
Intelin prosessorit tekevät täysin uskomattoman typeriä juttua MMU:n ja spekulatiivisten lukujen suhteen. KPTI korjaa vain kernelin suorat muistiosoitukset pois, koko userspace on silti aivan täysin haavoittuva. Oletko kattonut miten Intelin prossut vuotavat datan, ei tehdä mov haluamastaan osoitteesta ja käyttää sitä johonkin aktivoimaan cachelinja. Eli ei minkäänlaista suojausta, spekulatiivinen muistihaku rikkoo kaiken. Toimivat Meltdown-mikrokoodipäivitykset vain sitten joutuvat ottamaan myös spekulatiivisen muistinkäsittelyn pois päältä ja tämä syö suorituskykyä niin että tuntuu.
Meltdown-attack onnistuu melkein keltä tahansa joka saa hello worldin koodattua. Meltdown-paperissa koodia ei käytetä kuin kernelidatan vuotamiseen mutta sama tapahan toimii Spectrenä eli userspacen vakoiluna, kaikki userspaceen sandboxattu koodi pystyy lukemaan isäntäohjelman kaiken datan. Webbiselaimiinhan tuli "Fixi" jossa ajoitustarkkuutta laskettiin jotta aivan naurettavan helppo reiän hyödyntäminen ei onnistu, mutta se ei varmasti ole kovinkaan pitävä paikkaus.
:facepalm:
Yritä nyt ymmärtää, miten välimuistin osoitteistus ja kirjanpito toimii. Lue vaikka viestini uudestaan ajatuksella läpi.
Siihen, että katsotaan mistä paikasta välimuistia jotain data löytyy jos se sieltä löytyy ei tarvita muita kuin niitä alimpia bittejä. Se määräytyy tuollaisessa välimuistissa vain niiden 12 alimman bitin perusteella.
Siihen, että tarkastetaan että osoittaako tämä data välimusitissa siihen paikkaan mihin nyt tehdään access tarvitaan sitten koko osoitetietoa.
Tämä mahdollistetaan että itse dataa (ja tagibittejä) voidaan hakea rinnakkain välimuistista ja sen osoitteen ylompiä bittejä TLBstä.
Mutta se osumantarkastus voidaan tehdä vasta kun osoitteenkuunnos on tehty.
Näin toimii VIPT-välimuisti.
Se, millainen on TLBn rakenne ja se, millainen sen L1D-välimuistin rakenne on kaksi täysin eri asiaa.
Tässä puhuttiin datavälimuistin rakenteesta, ei data-TLBn rakenteesta.
:facepalm:
Ei ole mitään yhtenäistä 2 megatavun aluetta missään jos käytetään 4 kiB virtuaalimuistisivuja. Jokainen 4 kiB virtuaalimuistisivu voi osoittaa fyysisessä muistissa aivan eri paikkaan.
Ja sen sivun fyysinen osoite on kokonaisuudessaan siellä sivutaulun viimeisellä tasolla. Sivutaulun aiemmissa tasoissa on pointteri siihen seuraavaan tasoon, ei mitään fyysisen osoitteen "sillä kohdalla" olevia bittejä
(ja millä ihmeen laskuopilla saat jotain 128 välimuistilinjaa johonkin?)
Ja siinä vaiheessa kun tarkastetaan, onko välimuistissä indeksiin numero 0 säilötty osoitteiden 32768-32831 data vai osoitteiden 2147483648-2147483711 sisätämä data, tarvitaan kyllä ihan jokaista osoitteen yläbittiä. Jos siellä puuttuisi yksikin bitti, sitten sen bitin kohdan verran toisistaan eroavat eri osoitteet sotkeentuisi välimuistin kirjanpidossa.
Ja sitä "osaa" välimuistista jossa se data voi olla, kutsutaan nimellä "setti" ja sen järjestysnumeroon (alkaen nollasta) viitataan termillä "indeksi".
Ja vaikuttaa muutenkin siltä, että olet tainnut käsittänyt assosiatiivisuuden aivan väärinpäin.
Pitää nimenomaan vääntää VIELÄ enemmän rautalankaa välimuistista.
Tosin Dunning-Kruger-efekti taitaa olla sillä tasolla että mikään rautalanka ei taida mennä perille, että miksi edes yritän..
Seuraava ei liity vielä mitenkään virtuaalimuistiin eikä TLBhen:
Ilman assosiatiivisuutta oleva välimuisti == direct mapped, "suorasijoittava"
Direct-mapped-välimuistissa jokaiselle muistiosoitteelle on tällöin tasan yksi mahdollinen paikka(indeksi), missä se voi välimuistissa olla. Tällöin osoitteen N alinta bittiä kertoo SUORAAN ja TARKKAAN sen, mihin kohtaan välimuistia se data menee, jos se sinne menee.
Välimuisti jossa on 64 tavun linjat, 32 kilotavun kapasiteetti, tarkoittaa että eli indeksejä on 512 kappaletta(0-511). 6 alinta bittiä(0:5) valitsee tällöin tavun välimuistilinjalta, seuraavat 9 bittiä(5:14) osoitetta valitsee suoraan indeksin, jolta data löytyy, JOS se välimusitista löytyy. Ja kaikki ylemmät bitit tallennetaan välimuistin tagikenttään..
Eli tällöin muistiosoitteet esim. 0x0, 0x8000, 0x10000, 0x18000, 0x2000, 0x10000000, 0x20000000, 0x400000000000 mevät kaikki välimusiti-indeksiin, eli indeksiiin 0. Ainoastaan yksi niistä voi kerrallaan olla tallennettuna välimuistilinjaan. Ja osoitteet 0x40, 0x8040, 0x18040, 0x2040, 0x10000040, 0x20000040, 0x400000000040 menevät kaikki välimuisti-indeksiin 1. Ainoastaan yksi niistä voi kerrallaaan olla tallennettuna välimuistiin.
Kun sitten tulee musitiaccess vaikka osoitteeseen 0x50000000, otetaan esin osoitteesta ne bitit, joitka muodostavat indeksin, accessoidaan välimusitia siitä indeksista, ja verrataan, mitä välimuistin tag-kentästä löytyy siitä indeksistä. Löytyykö sieltä samat ylimmät bitit kuin mihin nyt halutaan osoittaa, jolloin välimuisti sisältää sen osoitteen mitä haluttiin hakea, vai löytyykö sieltä jotkut muut bitit, jolloin välimuistissa on talletettuna jonkun muun osoitteen data, ja meillä on huti.
Tämän tarkastamiseen tarvitaan osoitteen kaikki ylimmät bitit. Jos sieltä jätettäisiin joku ylempi bitti pois, sitten sen bitin position verran tosistaan eroavia osoitteita ei välimuistin kirjanpidossa voisi eroittaa toisistaan, ja välimuistista annettaisiin toisen data toisen osoitteella.
Suorasijoittavan välimuistin pahin huono puoli on, että usein tehdään accesseja välimuistin koon kerrannaisen päähän toisitaan(kaikki kiva on kahden potensseissa, sekä välimuistien koot että yleiset taulukkokoon koodissa jne). Accessit peräkkäin osoitteisiin 0x8000 ja 0x10000 ja sitten taas 0x8000 ja sitten taas 0x100000 johtaa siihen, että 0x10000 menee välimuistissa samaan kohtaan (indeksi numero 0) kuin missä 0x8000 oli eli 0x8000 heitetään välimusitista pihalle. Sitten se joudutaan kolmatta accessia varten jälleen lataaman välimuistiin, ja heittää samalla osoitteen 0x10000 datan pihalle välimuistista. Ja sitten jälleen viimeinenkin access on tämän takia huti.
Sitten otetaan virtuaalimuisti ja TLB huomioon:
Ja jos tällaisen 32kiB suorasijoittavan välimuistin kanssa käytetään 4 kiB virtuaalimusitisivuja, osoitteenmuunnos pitää tehdä ennen välimuistista hakemista, koska osoitteenmuunnos vaikuttaa bitteihin 12:14 joita tarvitaan indeksin valitsemiseen, eli ennen osoitteenmuunnosta ei voida tietää, mistä indeksistä se välimusitista löytyy. Ei siis voida käyttää VIPTiä
Jotta direct mapped-cachelle EI tarvi osoitteenmuunnosta tehdä ennen kuin access siihen aloitetaan, tarvii sen koon olla niin pieni, että koko indeksi löytyy sieltä virtuaalimuistisivun sisäisistä biteistä, eli cachen koko maksimissaan virtuaalimuistisivun kokoinen.
Assosiatiivinen välimuisti taas tarkoittaa sitä, että siellä on efektiivisesti monta pienempää välimuistia rinnakkain(jokaista näitä kutsutaan nimellä way/tie). 8-tie-joukkoassosiatiivisessa niitä on 8. Ja data voidaan säilöä mihin tahansa niistä siihen indeksiin, mihin se osoitteeseensa mukaan osuu.
Eli nyt osoitteiden 0x8000 ja 0x10000 data voikin olla yhtä aikaa säilöttynä välimuistiin, koska osoite 0x8000 voi olla vaikka laitettu ensimmäiseen tiehen indeksiin 0 ja 0x10000 toiseen tiehen indeksiin 0.
Yksi setti muodostaa kaikkien näiden kahdeksan rinnakkaisen välimuistien samalla indeksillä olevat välimuistilijat. 0x8000 ja 0x10000 on indeksiltään samat(0) eli osuu samaan settiin, mutta koska jokaisessa setissä on monta välimuistilinjaa, ne voivat olla yhtä aikaa välimuistissa.
Virtuaalimuisti ja joukkoassosiatiivisuus:
Eli 32 kiB 8-tie-joukkoassosiatiivinen välimuisti koostuu kahdeksasta 4 kiB tiestä, eli 64 B linjakoolla jokaisessa tiessä on 64 linjaa. Tällöin osoitteen bittejä 6:11 käytetään linjan valitsemiseen. Kaikki mahtuvat samalle 4kiB virtuaalimuistisivulle. Voidaan käyttää VIPTiä.
ps. yhdessä suunnittelemistani prosessoriytimistä on ollut myös välimuisti.
Oletan, että sinä et sitten saa hello worldiä koodattua.
Toisilla ymmärtäminen prosessorin toiminnasta perustuu tietoon, kokemukseen ja ymmärtämiseen, toisilla uskoon ja epämääräisten yksittäisten tiedonjyvien lukemiseen ymmärtämättä yhtään kokonaiskuvaa ja niiden yksityiskohtaisten tiedonjyvästen merkitystä.
Toki kaikki sellainen, mitä ei ymmärrä, kuulostaa uskomattomalta.
Joko paljastit olet jälleen "uudella" tavalla täysin pihalla siitä, miten käyttäjärjestelmissä virtuaalimuistia käytetään, tai sitten sekoitat jälleen Meltdownia ja Specreä keskenään.
Userspace-ohjelmien muistia ole mapatty toisilleen. Meltdown ei toimi mappaamattomaan muistiin.
Ja Inteliä vastaan asian tiimoilta nostettujen kanteiden määrä on nyt noussut 35:een:
Spectre and Meltdown are now a legal pain for Intel — the chip maker faces 35 lawsuits over the attacks
Kyllä tästä jokin lasku täytyy kirjata jo ihan taseeseen.
Tätä keskustelua on ollut hauska seurata 🙂 Kieltämättä muutamassa kohtaa on meinannut kahvit tulla ulos nenästä.
No se on ollut paljon yksinkertaisempi kuin mistä nyt yrität vääntää juttua. Täähän ei ole edes mikään monimutkainen asia.
Eli jos sulla on x bittiä osoiteavaruutta niin kaikki muistiosoitteet on mapattava tähän muistiavaruuteen. Jos emme tarkasta kuin 12 alimpaa bittiä meillä on 4 kilotavua muistiavaruutta jolla cache voi operoida, pyöritteli sen miten päin tahansa.
Nyt jos meillä on täysi TLB käytössä pystytään mappaamaan kaikki muistiosoitteet koko muistiavaruudesta tähän cacheen(fully assosiactive, way-set assosiactive jakaa cachen sitten osiin). Jokainen TLB muunnos pitää kuitenkin suorittaa ennen muistiin viittaamista joten L1-tlb haussa voidaan hyvin tinkiä kuinka monta bittiä TLB:stä tarkistetaan, se yhdeksän bittiä oli vain esimerkki, eli jos TLB:stä tarkistetaan yhdeksän vähiten merkitsevää bittiä L1 TLB-haussa se muodostaa yhdessä 12 bittisen offsetin kanssa 21 bittisen alueen prosessin lineaarisessa osoiteavaruudessa. Toki koko tuo osoitteiston käännökset eivät ole yhtä aikaa TLB:n muistissa vaan ainoastaan TLB-entryjen mukainen määrä, eli jos esimerkiksi on se 128 4KB:n sivua TLB:ssä tuo kahden megan alue pitää sisällään 128 erillistä 4KB:n aluetta joiden kohdalla osoitemuunnos löytyy TLB:stä(ja vastaavasti 32 KB:n välimuisti pitää sisällään 64 erillistä 512 bitin aluetta) . Ja toki koko TLB-osuma pitää tarkistaa jossain vaiheessa(ennen storea) mutta tässä esimerkissä meillä on 2megan alue jolla ohjelma voi operoida ilman että TLB-muunnoksessa tulee vääriä muunnoksia noiden 9 virtuaalimuistibitin avulla.
Niin kuka on pihalla. Kaikki ohjelmistotko on erotettu erillisiin muistiavaruuksiin? Tuossahan oli esimerkkikin, webbiselaimen javascript joka pyörittää ulkopuolista koodia isäntäohjelman prosessissa, tälläisissä tapauksissa ulkopuolinen koodi voi täysin vapaasti lukea isäntäohjelman kaiken datan – ja tiedemme myös sen että selaimissa "korjaus" on toistaiseksi ajastimien tarkkuuden lasku tasolle jolla cachelinjojen nopeuden vakoilu on ainakin vaikeaa.
Mites esimerkiksi kaikki kääntäjien läpi ajettava koodi? JIT-kääntäjän pitäisi pyöriä eri muistiavaruudessa kuin ajettava koodi – mahtaakohan hidastaa 😀
Juu ei toimi. Virtuaalimuistin oikeusbitit eivät ole ongelma vaan se että Intelillä data prefetch tuo cachelinjoihin muutoksia myös pieleen spekuloiduissa muistihaussa, meltdown-vuodossa luetaan vain loopissa haluttua osoitetta ja data putkahtaa cacheen välittämättä edes oikeusbiteistä. Tämä on se ongelma mihin Intelin epätoivoiset mikrokoodipäivitykset yrittävät tuoda korjausta, mutta se vaatii myös ohjelmien uudelleenkäännön yms. skeidaa jotta homma saadan pelaamaan -> ainakin serverimaailmaan tuollaiset prossut on kyllä "rikki".
Spectressä sentään pitää huijata branch-predictor osoittamaan haluttua dataa, vähän sentään vaikeampi hyödyntää kuin suoraan pyytämällä haluamaansa dataa.
No väärällä mutta onhan tuossa kirjoituksessakin lähtötiedot väärin, 64 tavun cachelinjat on tietysti 9 bitin osoituksella eikä 8:n.
:facepalm:
Missään ei ole välimuisteja, jotka olisivat yksinkertaisempia kuin read-only-suorasijoittava välimuisti, jonka toiminnan selitin edellisessä viestissäni.
:facepalm:
Et siis ilmeisesti edelleenkään ymmärrä ihan perusteita siitä, mitä koko virtuaalimuistisivun käsite tarkoittaa, eli siis mikä on koko sivutukseen perustuvan virtuaalimuistin toimintaperiaate
Yritän nyt vielä vääntää senkin rautalangasta. (lisäselvennys vielä notaatiostani: 0x luvun alussa tarkoittaa tässä heksalukua, yleisimpien ohjelmointikielten notaatio, ohjelmointia kokemattomalle voi olla uusi juttu)
Sivuttavan virtuaalimuistin mappayksessa virtuaalisen ja fyysisen muistin välillä mäppäys tehdään sivu kerrallaan. Virtuaalisen musitin sivuja mäpätään osoittamaan vapaasti mihin tahansa fyyisen musitin sivuihin. Eli homma toimii siis täysin sivun koon granulariteetilla.
Muistiosoite koostuu kahdesta osasta: Sivun osoite (ylimnmät bitit) ja offset sivun sisällä (alimmat biit).
Jos muistiosoite on vaikka 0x00000034, sen sivun osoite on 0x00000000(josta voidaan impliittisesti jättää alimmat bitti pois, koska ne on aina nollia, eli 0x00000 ja offset sivun sisällä 0x34.
Jos muistiosoite on vaikka 0x00001034, sen sivun osoite on 0x000001000 (josta voidaan implisiittisesti jättää alimmat bitit pois, eli 0x00001, ja offset sivun sisällä 0x34.
jos muistiosoite on vaikka 0x12345678, sen sivun osoite on 0x12345000 (josta voidaan implisiittisesti jättää alimmat biti pois, eli 0x12345), ja offset sivun sisällä 0x678.
Virtuaalimuistia ei voida olla mäpätty osoittamaan siten että se alkaa jostain fyysisen muistisivun puolivälistä ja jatkuu seuraavan fyysisen muistisivun puoliväliin. Vaan se on mäpätty koko siihen sivuun.
Tämä tarkoittaa sitä, että se virtuaaliosoitteen muunnos fyysiseksi osoitteeksi ei koska niihin offsetteihin. Se, että joku osoite on sivun 576. osoite en aina sivun 576. osoite, riippumatta siihen, mistä sivusta on kyse.
Tämän takia mitään osoitteenmuynnosta ei tarvi tehdä niille alimmille 12 bitille. Ne on AINA VALMIIKSI OIKEAT KOSKA NE ON AINA SAMAT SEKÄ FYYSISELLE ETTÄ VIRTUAALISELLE OSOITTEELLE
Ensinnäkin,se, millainen assosiatiivisuus itse välimuistilla on ja millainen assosiatiivisuus TLBllä on on täysin erillisiä asioita.
Toisekseen, lähdet siitä virheellisestä lähtöoletuksesta, että täysin assosiatiivinen välimuosti olisi jotenkin normaalitilanne, josta "lähdetään liikkelle ja johon muita verrataan".
Tämä on väärä lähtöoletus, ja ne on hyvin harvinaisia, koska niiden osuman tarkastaminen yhtään suuremmasta välimuistista on äärimmäisen kallis operaatio(koska pitää verrata tagibittejä välimuistin joka ikisestä linjasta). Suorasijoittava on se yksinketainen perustapaus, ja muut on sitä että siitä lähdetään parantamaan.
Mitähän nyt oikein tarkoit sanalla "viitata" tässä….
… ei voida, koska pitää tarkistaa, että siinä välimuistissa sen indeksin kohdalla on juuri sen osoitteen data, jota halutan hakea. Eikä jonkun uun sellaisen osoitteen data, jonka alimmat biti sanoo että se menee siihen samaan paikkan välimusitissa, jos se on välimusitissa.
Haukut Inteliä siitä että intel ei ole suojannut prosessoreita hyvin hankalilta sivukanavhyökkäyksiltä ja itse olet valmis tekemään L1-datakakun, joka suostuu antamaan aivan väärän osoitteen dataa etkä näe tässä mitään ongelmaa
:facepalm:
:facepalm:
Tämä alkaa mennä jo kategoriaan "not-even-wrong".
Nykyaikaisissa prosessoreissa on 48-bittiset virtuaalisoitteet(*). Koska tahansa voi tulla osoituksia mihin tahansa näistä virtuaaliosoitteista. Ja mikä tahansa niistä virtuaaliosoitteista voi osoittaa mihin tahansa fyysesssä musitissa (paitsi että alimmat 12 bittiä on aina fyysisessä ja virtuaalisooitteessa samat). Kaikessa kirjanpidossa ja osoitteistuksessa pitää koko ajan ottaa tämä huomioon.
Ja sillä, mitkä entryt sieltä L1-DTLBstä löytyy, ja mitkä se joutuu hakemaan kauempaa, ei ole mitään tekemistä sen kanssa, mitä kirjanpitoa L1D-välimuisti tarvii. VIPT-välimuisti aloittaa accessinsa täysin TLBstä riippumatta(koska tarvii siihen accessiin aloittamiseen vain nitä alimpia 12 bitiä). Ja osuman tarkistamiseen tarvii sen koko fyysisen osoitteen, koska sen pitää pystyä erottamaan mikä tahansa fyysinen osoite toisistaan.
Se, että voidaan tehdä jonnekin 21 bitin alueelle muistisoituksia ilman että sen sisällä sekoaa mitään ei lohduta yhtään mitään, koska aina voi tulla accesseja sen 21 bitin alueen ulkopuolelle. Jos yritetään lukea osoitteesta 0x12345678 mutta saadaankin osoiteen 0x22345678 niin sitten prosessori toimii väärin.
Niinkuin oikeasti. Opettele ohjelmoimaan. Ensin jollain korkean tason kielellä, sen jälkeen assemblyllä. Sen jälkeen voisit ehkä alkaa joskus ymmärtääkin jotain.
(*) 64-bittisen pointterin ylimmät 16 bittiä on käyttämättä, voidaan myöhemmin ottaa käyttöön muuttamatta userspace-softia, vaatien muutosta vain kerneliin.
:facepalm:
Miten saat 64 tavun välimuistilinjoista 9 osoitebittiä?
Ei sen vapavalintaisen tavun osoiittamiseen sieltä tarvita kuin 6 bittiä.
Vai olet vuosia vängännyt vaikka mistä tietämättä edes niin yksinkertaista perusasiaa, että muistiositteet osoittaa tavuihin eikä bitteihin?
Ai näin korkealle tasolle pitää nousta? 2^9=512 bittia = 64tavua.
Puhuin siis TLB-optimoinnista, L1-cachen kanssa joko dekoodataan joka muistiviittauksessa koko virtuaalimuistiosuus TLB:stä tai luotetaan siihen että koodin tällähetkellä pyörivä osa mahtuu pienempäänkin muistijälkeen. Tästä oli polemiikkiä aikanaan software vs hardware TLB toteutuksissa kun tosiaan TLB:n osittainen dekoodaus avaa mahdollisuuksia side-channel vakoilulle mutta ongelma ei ole kovin suuri, hallittavissa ohjelmiston ja käyttöjärjestelmän suunnittelulla. Intelillä kuitenkin taisi mennä aika kauan vakuuttaa serverpuoli ratkaisun turvallisuudesta, ja sitten se kusee näin.
Käyttöoikeuden tarkastus olisi yksi bitti – tämänkin Intel on optimoinut pois, kertoneeko jotain siitä kuinka kriittinen TLB:n optimointi on.
Ja siis tämä on vain TLB:n nopeusoptimointi, kun on dekoodattu x määrä bittejä että TLB:n osumaprosentti on käyttötarkoitukseen riittävä voidaan mahdollisesti löydettyä osoitetta lähteä etsimään cachesta. TLB:n dekoodaus jatketaan loppuun sitten yhdessä cachen haun kanssa ja jos muistiviittaus tuli aluksi dekoodatun alueen ulkopuolelta tuli TLB miss ja perutaan tehdyt haut.
Jotenkin tämä keskustelu muistuttaa minua jostain aikaisemmasta väännöstä tämän aiheen ympärillä… siis, että keskustelussa on kaksi osapuolta, joista vain toinen tietää oikeasti mistä puhuu. Hieman rasittavaa edes sivusilmällä seurata tällaista…
Esimerkissäsi on tietoalkion koko. Jos on 2 kpl tuon kokoista(tai minkä kokoista tahansa) tietoalkiota, niihin viittaamisiin riittää yksi bitti. Se kuinka moneen alkioon pitää viitata määrittää indeksointiin tarvittavien bittien lukumäärän.
Edittiä eli korjausta.
:facepalm:
Missään viimeisen n. 50 vuoden aikana valmistetussa CPUssa normaalia muistia ei osoiteta bitti kerrallaan vain tavu kerrallaan.
Tämä jos mikä on ihan tietotekniikan alkeisasiaa.
(Ja jos jossain yli 50 vuotta vanhassa tietokoneessa muistiosoitteet osoittavat yksittäisiin tavuihin eikä bitteihin, C/C++-kieli ei toimi niissä, koska C-kielen speksi sanoo, että sizeof(char) == 1 ja kaikki osoitteenlaskenta mitä ohjelmissa tehdään pohjaa tähän)
(muutamassa hyvin harvinaisessa signaaliprosessorissa muistia osoitetaan esim. 16-bittinen sana kerrallaan, mutta tällaisetkin arkkitehtuurit ovat erittäin harvinaisia. Ja niillä siis joko char-tietotyyppi on 16-bittinen tai sitten 8-bittisten charrien accessoiminen pointtierien päästä vaatii monen käskyn verran ylimääräistä maskausta ja shiftausta)
:facepalm:
Perun sanani suosituksistani alkaa opettelemaan ohjelmointia.
On ehkä maailman kannalta parempi, että missään ei tulla koskaan ajamaan sinun kirjoittamaasi ohjelmakoodia.
Sinun mielestäsi prosessorin pitäisi vain luottaa siihen, että koodi nyt sattuu kerralla käyttämään vain n. miljardisosaansa koko muistiavaruudestaan.
:facepalm:
Kerrotko mielipiteesi siihen, mihin 48-bittisiä virtuaaliosoitteita mielestäsi tarvitaan, jos ohjelmat mielestäsi käyttävät vain n. 21 bittiä muistia kerrallaan?, eikä prosessorin tarvitse toimia oikein, jos ohjelma käyttää yli 21-bitin verran muistia?
Ei, kyse oli aivan eri asiasta. Sinä et vaan ymmärtänyt, mistä niissä puhuttiin.
Suurin asia, mikä tässä kusee on sinun ymmärryksesi ihan yksinkertaisista asioista liittyen ihan perusasioihin muistiin liittyen.
x86-64-tilassa tai PAE-päällä käyttöoikeuksille on kolme bittiä, vanhassa 386-moodissa 2 bittiä.
Siellä on erikseen lukuoikeus-bitti, kirjoitusoikeus-bitti ja execute-oikeus-bitti (joka puuttuu 386-tilasta, siinä se on yhdistetty lukuoikeusbittiin).
Väärin. Se bitti luetaan sieltä ja käskyyn merkataan pystyyn flagi, että tämä luku on osoitteeseen, josta ei saa lukea. Se käsitellään kerralla siinä vaiheessa kun sen siitä lentävän poikkeuksen saa heittää aiheuttamatta väärään aikaan lentävää poikkeusta.
AMD joutuu käsittelemään tämän kahdessa osassa, ensin vain keskeyttää sen loadin ja myöhemmin heittää poikkeuksen.
Ei sieltä TLBstä tarvita yhtään bittiä että se cacheaccess voidaan aloittaa, koska siihen accessin aloittamiseen tarvitaan vain niitä muistiosoitteen alimpia 12 bittiä, joita ei TLBstä tarvitse katsoa, koska ne eivät muutu osoitteenmuunnoksessa virtuaaliosoitteesta fyysiseksi.
Ja siinä vaiheessa kun tarkastetaan, tuliko osuma, ei voida luottaa yhtään mitään siihen mille alueelle accessi osuu, vaan pitää tarkastaa osoiteteen kaikki bitit, koska se voi tulla mihin tahansa osoitteeseen koko fyysisen muistin alueella.
Sekoitat nyt TLBn ja datakakun toimintaa todella pahasti keskenään.
TLBn nopeusoptimoinneilla ei ole mitään tekemistä sen kanssa, miten L1D-välimuisti toimii.
Olet lukenut joskus jostain jonka olet ymmärtänyt väärin. Höpinästäsi ei kuitenkaan saa selvää, mitä olet oikeasti joskus jostain lukenut.
Oliskohan oma topikki paikallaan tälle vääntämiselle? Jos tosiaan haluatte jatkaa vielä..
Äläs nyt. Tämä on jo erään toisen foorumin ajoilta hyvin tuttua vänkäämistä näille kahdelle käyttäjälle. Napataan me muut popcornit esiin, otetaan hyvä asento ja luetaan mielenkiintoista teknistä väittelyä – vaikka itse olen jutuista pihalla kuin lumiukko. 🙂
Ei voi.
Otappas nyt edes selvää, mitä termi "prosessi" tarkoittaa.
Kerrankos sitä pyörittelee lähtöarvot pieleen, sen takia on hyvä että tekijät on selvillä niin muut huomaa helposti missä meni mehtään.
Saatat olla täysin oikeassa. Pitäis panostaa itse asiaan ja jättää ylimääräiset höpinät pois.
Eli cachen toiminnastahan olet täysin oikeassa, itsellä oli vain vähän ongelmia sisäistää kun ei peruslaskuista lähtien onnistunut.
Mutta yritetään siis uudestaan kun lähtöarvot on saanut päähän oikein.
Eli 8 way set cachessa tarvitsee vertailla 8 kpl 12 bitin offsettiä yhdessä TLB:n dekoodauksen kanssa -> TLB:stä taas tarvitsee verrata 4kpl 36:ta sivunumerobittiä(jos siis 4-way TLB). Käsittääkseni kaikki nämä eri vertailut voi laittaa yhtäaikaa liikkeelle. 36 bitin comparaattori on vain huomattavasti hitaampi kuin 12 bitin -> meillä on mahdollisesti kellotaajuutta rajoittava hidas polku.
-> jos dekoodaamme tässä vaiheessa vain samat 12 bittiä sivunumerobiteistä saamme varmaankin tulokset valmiiksi likipitäen samassa ajassa – ja meillä on 24bittiä(16MB jos nyt laskut menee oikein) lineaarista muistiavaruutta dekoodattuna. Eli siis ajettavan koodinpätkän osat jos ovat tuolla alueella löydetyt TLB-hitit ovat oikeita. Ja kun otetaan huomioon että TLB range sivuista laskettuna on 128*4KiB=512KiB(1/32 osa alueesta) ja itse cachea on 32KiB noita väärin tulkittuja osittain dekoodattuja TLB-tuloksia on hyvin pieni prosentti verrattuna normaaleihin TLB-misseihin. Ja tässä siis kyse L1 DTLB:stä, hudin vaikutus ei ole suuren suuri kun L2 TLB:kin löytyy. Mun muistikuvat asiasta on kuitenkin ajalta jolloin missään prosessorissa ei ollut useampitasoista TLB:tä.
Ja nykyprosessorilla kyse ei optimoinneissa taida enää olla niinkään nopeudesta kuin tehonkulutuksen optimoinnista, eihän esimerkiksi se pois tässä vaiheessa jätetty yhden bitin käyttöoikeustarkistus voi nopeutta rajoittaa mutta tehonkulutukseen voi olla pieni vaikutus.
Nykyäänhän on käytössä Kernel-mode JIT kääntäjiäkin, sellaisen läpi ajettuna Spectrekin pääsee käsiksi kernelimuistiin.
Mutta kaikki prosessorit eivät ole yhtä haavoittuvaisia, Spectre pääsee lukemaan kernelimuistia Intelin prosessoreilla myös userspacessa ajetusta ohjelmasta, ei muilla.
No joo tuokin tosin varmaan on tilanne ennen Meltdown-päivitystä, ei sen jälkeen.
@hkultala & @Sami Riitaoja
Voitaisiinko pojat sopia, että tätä vääntämistä jatketaan vaikka YV:n puolella. Menee nyt vähän turhan pitkäksi vääntämiseksi täällä.
Mitä helvettiä? Ymmärrän juuri ja juuri eri ketjun, mutta muuten kyllä en vähääkään.
Tod näk tässä on oppinut enemmän cpu:n toiminnasta kuin missään aiemmin.
Tämä on mennyt kahden henkilön vääntämiseksi, eikä ainakaan minusta palvele tämän otsikon alla. YV, uusi ketju, mikä se ratkaisu sitten onkaan.
No hoida sitten hommasi ja siirrä keskustelu sopivaan ketjuun.
Keskustelu on sillä tasolla että ihmisiä ei ole kovin montaa, jotka tunee cput noin hyvin. Mutta ei se voi olla syy rajoittaa keskustelua.
Eikä se myöskään tarkoita sitä että muita ei kiinnostaisi ja keskustelu pitäisi käydä yv:llä.
Mielenkiinnolla olen seurannut myös tätä keskustelua ja mielellään näkisin sen jatkuvan.
N-way set cachet on multa aina mennyt ohi älyn kun asiaa on kuvattu n-määrällä laatikoita joissa cachelinjat. Kultala selitti hyvin että homma lähtee direct-mapped cachesta jonka avulla löysin yhden fiksun sivun joka kuvas asian juuri noin, n tuossa määrittää montako cachelinjaa aina muodostaa setin ja setti on sisäisesti fully assosiactive. Nyt em. asiakin mahtui älyyn, toivottavasti on vielä oikeinkin.
Eikai sitä kukaan viitsi YV:nä vääntää mitään 😉
@Ville Suvanto henkilöiden keskustelu on ollut ihan asiallista ja asiassa pysyvää, joskin ei otsikon. Tuollaisen nillittämisen sijaan olisit voinut tehdä sen ketjun uudella otsikolla ja siirtää henkilöiden viestit siihen.