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

por xaizos