Dentro dos sistemas Linux proporcionase a funcionalidade da virtualización, que permite a unha máquina que executa un sistema (neste caso openSUSE) ou host, executar múltiples máquinas virtuais (VMs), tamén coñecidas como guests. As VMs empregan o hardware físico e os recursos informáticos do host para executar un sistema operativo virtualizado independente (guest OS) como un proceso de espazo de usuario nun sistema operativo do host. En outras palabras, a virtualización permite ter sistemas operativos dentro dos sistemas operativos. As máquinas virtuais permiten probar con seguridade configuracións e funcións de software, executar software heredado ou optimizar a eficiencia da carga de traballo do hardware.
A GPUs e vGPUs son aceleradores para tipos específicos de cargas de traballo gráficas ou de computación. Algunhas GPU poden conectarse directamente a unha máquina virtual, mentres que algúns tipos tamén ofrecen a posibilidade de crear GPU virtuais (vGPU) que comparten o hardware físico subxacente.
O que se explica na seguinte entrada é como empregar a función vGPU do hardware que permite dividir un dispositivo físico en varios dispositivos virtuais, denominados mediated devices
. Estes dispositivos mediados poden asignarse entón a múltiples máquinas virtuais como GPUs virtuais. Como resultado, estas VMs poden compartir o rendemento dunha única GPU física. Hai que ter en conta que a asignación dunha GPU física ás máquinas virtuais, con ou sen uso de dispositivos mediados, fai que o host non poida empregar a GPU. Concretamente imos asignar una tarxeta de video adicada a un sistemas Windows como invitado dentro dun sistema operacivo Linux (openSUSE) como host.
Requisitos:
- Necesitarás polo menos dúas tarxetas de video – unha empregada polo host de Linux e a outra adicada á máquina virtual que correrá con Windows.
- Non podes empregar unha GPU integrada de Intel para a máquina virtual, só poderás empregar AMD ou NVIDIA. Poderás empregar unha GPU integrada de Intel para o host.
- Necesitarás unha CPU e unha placa base que soporten VT-D (Intel) ou AMD-Vi (AMD) e ditas funcións deberán estar activas na BIOS da túa placa base.
- O porto PCI root non poderá ser parte do mesmo grupo IOMMU que a GPU que queres empregar para empregar na máquina virtual (iso verase máis adiante).
- Unha segunda pantalla ou calquera dispositivo que vai será empregada pola máquina virtual.
Instalando o software
Dentro de openSUSE hai que instalar unha serie de paquetes para poder construír a máquina virtual:
zypper in libvirt libvirt-client libvirt-daemon virt-manager virt-install virt-viewer qemu qemu-kvm qemu-ovmf-x86_64 qemu-tools
Activando IOMMU
IOMMU é o nome xenérico para Intel VT-x/Intel e AMD AMD-V/AMD-Vi. Necesitas activalo introducindo nas opcións do cargador do núcleo de linux o seguinte: intel_iommu=on (para Intel CPUs) ou amd_iommu=on (para AMD CPUs). Para facer isto, edita o arquivo /etc/default/grub e engade a liña intel_iommu=on ou amd_iommu=on ás opcións de GRUB_CMDLINE_LINUX_DEFAULT options. Salva o arquivo e rexerenera o grub:
grub2-mkconfig -o /boot/grub2/grub.cfg
Reinicia e executa:
dmesg|grep -e DMAR -e IOMMU
Neste momento debe aparecer unha mensaxe do núcle que pon de manifesta que IOMMU está activa no teu núcleo.
Asegúrate de que o grupo de traballo IOMMU é válido
Executa o seguinte guión de comandos (que nomeamos como lsiommu):
#!/bin/bash shopt -s nullglob for d in /sys/kernel/iommu_groups/*/devices/*; do n=${d#*/iommu_groups/*}; n=${n%%/*} printf 'IOMMU Group %s ' "$n" lspci -nns "${d##/*}" done;
Aquí podes atopar dúas cousas: que grupo IOMMU de dispositivos queres empregar para a máquina virtual (no meu caso, grupo 15) e o seu identificador de provedor/modelo (no meu caso, 10de:0fb9 e 10de:1c81).
Illamento GPU
Necesitamos illar a GPU. Isto é sinxelo se temos dúas GPU’s de diferentes provedores, e un pouco máis complicado se son do mesmo. Tamén é un pouco máis complicado, ser ademais do mesmo provedor son o mesmo modelo. Esta guía está pensada para que as dúas GPUs non sexan exactamente o mesmo modelo, e non funcionará se son de dús GPUs idénticas.
Primeiro, creamos un ficheiro denominado /etc/modprobe.d/gpu-passthrough.conf que editamos e no que insertamos o seguinte código:
options vfio-pci ids=identificador_GPU[,identificador_audio_GPU]
No meu caso particular:
options vfio-pci ids=10de:1c81,10de:0fb9
Anota os identificadores. Edita outra vez /etc/default/grub e engade rd.driver.pre=vfio-pci ás opcións de GRUB_CMDLINE_LINUX_DEFAULT. Salva o arquivo e rexenera grub.
grub2-mkconfig -o /boot/grub2/grub.cfg
Reconstruíndo initrd
Necesitas reconstruír o disco inicial da ram para incluír todos os módulos que imos necesitar. Crea un arquivo que denominaremos /etc/dracut.conf.d/gpu-passthrough.conf e inserta a seguinte liña nel:
add_drivers+="vfio vfio_iommu_type1 vfio_pci vfio_virqfd kvm kvm_intel"
Reconstrúe agora o initrd executando:
dracut --force /boot/initrd $(uname -r)
Por favor presta atención ás mensaxes, porque se algo non funciona podo provocar que o sistema Linux non volva arrancar.
Reinicia e verifica que a GPU está illada
Despois de reconstruír o initrd, verifica que a GPU foi illada. Executa lspci -k e observa qué controladores do núcleo se atopan en uso. Para unha GPU que se atope illada (para emprgar na VM) o seu estado deberá ser vfio-pci. Por exemplo:
0b:00.0 VGA compatible controller: NVIDIA Corporation GP107 [GeForce GTX 1050] (rev a1)
Subsystem: ASUSTeK Computer Inc. Device 861b
Kernel driver in use: vfio-pci
Kernel modules: nouveau
0b:00.1 Audio device: NVIDIA Corporation GP107GL High Definition Audio Controller (rev a1)
Subsystem: ASUSTeK Computer Inc. Device 861b
Kernel driver in use: vfio-pci
Kernel modules: snd_hda_intel
Definir unha máquina virtual
Primeiro, abre o arquivo /etc/libvirt/qemu.conf, atopa a opción nvram e editala do seguointe xeito:
nvram = [ "/usr/share/qemu/ovmf-x86_64.bin:/usr/share/qemu/ovmf-x86_64-code.bin" ]
Reinicia o proceso libvirt:
systemctl restart libvirtd
Comeza a instalar unha máquina virtual detro de KVM. Selecciona «Local install media» e «x86_64» como opcións da arquitectura. Selecciona o instalador para windows, acantidade de memoria que vai empregar, así como os procesadores que lle son asignados. xera unha imaxe para o disco físico. Nomea a túa máquina virtual e lembra marcar a opción de «Customize configuration before install» e marca «Finish».
Agora saltas á configuración da túa máquina virtual. Selecciona o firmware UEFI e o chipset i440FX. Dentro das posibles opcións teño activada «ovmf-x86_64-4m-code.bin«. No procesador colle a opción de «host-passthrough». En engadir hardware, cambia a configuración do disco a SCSI. Engade a túa GPU illada, no meu caso unha tarxeta gráfica. É recomendable que teñas tamén unha rato e un teclado a maiores para poder traballar coa túa máquina virual de xeito independente do host. Comeza a instralación do sistema Windows.
Sistema Windows instalado
Despois da instalación, deberás cambiar algunha cousas dentro da configuración do arquivo da máquina virtual. Para elo debes editar o XML de configuración. No meu caso a máquina virtual chámase microsoftwindows10:
virsh edit microsoftwindows10
Dentro de «features» terás que eliminar toda etiqueta <hyperv> e introducir o código seguinte deixando a sección como segue:
<features> <acpi> </acpi> <kvm> <hidden state='on'/> </kvm> <vmport state='off'/> </features>
Ás veces á máquina virtual non recoñece correctamente a tarxeta gráfica. Para solucionalo, dentro da sección «clock» elimina a liña:
<timer name='hypervclock' present='yes'/>
Con isto deberías ter montada unha máquina virtual con Windows tendo unha tarxeta gráfica dedicada. No proceso tamén se pode incluír a tarxeta gráfica, pero no meu caso optei por engadir unha tarxeta de son USB, dado que a PCI daba problemas de rendemento e velocidade, que ao anulala, desapareceron.
Sistema Windows XP
Para a instalación dun sistema Windows XP hai que ter en conta que é preciso ter os controladores da tarxeta gŕafica correcta para poder instalar no sistema windows. Partindo deste requisito, hai que editar o arquivo de configuración da máquina virtual onde teñas instalado os sistema invitado e modificar o XML, ademais das anteriores liñas, as seguintes:
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
<qemu:commandline>
<qemu:arg value='-set'/>
<qemu:arg value='device.hostdev0.x-vga=on'/>
</qemu:commandline>
FONTES de información
- https://forums.opensuse.org/showthread.php/522015-VGA-PCI-Passthrough-guide-on-openSuSE-Leap-42-2
- https://www.heiko-sieger.info/running-windows-10-on-linux-using-kvm-with-vga-passthrough/
- https://medium.com/jmtorres/iommu-virtualizando-windows-10-9afb7c01c358
- https://gist.github.com/jb-alvarado/d6aef18ddb965939442838d7310c5b31
- https://www.youtube.com/watch?v=roDayhayu08
- http://vfio.blogspot.com/2016/09/passing-qemu-command-line-options.html
- https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#Video_card_driver_virtualisation_detection