Visualizzazione post con etichetta Corso VT-x. Mostra tutti i post
Visualizzazione post con etichetta Corso VT-x. Mostra tutti i post

martedì 11 gennaio 2022

06 - Comunicazione Client-Hypervisor

Finora si è usato un client al solo scopo di avviare la VMX operation. Sarebbe interessante sfruttare tale applicazione user mode anche per ricevere eventuali messaggi da parte del driver che implementa l'hypervisor, senza che si debba scomodare ogni volta il debugger. Per ricevere messaggi dal driver è necessario implementare un sistema di comunicazione client-driver. In questa lezione si userà il metodo ideato e sviluppato da Mohammad Sina Karvandi per la sua serie di tutorial Hypervisor from Scratch (si veda [1]). A grandi linee, l'idea alla base di tale sistema può essere rappresentata visivamente dalla seguente immagine.



In pratica, il driver scrive i suoi messaggi in uno tra due buffer in kernel mode. Il buffer non-immediate accumula messaggi ed evita di occupare troppi elementi dell'immediate buffer. Una volta che il non-immediate buffer è pieno viene copiato in un elemento dell'immediate buffer. Il client invia ciclicamente richieste al driver (tramite DeviceIoControl) per indicargli che è pronto a ricevere i suoi messaggi. Se il driver ne ha scritto qualcuno nell'immediate buffer allora accoda una DPC al processore corrente che verrà eseguita non appena l'IRQL associato a tale CPU sarà minore o uguale a DISPATCH_LEVEL. La funzione di callback eseguita non fa altro che copiare il messaggio dall'immediate buffer al buffer user mode, pronto per essere letto dal client.
Naturalmente ci sono molti altri dettagli da considerare e che verranno esaminati in questa lezione ma avere un quadro generale della situazione potrà aiutare non poco nel momento in cui si andrà ad analizzerà il codice.


domenica 12 dicembre 2021

05.C - Uscire dalla VMX operation

Una volta lanciato Windows 10 come guest e supportato Hyper-V, restituendogli le VM exit di sua competenza, sarebbe auspicabile trovare un modo per uscire dalla VMX operation e tornare ad eseguire il sistema operativo normalmente. L'idea è la seguente: eseguire una VMCALL dal nostro driver (in non-root operation) per indicare al nostro hypervisor (in root operation) di eseguire VMXOFF e riprendere ad eseguire codice normalmente.  Come richiamare l'attenzione dell'hypervisor tramite VMCALL è argomento ormai noto in quanto già affrontato nelle precedenti due lezioni. La vera novità è trovare un modo per ritornare ad eseguire codice una volta usciti dalla VMX operation. In realtà, anche questo è un argomento che si è già affrontato, in un certo senso, quando si voleva riprendere ad eseguire codice una volta entrati in VMX operation. Ad ogni modo, nulla verrà lasciato al caso e tutto verrà spiegato nei dettagli nel corso di questa lezione.


sabato 11 dicembre 2021

05.B - Convivere con Hyper-V

Per testare il nostro driver su una macchina virtuale gestita da Hyper-V è necessario prendere coscienza del fatto che l'hypervisor implementato in esso si mette in mezzo tra Hyper-V e Windows 10 in quanto verrà trattato come guest speciale a cui vengono passate tutte le VM exit. Questo non sarebbe un problema se, come già detto in una lezione precedente, Windows 10 non richiedesse supporto ad Hyper-V per svolgere alcuni dei suoi compiti in modo alternativo rispetto al solito. Se tutte le VM exit vengono passate al nostro hypervisor allora è necessario catturare quelle destinate a Hyper-v e ripassargliele per farle gestire a lui. La domanda è quindi: quali sono le VM exit destinate ad Hyper-V? Fortunatamente a facile rispondere a tale domanda in quanto esiste una documentazione specifica che indica quale dovrebbe essere l'interfaccia pubblica di un hypervisor conforme alle specifiche indicate da Microsoft. Il documento in questione è linkato a fine lezione nei riferimenti, si veda [5].


giovedì 9 dicembre 2021

05.A - Lanciare Windows 10 come guest

Prima di poter essere in grado di sottoporre l'intero sistema operativo correntemente in esecuzione alla supervisione del nostro hypervisor è necessario trovare un modo per lanciarlo come guest. Questa lezione (insieme alle prossime due) cercherà di spiegare un modo per ottenere tale risultato. Il codice di esempio è fortemente ispirato a quello di alcuni hypervisor (si vedano i riferimenti a fine lezione) che hanno codice sorgente consultabile pubblicamente. A loro vanno tutti riconoscimenti del caso.




L'idea di base, per lanciare Windows 10 come guest, è quella di caricare il driver del nostro hypervisor e salvare lo stato dei registri in un punto X della sua esecuzione prima di entrare in VMX operation. Fatto questo si può dirottare l'esecuzione al solo fine di entrare in tale modalità operativa, inizializzare la VMCS e lanciare il guest. In questo modo sarà sufficiente indicare al guest di riprendere ad eseguire il codice dal punto X nel nostro driver per ottenere il risultato desiderato: eseguire l'intero OS come guest. Vediamo come mettere in codice quanto appena descritto a parole.



lunedì 15 novembre 2021

4.F - Demo: Inizializzare la VMCS e lanciare il guest

In questa lezione si cercherà di mettere a frutto quanto imparato nelle lezioni precedenti creando un semplice hypervisor che esce dalla VMX operation se il guest esegue l'istruzione HLT. L'immagine seguente mostra i messaggi mostrati dal debugger che vengono generati da tale hypervisor.




Per non rendere troppo tedioso il discorso si eviterà di mostrare nuovamente il codice già analizzato nel corso delle precedenti lezioni. Il progetto completo può essere visionato cliccando sul link fornito a fine lezione.



giovedì 11 novembre 2021

04.E - VMCS: VM-entry e VM-exit control (ed information)

Le ultime tre aree che compongono la VMCS verranno esaminate in questa lezione e completeranno il discorso sull'inizializzazione dei campi che si trovano in tale struttura. La seguente immagine mostra solo due di queste tre aree ma quella mancante (VM-Entry Control) non è certamente meno importante.





mercoledì 10 novembre 2021

04.D - VMCS: VM-execution control

La VM-execution control contiene tutti quei campi in grado di controllare e governare l'esecuzione in non-root operation. In particolare, attraverso tali campi l'hypervisor può indicare quali sono le istruzioni eseguite e gli eventi generati dal guest che provocano una VM exit, e che quindi devono cedergli il controllo al fine di controllare l'esito finale di tali operazioni. L'immagine seguente fornisce una rappresentazione visiva della VM-execution control. Gli elementi con sfondo bianco rappresentano bit che appartengono al campo di bit arancione sull'estrema sinistra.




Verranno tralasciati (cioè impostati a zero) tutti quei campi\bit ritenuti marginali o non essenziali per un corso di base sulla virtualizzazione delle CPU. Allo stesso modo, verranno momentaneamente inizializzati a zero alcuni campi\bit particolarmente importanti nelle fasi successive del corso. Nelle seguenti sezioni verranno esaminati brevemente molti campi di interesse che compongono la VM-execution control. Per alcuni di questi campi verrà fornita una spiegazione più approfondita nel corso delle successive lezioni.



sabato 6 novembre 2021

04.C - VMCS: Guest-state area

La guest-state area contiene tutti quei campi che vengono caricati nello stato del processore al momento di una VM entry ed in cui viene salvato lo stato del processore al momento di una VM exit. Per tale motivo, è necessario inizializzare tali campi prima di lanciare il guest. Convenzionalmente la guest-state area si può dividere in due parti: quella relativa ai registri e quella non relativa ai registri. A prescindere da questo, tutti i campi devono essere inizializzati in qualche modo. L'immagine seguente mostra la guest-state area nella sua interezza.




Come nel caso della host-state area, si tralasceranno (cioè verranno impostati a zero) tutti quei campi che richiedono che il processore sia in grado di supportare l'impostazione ad 1 di un particolare bit che si trova al di fuori di quest'area. Stessa sorte verrà riservata per tutti quei campi ritenuti marginali o non essenziali per un corso di base sulla virtualizzazione delle CPU.



mercoledì 3 novembre 2021

04.B - VMCS: Host-state area

La host-state area contiene tutti quei campi che vengono caricati nello stato del processore al momento di una VM exit poiché sono necessari all'esecuzione dell'hypervisor. Per tale motivo, è necessario inizializzare tali campi prima di lanciare il guest. L'immagine seguente, presa dalla documentazione, mostra un elenco dei campi che si possono trovare nella host-state area. Tutti devono essere inizializzati in qualche modo.



lunedì 1 novembre 2021

04.A - VMCS: Introduzione

La Virtual Machine Control Structure (VMCS) è una struttura che permette al processore logico di gestire le transizioni da root a non-root operation (VM entry) e viceversa (VM exit) quando si trova in VMX operation. Ad esempio, serve a gestire il comportamento del processore in non-root operation: nel senso che se una particolare istruzione viene eseguita o un dato evento viene generato è possibile che si verifichi una VM exit ed il controllo passi all'hypervisor, che può alterare il risultato dell'istruzione o l'inoltro dell'evento prima di ridare il controllo al guest con una VM entry. Per far si che questo funzioni, una VMCS deve conservare tutta una serie di informazioni. In particolare, questa la struttura è composta da sei gruppi di campi:

Guest-state area: campi in cui lo stato di un processore logico viene salvato al momento di una VM exit e caricato al momento di una VM entry.

Host-state area: campi in cui lo stato di un processore è caricato al momento di una VM exit. Non è necessario salvarlo al momento di una VM entry perché eventuali modifiche a questi campi può farle benissimo l'hypervisor durante la sua esecuzione in root operation (prima di ridare il controllo al guest con una VM entry). In altre parole, l'hypervisor è a conoscenza della VMCS e quindi il compito di modificare i campi che gli interessano (quelli dell'host) spetta a lui.

VM-execution control: campi che controllano e governano la non-root operation. Attraverso tali campi l'hypervisor può indicare quali sono le istruzioni eseguite e gli eventi generati dal guest che provocano una VM exit, e che quindi devono cedergli il controllo per la loro gestione.  

VM-exit control: campi che indicano i comportamenti ed il contesto esecutivo durante le VM exit. 

VM-entry control: campi che indicano i comportamenti ed il contesto esecutivo durante le VM entry. 

VM-exit information: campi che ricevono una descrizione sulle cause che hanno portato ad una VM exit.

Naturalmente, prima di lanciare il codice del guest è necessario allocare spazio per tale struttura: una per ogni guest, copiata su ogni processore, in modo da permettere al codice guest di essere libero di essere eseguito dove vuole. Inoltre, si devono inizializzare alcuni campi obbligatori (indicati dalla documentazione). Nel corso delle prossime lezioni si vedrà proprio come inizializzare tali campi in base al gruppo di appartenenza (attenzione: dato che esiste una copia della stessa VMCS su tutti i processori logici si devono inizializzare tutte le copie). Prima di fare questo, però, è necessario acquisire qualche piccola nozione preliminare che faciliterà questo compito.
Prima di proseguire nella lettura si consiglia di rileggere la breve sezione già dedicata alla VMCS in una delle lezioni precedenti, insieme a quella intitolata Host e Guest in VMX operation (si veda [6]).



sabato 16 ottobre 2021

03 - Sistemi multi-processore

Come visto nella precedente lezione, prima di entrare in VMX operation è necessario fixare i bit dei registri CR0 e CR4 quindi, in sistemi multi processore, è necessario eseguire il fix su ogni CPU. Inoltre, come si è detto in un'altra lezione, è necessario avere una copia della VMCS per ogni guest su tutti i processori logici quindi, quando si imposta la VMCS associata ad un particolare guest, è necessario effettuare la modifica su tutte le copie mantenute dalle CPU. Normalmente un programmatore non è interessato a sapere su quale processore venga eseguito il codice ma in questo caso serve un meccanismo che garantisca l'esecuzione di alcune operazioni su ogni processore logico.
Ci sono vari modi per ottenere questo risultato ed ognuno ha i suoi vantaggi e svantaggi. In questa lezione presenteremo 3 metodi e, nel corso delle prossime lezioni, si deciderà quale usare in base alle proprie esigenze ed al tipo di operazioni che si vogliono eseguire.



domenica 3 ottobre 2021

02 - Hello VMX!

In questa lezione si userà quanto visto nella precedente andando a scrivere un semplice driver da testare sulla nostra VM creata con Hyper-V. Tale driver si limiterà a verificare il supporto della CPU alla virtualizzazione e ad abilitare la possibilità di entrare in VMX operation. Dopo tali operazioni l'interazione tra Host e Guest non è ancora iniziata dato che questa richiederebbe l'esecuzione di VMXON, per entrare in VMX operation, e VMXLAUCH, per la VM entry che passa il controllo al codice guest. Per tale motivo le possibilità di combinare guai sono abbastanza limitate in quanto, praticamente, non cambia nulla. Tuttavia, vedere come scrivere ed eseguire le prime fasi di inizializzazione nel nostro hypervisor è importante per consolidare alcuni concetti prima di passare al resto.





venerdì 1 ottobre 2021

01 - Concetti preliminari

L'argomento principale attorno al quale ruoterà questo corso è VT-x, la tecnologia sviluppata da Intel per consentire la virtualizzazione delle CPU. Grazie a questa tecnologia il normale software eseguito su una CPU virtuale risulterà, in molti aspetti, vincolato: nel senso che le istruzioni lecite che vorrebbe eseguire potrebbero essere preventivamente vagliate da un supervisore. Persino gli eventi generati durante la sua esecuzione (interrupt ed eccezioni) potrebbero essere controllati e, nel caso, fatti sparire nel nulla. In passato, leggendo semplicemente la documentazione Intel, non era semplice comprendere a pieno come funzionasse la virtualizzazione. Fortunatamente, nel corso degli anni, sono stati rilasciati codici sorgenti pubblici e tutorial sull'argomento che hanno aiutato tantissimo nella sua comprensione (si vedano i riferimenti a fine lezione). Leggere la documentazione Intel di questi tempi risulta quindi molto più semplice che in passato.
Non si discuterà invece della virtualizzazione delle periferiche di I/O (dischi e schede varie) in quanto per quest'ultima viene usata una tecnologia dedicata a parte (VT-d).



martedì 28 settembre 2021

00 - Introduzione ed ambiente di lavoro

Il presente corso è il risultato dell'elaborazione di una serie di appunti presi dal sottoscritto durante lo studio della virtualizzazione nelle CPU Intel, in particolare VT-x. A tale proposito, quindi, non c'è alcuna velleità pedagogica o educativa, ne tantomeno pretesa di originalità o attestazione di qualsivoglia proprietà intellettuale. Non scrivo con l'intendo di insegnare ma, semplicemente, di lasciare traccia ed evidenza, soprattutto a me stesso, di tutti gli sforzi ed il tempo che ho dedicato a questo argomento. Inoltre, è possibile che alcuni dettagli non siano corretti o, addirittura, che intere lezioni siano da rivedere (lasciate un commento per segnalare qualsiasi cosa). Fatta questa doverosa premessa, teoria e codice sorgente attorno a cui si svilupperà il corso prendono spunto da diverse fonti, in particolare le principali sono: