La comprensione della tecnologia Wintel VT-x o AMD-V introdotta nel 2005,
resta ancora abbastanza fumosa ai più, se non per la sua implementazione a più
alto livello.
Queste righe hanno lo scopo di chiarire l'
idiosincrasia
verso questo tipo di architettura.
La virtualizzazione non è certo invenzione dei giorni nostri, visto che già
negli anni 70 l'IBM pionieristicamente introdusse questa tecnologia sui suoi
sistemi denominati IBM/370.
Semplificando, diremo che il trucco sta nel servirsi della partizione del
tempo d'uso della cpu (con opportuni algoritmi di scheduling), e delle tecniche
della memoria virtuale. Un sistema operativo può creare così l'illusione che
un processo disponga della propria CPU con la propria memoria (virtuale).
Ciò detto, dobbiamo precisare che gli approcci alla virtualizzazione sono di
due tipi, detti di
hypervisor di tipo 1, ove l’hypervisor è eseguito sul nudo
hardware. La macchina virtuale è eseguita come un processo utente in modalità
utente e come tale non gli è consentita l’esecuzione di istruzioni
privilegiate. La macchina virtuale esegue un sistema operativo guest che pensa
di essere in modalità kernel, sebbene sia in modalità utente. Diversamente, un
hypervisor di tipo 2 non è altro che un programma utente (che gira su un
sistema tipo Windows, Unix, ecc.) dove l’hypervisor viene eseguito come un
qualsiasi programma applicativo e ne segue le regole ancorchè applicate al contesto della virtualizzazione.
Sebbene ci si possa aspettare che la tecnica adottata dal hypervisor di tipo
1 dia prestazioni maggiori di quella di tipo 2, in realtà non è così.
Semmai l’hypervisor di tipo 1 può sfruttare le caratteristiche peculiari del
tipo 2 per migliorare le proprie performante, dando vita ad una sorta di sistema
ibrido dove vengono prese in prestito le migliori caratteristiche dei due tipi
di architetture.
Per completezza dobbiamo dire che esiste una terza tecnica (migliorativa) di
virtualizzazione detta
paravirtualizzazione, le cui specifiche esulano
dallo scopo di questo post.
Il motivo dell’esistenza dei due tipi di hypervisor ha a che fare con i difetti dell’architettura
del processore Wintel 386, portati avanti servilmente nelle nuove CPU per vent’anni,
in nome di una retrocompatibilità.
In parole povere, ogni CPU con la modalità kernel e la modalità utente ha un
insieme di istruzioni eseguibile solo in modalità kernel, come le istruzioni che
fanno l’I/O, il cambio delle impostazioni dell’MMU e così via.
Ci sono anche delle istruzioni che, se eseguite in modalità utente,
provocano un trap.
Nelle architetture I386 se si prova a fare qualcosa in modalità utente che
non dovrebbe essere eseguito in modalità utente, l’hardware dovrebbe eseguire
un trap. Diversamente dall'IBM/370, che possedeva questa proprietà, non era
così per il 386. Un discreto numero di istruzioni significative, se eseguite in
modalità utente, erano ignorate. Per esempio, l’istruzione POPF sostituisce il
registro dei flag
, cambiando il bit che
abilita/disabilita gli interrupt. In modalità utente questo bit semplicemente
non cambia. Conseguentemente, il 386 e i suoi sucessori non potrebbero
supportare un hypervisor di tipo 1.
In realtà, la situazione è leggermente peggiore di quanto delineato. Oltre
ai problemi relativi alle istruzioni che non riescono ad eseguire il trap in
modalità utente, ci sono istruzioni che possono leggere lo stato sensibile in
modalità utente senza provocare un trap.
Questi problemi furono risolti dal Intel (una ventina d'anni dopo
questo documento) introducendo o meglio migliorando la virtualizzazione
sui loro processori, quelli che oggi tutti conosciamo come VT.
La soluzione intrapresa è quella di far girare le machine virtuali in una
sorta di container, una zona del processore che, detta in modo semplicistico ma
lapalissiano, emula un IBM/370.
Ogni considerazione sulla (in)voluzione della tecnologia è lasciata come esercizio al lettore...