The fundamental idea behind a virtual machine is to abstract the hardware of a single computer (the CPU, memory, disk drives, network interface cards, and so forth) into several different execution environments, thereby creating the illusion that each separate environment is running on its own private computer. (Silberschatz et al. 2018).
Virtualization allows a single computer to host multiple virtual machines, each potentially running a completely different operating system.
È virtuale nel senso che la macchina virtuale ha la stessa percezione della realtà di una macchina reale. Qualcosa che non è la realtà ma appare molto simile ad essa.
Storicamente parlando le macchine virtuali erano un primo approccio al multitasking.
L’idea principale è creare un sistema che possa apparire al sistema operativo come hardware, in questo modo posso utilizzare un programma per emulare un altro sistema operativo. È hypervisor, VMM (virtual machine monitor).
Ovviamente ho uno fortissimo svantaggio in velocità, perché la simulazione software è molto meno efficiente della simulazione hardware. Un collegamento carino è con (Hofstadter 2007), una macchina che sia abbastanza espressiva da poter emulare sé stesso.
Analisi vantaggi svantaggi 🟨

- Posso avere sistemi operativi differenti sulla stessa macchina o SO, quindi posso sperimentarli senza installarli veramente.
- Posso simulare architetture differenti, e quindi supporre di avere istruzioni differenti di architettura altra!
- SO monotask in sistemi multitask.
- Maggiore sicurezza a bug software, è efficienza energetica.
Svantaggi:
- fortemente inefficiente
- Peso in più sia sulla memoria
- Context Switch molto frequenti che lo rendono più lento
- I/O lento.
- Difficile condividere risorse fra una macchina virtuale o all’altra.
Desiderata per virtualizzazione
Chiamiamo le proprietà di partizionamento:
- Condividere le risorse della stessa macchina
- Isolare le macchine diverse, in modo che non possano influenzarsi a livello software, in modo da creare la giusta simulazione, esattamente come macchine fisiche reali, che non possono comunicare fra di loro.
E la incapsulazione, con controllo completo di checkpointing, migrazione e replay. Nel caso di servizi cloud, avere queste desiderata rende possibile andare a copiare i dati in giro e riprendere l’esecuzione in un altro hardware, vedere Cloud Computing Services.
Desiderata principale:
- Efficienza: la virtualizzazione non deve essere troppo lenta, altrimenti non ha senso.
- Compatibilità: deve essere compatibile con il software esistente (deve eseguire allo stesso modo in macchina virtualizzata o meno).
- Isolamento: le macchine virtuali devono essere isolate fra di loro. pr
Virtualizzazione di Popek and Goldberg
Nel 1974 Popek e Goldberg hanno definito i requisiti per la virtualizzazione, che sono:
- Devono esistere una modilità kernel and user.
- Tutte le istruzioni sensibili devono essere istruzioni privilegiate.
- Le istruzioni sensibili sono quelle che cambiano lo stato a livello hardware (allocazioni, mappature)
- Le istruzioni privilegiate sono quelle che usano trap.
Al tempo il processore Intel x86 non era virtualizzabile, perché certe istruzioni sensibili (sensitive) non aveva istruzioni privilegiate, e quindi non poteva essere virtualizzato. Per esempio il registro %cs conteneva il livello di privilegio, e non poteva essere virtualizzato (esempio se OS pusha quel registro sulla stack, si dovrebbe aspettare il massimo livello di privilegio), dato che il VMM non poteva catturare la trap ed emulare l’istruzione, non era possibile virtualizzare questa operazione. Per questo usiamo binary translation per questo, ma impatta leggermente la velocità di esecuzione.
Livello processo o sistema 🟩
Le macchine virtuali di cui abbiamo parlato ora virtualizzano solamente l’hardware, cioè fa finta di avere un sistema hardware.
Mentre altre macchine virtuali provano a virtualizzare a livello di ABI (application binary interface) (che è livello di processo).
- Macchina virtuale a livello di processo (process VM): permette ad un programma di essere eseguito allo stesso modo su qualsiasi piattaforma. Un esempio di questo è la macchina virtuale di Java. Viene eseguita come una normale applicazione all’interno di un SO ospite e supporta un singolo processo. Il suo scopo è fornire un ambiente indipendente dalla piattaforma hardware e dal SO ospite. Vengono virtualizzati sia l’hardware che il sistema operativo.
- Macchina virtuale a livello di sistema (system VM): permette l’esecuzione di un completo SO, anche con un ISA diverso da quello della macchina reale. Viene virtualizzato esclusivamente e completamente l’hardware.
Differenza type 1 and 2 hypervisors
type 1 hypervisor and a type 2 hypervisor is that a type 2 makes uses of a host operating system and its file system to create processes, store files, and so on. A type 1 hypervisor has no underlying support and must perform all these functions itself (it runs on the bare metal, come se fosse lui stesso un sistema operativo, è infatti un sistema operativo che non fa altro che fare sistemi operativi!)
Esistono anche type 0 hypervisors che sono direttamente supporto per macchine virtuali fatte a livello hardware. Esempi di questo sono IBM LPARs and Oracle LDOMs.
Virtual Machine Monitor
Questo è quello che viene chiamato anche type 1 hypervisor. È un sistema operativo che gestisce altri sistemi operativi che eseguono sopra di esso. Chi sta sopra pensa di possedere l’intero hardware, mentre in realtà è la VMM che prova a tradurre o mandare di sotto.
Virtualizzatori
In questa sezione introduciamo alcuni eventi di virtualizzatori.
Qemu 🟩
qemu è un traduttore dinamico come se fosse un compilatore fra una architettura in una altra, fatta a runtime (quindi è un interprete, tipo 10x più lento rispetto esecuzione normale, ma un ordine di grandezza più veloce rispetto altri emulatori).
Con qemu posso anche dire al processo emulato di utilizzare il mio stesso kernel, nel caso che condivida l’architettura, questo rende la cosa molto più veloce del normale! e.g. KVM (che è il nome dell’Hypervisor per linux). Questo è anche una tipologia di type-2-hypervisor perché attingo al kernel della macchina ospite per fare funzionare più in fretta, e non faccio simulazione sistema totale.
Utile o per runnare programmi per architettura differente (in questo senso program VM), oppure per emulare un sistema operativo dentro un sistema operativo.
-
Comando per caricare una macchina virtuale con qemu e utilizzare KVM
senza vga, non starebbe sullo schermo senza quella flag. hda gli specifica il file con cui emulare il disco, k il layout del keyboard m è la memoria ram monitor è per poter mandare interrupt dal terminale in cui ho lanciato il mio comando di emulazione. Quando installa prima è installato nella RAM disk, e poi viene utilizzato per l’installazione vera e propria.
XEN 🟩
XEN è hypervisor livello 1 (SO che permette di fare altri SO virtuali), e utilizzare paravirtualizzazione (si fanno trap and emulate principalmente) , e utilizza una gestione diversa dei drivers che possiede, ossia il Domain0 possiede tutti i drivers fisici (le interazioni con i device le manda alla macchina 0, perché per restare un sistema operativo semplice non riesce a gestire sistemi operativi).
Esempio di maggiore efficienza
Per il type 2 hypervisor il SO installato pensa veramente di stare in una macchina sé, quindi fa cose per minimizzare i seek del disco ma in questo caso non deve fare veramente seek, quindi è meno efficiente, facendo una assunzione errata.
Si utilizzano paravirtualizzazione, ossia devices virtuali più efficienti per questa cosa, ed effettivamente non assumo di stare utilizzando device fisici, ma sono a conoscenza di utilizzare device virtuali, e posso fare ottimizzazioni del caso (che non so quali siano forse per il disco non faccio cose strane per il seek ad esempio).
Il problema è che essendo a conoscenza, dovrei fare il mio SO in modo che sia compatibile con le hyper all offerte dall hypervisor
Implementazione della Virtualizzazione
Metodi di virtualizzazione
Possiamo considerare tre metodi principali di virtualizzazione:
- Simulazione via software sull’host (molto molto lento, tipo 100x volte più lento)
- Un esempio è QEMU in full emulation.
- Esecuzione diretta
- Trap and emulate in cui il VMM intercetta il trap ed esegue l’istruzione equivalente
- Emulazione con supporto hardware
- come con le estensioni Intel VT-x e AMD-V.
- Questo è il metodo più utilizzato oggi giorno.
- Vedi sezione di istruzioni di virtualizzazione.
- Add Virtual Machine Control Structure (VMCS) che decide quali istruzioni fanno VMexit, e quando si può cambiare queste informazioni con VMread or write e simili, consentendo all’hypervisor di controllare il comportamento della VM.
- Dynamic binary translation
- Necessario quando l’hardware non è totalmente virtualizzabile, quindi introduce delle istruzioni di emulazione in più.
- Paravirtualizzazione
- In questo caso il SO virtuale è a conoscenza che esiste un hypervisor quindi può fare delle hypercall per eseguire delle istruzioni sensitive, e in generale è un approccio più veloce invece della virtualizzazione totale di cui abbiamo parlato prima. Però bisogna essere a conoscenza del hypervisor.
- Quindi andiamo a modificare parti del SO in modo da tenere in considerazione l’esistenza dell’hypervisor, rende più veloce, però bisogna andare a modificare il SO stesso, per ogni SO.
- Un esempio è XEN.
Parametrizzazione SO 🟩
Questo non è proprio un metodo di virtualizzazione di un Sistema Operativo, ma un modo per modificare leggermente alcuni sistemi operativi.
Essendo libero linux, è molto comodo poter cambiare alcuni parametri e poi ricompilare il kernel seguendo quei parametri. Tanto è tutto open source, quindi si potrebbe fare. Questo permette al kernel di essere molto portabile.
Una cosa molto importante da capire è che il kernel è una cosa diversa della distribuzione, il kernel è il primo programma che viene caricato dal bootloader e carica il FS e tutto il resto (quindi le cose iniziali), il secondo sono tutte le utility per il kernel che lo rendono utilizzabile da un utente normale.
-
Comando runnato per la emulazione kernel/distribuzione
-
Slide parametrizzazione ++ portabilità (che deve runnare per hardware differentI)
Istruzioni di virtualizzazione 🟥
Abbiamo aggiunto delle istruzioni di emulazione come VMX ON, VMX OFF, VMLAUNCH, VMRETURN
in cui il processore sa di stare emulando, e quindi è più veloce perché esegue l’istruzione in altro modo, forse con istruzione nativa. Pagina wiki
fa pensare di essere in kernel mode, ma non è in kernel mode, è come se stesse in un livello di priviliegio intermedio.
VMLAUNCH
Queste sono quelle principali istruzioni che permettono la virtualizzazioen a livello software, il fatto che rende l’esecuzione molto più veloce, quindi invece di simulare tutto sopra il sistema operativo attuale (e syscalls attuali) posso accedere ad istruzioni hardware molto più veloci.
Memoria Virtuale
C’è una MMU del sistema operativo che mappa alla VM fisica, che si deve basare all’indirizzo logico, che deve essere risolto dalla MMU reale fino ad avere un indirizzo fisico.

Permettono di evitare l’utilizzo di Shadow page tables, che sono il remapping della pagine virtuali con le pagine fisiche. Ci sono esattamente lo stesso numero di pagine nei sistemi operativi virtuali con il numero di pagine nel shadow page table. Esiste molto overhead di memoria per quanto riguarda questa parte.
Extended Page Tables
Abbiamo in pratica una sezione di traduzione in più per mapparlo a EPT (Extended Page Tables), che mappa le pagine virtuali con le pagine fisiche, e quindi non c’è overhead di memoria, e quindi è molto più efficiente in comparazione con le shadow page tables.

Virtualizzazione di I/O
Problemi di virtualizzazione I/O
Si ricorda in Devices OS che solitamente questi usano Direct Memory Access per scrivere per il sistema operativo, però questo spesso non è possibile e bisogna fare qualche interrupt virtuale per risolvere questo problema. Possiamo
- Para virtualizzare l’interfaccia del device
- Emulare il device I/O.
Single Root I/O Virtualization
SR-IOV enables hardware-assisted virtualization by partitioning a single PCIe device into multiple Virtual Functions (VFs), which can be assigned directly to virtual machines (VMs) or containers. This reduces overhead caused by traditional software-based I/O virtualization.
Key Components of SR-IOV:
- Physical Function (PF)
- The main PCIe function, fully featured, controlled by the host OS (hypervisor).
- Manages and configures the Virtual Functions.
- Virtual Functions (VFs)
- Lightweight PCIe functions with limited resources, assigned to VMs or containers.
- Each VM gets direct access to a VF, bypassing the hypervisor for performance gains.
References
[1] Silberschatz et al. “Operating System Concepts” Wiley 2018
[2] Hofstadter “I Am a Strange Loop” Basic Books 2007