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.
- Efficienza: vuoi che la macchina comunque sia veloce abbastanza da emulare quello che deve fare.
- Equivalenza: uno stesso programma eseguito su macchina virtuale e non dovrebbe avere gli stessi effetti.
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.
Virtualizzazione di Popek and Goldberg
Nel 1974 Popek e Goldberg hanno definito i requisiti per la virtualizzazione, che sono:
- Devono esistere una modalità 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.
Anelli di privilegio

Image from CCA course slides 2025 ETHz
Functions calls between rings can happen only through hardware-enforced mechanisms. Code in more privileged can read and write memory in lower privilege ring.
Examples of priviledged operations include:
- Update memory address mapping
- Flush or invalidate data cache
- Read or write system registers
- Change the voltage and frequency of processor
- Reset a processor
- Perform I/O operations
- Context switch; change from kernel mode to user mode
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
Intel VT-X
With Intel VT-X hardware virtualization support, the processor supports two modes of execution: VT Root mode and VT Non-Root Mode. In root mode, the CPU operates much like older generations of processors without VT-x support of the four privilege levels (ring 0, 1, 2, 3).
In non-root mode, there are still four privilege rings and the same instruction set, but a new structure called VMCS (Virtual Machine Control Structure) now controls the CPU operation and determines how certain instructions behave. To efficiently support virtualization, the hypervisor runs in VT Root Mode while the guest OS runs in Non-Root mode and the hypervisor can configure the VMCS to cause a VMexit (i.e., hardware-level transfer of control to VMM) when a sensitive instruction is executed, avoiding the need for software traps.
Implementazione della Virtualizzazione
Possiamo considerare tre metodi principali di virtualizzazione:
Simulazione diretta
- Simulazione via software sull’host (molto molto lento, tipo 100x volte più lento)
- Un esempio è QEMU in full emulation.
- Questo in inglese è chiamato hosted interpretation.
Esecuzione diretta
Qui listiamo principalmente due metodi di virtualizzazione.
- Trap and emulate in cui il VMM intercetta il trap ed esegue l’istruzione equivalente
- Dynamic binary translation
- Necessario quando l’hardware non è totalmente virtualizzabile, quindi introduce delle istruzioni di emulazione in più.
- Questo significa che durante l’esecuzione di istruzioni che dovrebbero essere virtualizzate, si ha una traduzione diretta dell’instruzione in parti equivalenti valide (ad esempio quando esegui una istruzione privilegiata, aggiunge una istruzione che fa trappare ed eseguire la stessa cosa).
- Translation happens during runtime, and then it is directly executed.
- Necessario quando l’hardware non è totalmente virtualizzabile, quindi introduce delle istruzioni di emulazione in più.
Supporto Hardware
Questa è di gran lunga la versione di virtualizzazione più efficiente.
- come con le estensioni Intel VT-x e AMD-V.
- Emettono istruzioni come
vmexit
evmentry
che permettono di passare fra un livello di privilegio a un altro.
- Emettono istruzioni come
- 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.
- Questo si può configurare: esplicitamente indicare quali soluzioni triggerano quali cambi di privilegi.
Un problema con questo metodo è che eseguire una trap per ogni esecuzione privilegiata aggiunge tempo di computazione, quindi abbiamo qualche overhead per istruzione.

Esempio di struttura con VMCS | Immagine dal corso CCA 2025 ETH Zürich
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.

x84-64 address translation
Solitamente i sistemi x86-64 utilizzano un sistema di traduzione che è multi-livello.
Quindi abbiamo bisogno di 4 accessi a tavole per sistemi a 64 bit, mentre per sistemi a 32 bit abbiamo solamente bisogno di PDE e PTE.
Shadow Page Tables
The guest OS maintains its own page tables (GVA → GPA), but these mappings are not valid for the real hardware, because the guest doesn’t control the real memory. So, the hypervisor (VMM) constructs shadow page tables that translate directly from GVA → HPA, meaning they map guest virtual pages to host physical directly, while the guest thinks his pages map guest virtual to physical.

Implementation: The hypervisor must track whenever the guest OS modifies its page tables. This is usually done by:
- Marking guest page table pages as read-only.
- Catching page faults when the guest tries to write to them.
- Emulating the write in software to keep track of changes.
When the guest changes its page tables (e.g., context switch, mapping change), the hypervisor:
- Invalidates parts of the shadow page table.
- Rebuilds or updates entries as needed (called shadow page table synchronization).
Svantaggi:
- Esiste molto overhead di memoria e tempo per quanto riguarda questa parte.
- TLB flushes rende molto overhead da sta 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, però necessita di supporto hardware all’operazione, questa è la soluzione preferita in ambienti cloud.

Multi-Level Translation
Questa nota è di particolare interesse perché se abbiamo un TLB miss in virtualizzazione, dobbiamo andare a recuperare le informazioni da EPT e prende molti molti accessi in più.
HugePages
This is an idea that attempts to solve the problem in virtualization that we raised above. With bigger virtual pages it is more difficult to have a TLB miss (hugepage is 2MB, while gigantic pages are 1GB). The idea is that here big part of the memory is mapped to the physical address, which means we don’t have to translate it, having thus fewer walks when we have TLB miss.
The drawback with this solution is that Internal fragmentation (wasted memory) is much higher, and the system becomes slow for small dynamic allocations.
Virtualizzazione di I/O
Esistono moltissimi dispositivi I/O, che rendono la possibilità di virtualizzare un po’ difficile. Scrivere drivers a livello I/O non è poi tanto pratico.
Problemi di virtualizzazione I/O
Il dispositivo I/O virtuale deve essere in grado di: Virtual device interface
- Traps device commands
- Translates DMA operations
- Injects virtual interrupts
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.

Image taken from the paper (Firestone et al. 2018)
References
[1] Hofstadter “I Am a Strange Loop” Basic Books 2007
[2] Firestone et al. “Azure Accelerated Networking: SmartNICs in the Public Cloud” 2018
[3] Silberschatz et al. “Operating System Concepts” Wiley 2018