diff options
Diffstat (limited to '')
-rw-r--r-- | doc/pcie_passthrough.tex | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/doc/pcie_passthrough.tex b/doc/pcie_passthrough.tex new file mode 100644 index 0000000..1528593 --- /dev/null +++ b/doc/pcie_passthrough.tex @@ -0,0 +1,233 @@ +\documentclass[a4paper,10pt]{article} + +\usepackage[outer=2cm,inner=2cm]{geometry} +\usepackage[hidelinks]{hyperref} +\usepackage{framed} +\usepackage{lmodern} + +\usepackage{fontspec} +\usepackage{ragged2e} +\setmainfont{Latin Modern Mono} + +\title{PCIe GPU passthrough on Debian} +\author{Nao Pross} + +\begin{document}\tt + \maketitle + + \section{Introduzione} + Recentemente grazie all'evoluzione delle tecnologie di virtualizzazione \`e + diventato possibile passare direttamente un dispositivo collegato in uno + slot PCI ad una macchina virtuale, che può quindi usufruire dell'hardware a + performance quasi nativa. Un computer configurato per funzionare in tale + maniera apparirà come se fossero due computer distinti con due monitors (o + ad uno con un kvm switch). Il vantaggio di un setup del genere è la + possibilità di cambiare immediatamente da un sistema operativo all’altro + senza dover attendere che ma macchina si riavvii (in un dualboot) e si + evitano potenziali problemi come Windows Update che rendono il PC inusabile. + + \section{Limitazioni} + Come ogni sistema si ha delle limitazioni quali + \begin{itemize} + \item Per poter vedere l'uscita video della VM si deve collegare un + display ad una delle uscite della scheda grafica passata + \item Non \`e possibile passare la iGPU ad una VM (\`e possibile ma con + altre tecnologie ancora sperimentali) + \item Non \`e possibile passare una GPU discreta di un laptop (es NVIDIA + Optimus) poich\`e non \`e possibile visualizzare il video in uscita + \end{itemize} + + \section{Funzionamento (In grandi linee)} + Le macchine virtuali vengono emulate grazie ad un software chiamato QEMU che + supporta il passaggio di hardware PCI alla VM, inoltre QEMU utilizza un + estensione chiamata KVM che permette di creare delle macchine virtuali + collegate alla kernel dunque ottimizzate. Altrimenti QEMU dovrebbe emulare + l’intero processore su cui viene virtualizzato il sistema operativo. Infine + per gestire questi due componenti LibVirt è un software che salva le + configurazioni di QEMU in dei file XML e che permette alle VM di essere + tenute accese in background. \\ + + Passando una scheda video in PCI ad una macchina virtuale permette di + utilizzare la potenza grafica hardware che sarebbe altrimenti emulata (le + grafichce virtuali di QEMU non sono per niente ottimizzate, per tali scopi è + meglio utilizzare VirtualBox o VMWare Fusion). Quindi per poter vedere la + grafica della macchina virtuale si deve collegare un monitor ad una delle + entrate della scheda video. + + \section{Hardware Requirements} + \begin{itemize} + \item Intel processor with iGPU (or 2 GPUs) + \item Processor with VT-x and VT-d + \item NVIDIA or AMD graphics card (2 if with no iGPU) + \item Motherboard with VT-d support + \item Motherboard with UEFI based bootloader + \item Motherboard with IOMMU support (per configurazioni avanzate) + \end{itemize} + + \section{Software Requirements} + \begin{itemize} + \item Linux Kernel with iommu\_groups support ( kernel >= 3.9 ) + \end{itemize} + + \section{Hardware utilizzato} + Per questo questo test ho usato una configurazione hardware esagerata, anche + con un sistema decisamente meno costoso \`e possibile realizzare il + progetto. + \begin{itemize} + \item ASUS Z170-A motherboard + \item Intel Core i7 Skylake 6700 CPU with Intel Graphics 530 + \item MSI NVIDIA GTX1050Ti OC 4GB + \item 32GB DDR4 + \end{itemize} + + \section{BIOS Settings} + Per incominciare è necessario controllare che nel BIOS siano attivate le + tecnologie di virtualizzazione VT-x e VT-d. Inoltre se si vuole utilizzare + la iGPU in alcune motherboard (come nel mio caso) si deve modificare un + impostazione nel bios per non disattivarla qundo viene inserita una scheda + grafica secondaria. + + \section{Sistema Operativo} + Per avere un sistema stabile consiglio di utilizzare Debian Linux poiché + essendo utilizzato soprattuto nei servers il ciclo di testing e updates è + molto lento in modo da avere sempre un supporto legacy e un sistema stabile. + Purtroppo però attualmente (12.2016) Debian 8 Jessie ha ancora la kernel + 3.16 quindi si deve abilitare il supporto backport per poter installare una + versione aggiornata della kernel. \\ + + Prima di installare il sistema operativo è consigliato rimuovere la GPU che + si utilizzerà per il passthrough dallo slot PCI per evitare che Linux si + autoconfiguri per utilizzare i suoi driver grafici. Una volta installato il + sistema si devono installare i seguenti pacchetti: + \begin{framed}\raggedright + \% sudo apt-get install \textbackslash \\ + ~ qemu-kvm libvirt-bin virtinst bridge-utils virt-manager ssh-askpass ovmf + \end{framed} + + \section{Kernel Modules and GRUB} + Normalmente Debian viene con GRUB2 preinstallato come bootloader, se si + dovesse avere un altro bootloader si deve semplicemente passare gli stessi + parametri alla kernel quando si avvia. \\ + + Dalla kernel 3.9 Linux ha introdotto gli iommu\_groups che permettono di + mappare dispositivi di memoria reale ad indirizzi virtuali che possono + essere a loro volta passati alla VM. Per poter utilizzare questa + funzionalit\`a la si deve abilitare inoltre \`e necessario anche il supporto + degli ACS per poter suddividere i sottocomponenti del gruppo iommu (per + esempio le porte individuali di un estensione di USB via PCI). Per attivare + le funzionalit\`a si deve passare alla kernel i seguenti parametri: + \begin{framed}\raggedright \footnotesize + \# file: /etc/default/grub \\ + ... \\ + GRUB\_DEFAULT\_CMDLINE\_LINUX\_DEFAULT="intel\_iommu=on iommu=1 pcie\_acs\_override=downstream" \\ + ... + \end{framed} + Per aggiornale le impostazioni installate + \begin{framed}\raggedright + \% sudo update-grub + \end{framed} + + \section{GPU Settings} + Per evitare che Debian utilizzi la GPU all’avvio si deve modificare le + impostazioni dell’initramfs in maniera tale che il modulo della kernel non + venga avviato. Per sapere il nome del modulo della kernel caricato per la + GPU si può usare il seguente comando (nel mio caso la scheda è una NVIDIA): + \begin{framed}\raggedright \scriptsize + \% lspci -nnk | grep -i -A2 nvidia \\ + 02:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] [10de:1c82] (rev a1) \\ + ~~~~~~~~Subsystem: Micro-Star International Co., Ltd. [MSI] GP107 [GeForce GTX 1050 Ti] [1462:8c96] \\ + ~~~~~~~~Kernel driver in use: nouveau \\ + -- \\ + 02:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:0fb9] (rev a1) \\ + ~~~~~~~~Subsystem: Micro-Star International Co., Ltd. [MSI] Device [1462:8c96] \\ + ~~~~~~~~Kernel driver in use: snd\_hda\_intel + \end{framed} + Nel file di configurazione + \begin{framed}\raggedright + \# file: /etc/modprobe.d/blacklist.conf \\ + ... \\ + blacklist nouveau + \end{framed} + Infine per aggiornare la configurazione + \begin{framed}\raggedright + \% sudo update-initramfs -u + \end{framed} + + \section{Driver binding} + Per passare un dispositivo ad una VM si deve indicare alla kernel di + utilizzare il modulo `vfio-pci', perci\`o \`e necessario inizializzare + questi dispositivi all'avvio. Per questo possiamo usare questo script preso + da \href{https://www.reddit.com/r/pcmasterrace/comments/3lno0t/gpu_passthrough_revisited_an_updated_guide_on_how/?ref=share&ref_source=link}{qui} + salvandolo come `/usr/local/bin/vfio-bind'. + \begin{framed}\raggedright + \# file: /usr/local/bin/vfio-bind + \begin{verbatim} +#!/bin/bash + +modprobe vfio-pci + +for dev in "$@"; do + vendor=$(cat /sys/bus/pci/devices/$dev/vendor) + device=$(cat /sys/bus/pci/devices/$dev/device) + if [ -e /sys/bus/pci/devices/$dev/driver ]; then + echo $dev > /sys/bus/pci/devices/$dev/driver/unbind + fi + echo $vendor $device > /sys/bus/pci/drivers/vfio-pci/new_id +done \end{verbatim} + \end{framed} + Attivando la flag per poterlo eseguire: + \begin{framed}\raggedright + \% sudo chmod +x /usr/local/bin/vfio-bind + \end{framed} + Con questo script possiamo collegare il driver per la virtualizzazione a + qualsiasi dispositivo PCI nella seguente maniera: + \begin{framed}\raggedright + \% sudo vfio-bind <indirizzi pci> + \end{framed} + Per trovare l'indizirro dei dispositivi che vogliamo passare utilizziamo di + nuovo il seguente comando: + \begin{framed}\raggedright \scriptsize + \% lspci -nnk | grep -i -A2 nvidia \\ + 02:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] [10de:1c82] (rev a1) \\ + ~~~~~~~~Subsystem: Micro-Star International Co., Ltd. [MSI] GP107 [GeForce GTX 1050 Ti] [1462:8c96] \\ + ~~~~~~~~Kernel driver in use: nouveau \\ + -- \\ + 02:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:0fb9] (rev a1) \\ + ~~~~~~~~Subsystem: Micro-Star International Co., Ltd. [MSI] Device [1462:8c96] \\ + ~~~~~~~~Kernel driver in use: snd\_hda\_intel + \end{framed} + Nel mio caso gli indirizzi da passare alla VM sono `0000:02:00.0' per il + video e `0000:02:00.1' per l'audio. Successivamente possiamo automatizzare + la configurazione in modo che il driver per la virtualizzazione venga + avviato subito all'avvio della macchina. Quindi lo facciamo con una unit di + SystemD. + \begin{framed}\raggedright + \# file: /etc/systemd/system/vfio-pci-bind.service + + \begin{verbatim} +[Unit] +Description=Bind PCI devices to the virtio driver + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/vfio-bind 0000:02:00.0 0000:02:00.1 + +[Install] +WantedBy=multi-user.target +Before=libvirt-guests.service \end{verbatim} + \end{framed} + + \section*{Appendici} + \subsection*{i915 Skylake iGPU support} \label{skylakeigpu} + Attualmente (12.2016) i driver grafici per i nuovi processori intel di + architettura skylake sono disponibili e relativamente stabili dalle kernel + 4.7+, quindi nella mia installazione di debian ho deciso di utilizzare il + backport della kernel 4.8.0. Per abilitare i backports si deve aggiungere + un nuovo repo nel file `/etc/apt/sources.list'. + \begin{framed}\raggedright + \# file: /etc/apt/sources.list \\ + deb http://ftp.debian.org/debian jessie-backports main non-free + \end{framed} + Successivamente si deve aggiornare la kernel e i driver grafici mesa + +\end{document} |