Normalmente una macchina virtuale vede solo dispositivi emulati: una scheda di rete virtuale, un controller dischi virtuale, una scheda grafica semplicissima. Per molti usi basta, ma ci sono casi in cui serve l'accesso diretto all'hardware reale: una scheda video per la transcodifica o il calcolo, un controller dischi da dare a un sistema di storage, una scheda di rete ad alte prestazioni. Qui entra in gioco il passthrough PCIe.
L'idea di fondo
Con il passthrough, un dispositivo PCIe fisico viene staccato dall'host e consegnato in modo esclusivo a una macchina virtuale. Il sistema ospite lo vede come se fosse montato su una scheda madre vera, carica i propri driver e lo usa con prestazioni vicine a quelle native.
Il problema da risolvere è la memoria. I dispositivi PCIe leggono e scrivono direttamente nella RAM tramite DMA (Direct Memory Access). Se un dispositivo assegnato a una macchina virtuale potesse scrivere ovunque, potrebbe corrompere la memoria dell'host o di altre macchine. Serve quindi un componente che traduca e limiti gli accessi: l'IOMMU.
L'IOMMU
L'IOMMU è per i dispositivi ciò che l'unità di gestione della memoria è per i processi: traduce gli indirizzi usati dal dispositivo in indirizzi fisici e blocca gli accessi non autorizzati. Su piattaforme Intel si chiama VT-d, su AMD AMD-Vi.
Requisiti:
- processore con supporto IOMMU;
- scheda madre e firmware che lo espongano correttamente;
- opzione attivata nel BIOS o UEFI;
- supporto abilitato nel kernel dell'host.
Su molte distribuzioni recenti l'IOMMU di AMD è attivo per impostazione predefinita, mentre su Intel può essere necessario aggiungere intel_iommu=on ai parametri di avvio del kernel. Spesso si aggiunge anche iommu=pt, che applica la traduzione solo ai dispositivi assegnati alle macchine virtuali.
I gruppi IOMMU
Il concetto che più spesso blocca chi prova il passthrough è quello dei gruppi IOMMU. L'hardware non sempre riesce a isolare ogni dispositivo dagli altri: alcuni dispositivi, collegati dietro lo stesso bridge PCIe, possono comunicare tra loro senza passare dall'IOMMU. Il kernel li raggruppa, e un gruppo può essere assegnato solo per intero.
Per vedere i gruppi su Linux si può usare un piccolo script:
for g in /sys/kernel/iommu_groups/*; do
echo "Gruppo ${g##*/}:"
for d in $g/devices/*; do lspci -nns ${d##*/}; done
done
Se la scheda video si trova da sola nel proprio gruppo, o insieme solo alla sua componente audio, il passthrough è semplice. Se condivide il gruppo con il controller USB o di rete dell'host, i problemi aumentano. Piattaforme workstation e server tendono ad avere gruppi più puliti delle schede madri di consumo, e anche lo slot scelto conta: gli slot collegati direttamente al processore sono di solito meglio isolati di quelli che passano dal chipset.
Esiste una patch del kernel, chiamata ACS override, che forza la separazione dei gruppi. Funziona, ma lo fa ignorando l'isolamento che l'hardware non garantisce: riduce la sicurezza ed è adatta solo a laboratori dove questo rischio è accettato consapevolmente.
VFIO: staccare il dispositivo dall'host
Il driver che permette di consegnare un dispositivo a una macchina virtuale si chiama vfio-pci. Perché funzioni, il dispositivo non deve essere già in uso da un driver dell'host. La procedura tipica:
- individuare gli identificativi del dispositivo con
lspci -nn(per esempio10de:xxxx); - indicare al modulo vfio-pci di prendere quegli identificativi all'avvio;
- se necessario, impedire al driver normale dell'host di caricarsi per primo;
- rigenerare l'initramfs e riavviare;
- verificare con
lspci -kche il driver in uso siavfio-pci.
A quel punto si aggiunge il dispositivo alla configurazione della macchina virtuale, preferibilmente con tipo di macchina q35 e firmware UEFI.
Casi d'uso tipici
Controller dischi per un sistema di storage
Assegnare un controller SATA o SAS (spesso chiamato HBA) a una macchina virtuale che gestisce lo storage permette al sistema ospite di vedere i dischi direttamente, con accesso ai dati SMART e senza strati intermedi. È il modo consigliato quando si virtualizza un sistema NAS che usa ZFS.
Scheda video
Una GPU dedicata in passthrough serve per transcodifica, calcolo o desktop virtuali con accelerazione. Alcune schede richiedono attenzioni particolari, come l'estrazione del firmware video o il problema del reset: certe GPU non si reinizializzano correttamente quando la macchina virtuale viene riavviata, e richiedono il riavvio dell'intero host.
Scheda di rete
Una scheda di rete in passthrough a un firewall virtuale offre prestazioni piene. Alcune schede supportano SR-IOV, che divide un unico dispositivo fisico in più funzioni virtuali assegnabili a macchine diverse.
I limiti da accettare
- Il dispositivo è esclusivo: l'host e le altre macchine virtuali non possono usarlo.
- La migrazione a caldo della macchina virtuale verso un altro nodo non è possibile.
- Gli snapshot con memoria possono non funzionare.
- Se si assegna l'unica scheda video, l'host resta senza console locale: la gestione remota diventa indispensabile.
In sintesi
- Il passthrough consegna un dispositivo PCIe reale a una macchina virtuale con prestazioni quasi native.
- Serve l'IOMMU (VT-d o AMD-Vi), attivo nel firmware e nel kernel.
- I gruppi IOMMU si assegnano per intero: piattaforme e slot ben isolati semplificano tutto.
- Il driver vfio-pci deve prendere il dispositivo prima del driver normale dell'host.
- Il dispositivo diventa esclusivo e la macchina virtuale perde la migrazione a caldo.