Proxmox Passthrough

   La virtualización hoy en día es indispensable en la mayoría (por no decir todas) las empresas de TI o que alojan un sistema propio, una de las principales ventajas es la de correr múltiples máquinas virtuales y contenedores dentro de un mismo equipo. No es simplemente virtualizar un SO como VMWare Workstation o VirtualBox, es utilizar todo un sistema dedicado a la virtualización y aunque pudiéramos utilizar debian con docker, ya existen soluciones especializadas a esto, las más famosas son:


   De todas estas soluciones mi favorita es Proxmox, ya que no es solo una distro basada en debian con KVM, sino que extienden la funcionalidad para facilitar la configuración y muchas otras cosas como VLAN y VirtIO... Aunque esto no es programación como tal es interesante la idea de utilizar un entorno virtualizado con acceso a dispositivos de forma física o incluso 1 PC para múltiples usuarios de forma independiente.

   La razón de esta entrada es porque actualmente me veo en la necesidad de utilizar una tarjeta gráfica para un software en concreto corriendo de forma simultanea debian y otros contenedores para múltiples pruebas, por lo que esto te puede servir si:

  • Necesitas máquinas virtuales que interactúen de forma directa con el Hardware
  • Requieres de un sistema completo que funcione de forma independiente al principal
  • Quieres tener un sistema operativo para juegos sin tener un Dual Boot (si, aunque no es el caso sabemos que muchos lo hacen con este fin)

   No es necesario si:

  • Utilizas contenedores simples
  • Tus máquinas virtuales no necesitan acceso a una tarjeta PCI o Hardware específico
  • No necesitas ningún tipo de aceleración gráfica por parte de la GPU

   Sabiendo esto, lo primero que debemos saber es que pasar directamente los periféricos USB en proxmox es cosa sencilla, la misma interfaz nos permite realizar esto:


   Ahora, si queremos hacer lo mismo con una tarjeta PCI debemos seguir los pasos indicados aquí: PCI Passthrough. Sin embargo, no es tan simple como se lee, así que vamos a los pasos.

   Lo primero es tener un hardware compatible, normalmente todos los Xeon y procesadores de gama alta de Intel son compatibles, en el caso de AMD no todos lo hacen de forma correcta, por lo que aconsejo revisar la compatibilidad antes de continuar.

   Una vez seguros de que nuestro hardware funcionará sin problemas, vamos a configurar el BIOS, debemos habilitar en nuestra tarjeta madre (MOBO) las opciones de virtualización (VT-d/VT-x en Intel y AMD-V en AMD), luego creamos nuestra máquina, pero aquí es donde viene el detalle que la documentación no explica...

   Si vamos a utilizar una PCI de forma básica (audio, red, serial, paralelo, etc) podemos utilizar SeaBIOS (legacy), sin embargo, esto se nos complica al utilizar una tarjeta PCIe y sobre todo con las tarjetas de video, es por eso que en estos casos utilizaremos OVMF (UEFI) y la controladora de discos SCSI:


   De aquí en adelante los pasos son básicos para cualquier SO, sin embargo me enfocaré en Windows (específicamente 10) ya que es el más utilizado en estos casos, utilizando un procesador Intel. Para continuar con la creación, necesitamos enfocarnos en los drivers VirtIO para Windows, por lo que vamos a la web de Fedora para descargarlos: Windows VirtIO Drivers

   Buscamos el ISO (Stable virtio-win iso), una vez descargados nos aseguramos de montarlo en un disco virtual aparte:


   Pudiéramos utilizar también el driver de red (paravirtualized) pero esta demostrado que en las ediciones de Windows que no sean Server tienden a tener problemas de rendimiento, por lo que utilizar E1000 vendrá bien.

   Al momento de llegar a la selección de discos veremos que no aparece en el listado, es porque Windows no posee estos drivers VirtIO, por lo que vamos a cargar controladores extra (abajo a la izquierda) y seleccionamos el que sea adecuado para nuestra versión dentro de la carpeta "stor" (Win10 x86/x64). Una vez cargados podremos seleccionar el disco y continuar la instalación.

   Ahora apagamos la máquina y nos vamos al shell de nuestro nodo proxmox a modificar el GRUB para darle soporte a nuestra tarjeta PCI / PCIe:
nano /etc/default/grub
   Dentro agregamos buscamos la línea GRUB_CMDLINE_LINUX_DEFAULT y la modificamos de la siguiente forma:
GRUB_CMDLINE_LINUX_DEFAULT="rootdelay=10 quiet intel_iommu=on kvm=off video=efifb:off"
   Actualizamos el GRUB:
update-grub
   Ahora reiniciamos y verificamos que todo ha salido bien con el comando dmesg | grep -e DMAR -e IOMMU, si no vemos salida entonces puede que el procesador no soporte iommu o que no este habilitada la opción VT-d en el BIOS.

   Lo siguiente es ubicar la dirección física (a nivel lógico) de nuestra tarjeta, por lo que un simple lspci bastará, una vez hecho esto debemos ver una salida como la siguiente:


   En mi caso la tarjeta esta ubicada en el slot 1, por lo que los dispositivos de destino son el 01:00.0 (Video) y el 01:00.1 (Audio HDMI). Hasta este punto basta con agregar el dispositivo a la conf de la máquina virtual (/etc/pve/qemu-server/vmid.conf) y tendremos nuestra tarjeta funcionando:
hostpci0: 01:00
   Pero esto no nos funcionará si queremos usar nuestra tarjeta de video con aceleración 3D, ya que necesitaremos un par de configuraciones más, por lo que vamos a ubicar el VendorID de nuestra tarjeta con el comando lspci -n -s 01:00:


   Ya que hemos ubicado todo lo necesario comencemos por agregar nuestro Vendor en los módulos y agregar a la lista negra del sistema principal los drivers, esto con el fin de que el sistema principal no utilice la tarjeta de video de modo que sea dedicada a la VM:
echo "options vfio-pci ids=10de:128b,10de:0e0f  disable_vga=1" > /etc/modprobe.d/vfio.conf
echo "blacklist radeon" >> /etc/modprobe.d/blacklist.conf
echo "blacklist nouveau" >> /etc/modprobe.d/blacklist.conf
echo "blacklist nvidia" >> /etc/modprobe.d/blacklist.conf  
   Mucha atención con los IDs, deben ser los de nuestra tarjeta y ningún otro. Ahora si vamos a editar la conf de la VM de la siguiente forma:

   Lo que hicimos es agregar nuestros dispositivos (hostpciX) a la lista, también especificamos el tipo de máquina a Q35 para utilizar el chipset ICH9. Ya con esto solo nos resta asignar un teclado y mouse a nuestra VM como explicamos al inicio de la entrada, conectamos una salida a la VGA y ya podremos ver nuestro SO utilizando la VGA sin problemas, pero aún no terminamos.

   En este punto es cuando pueden salir mal las cosas, lo primero es utilizar GPU-z o dxdiag para ver si la info de nuestra tarjeta esta bien, si no vemos nVidia o AMD en el fabricante junto con los valores correctos debemos volcar una ROM, para ello vamos nuevamente al shell de nuestro nodo y ejecutamos lo siguiente:
cd /sys/bus/pci/devices/0000:01:00.0/
echo 1 > rom
cat rom > /tmp/image.rom
echo 0 > rom
   Recordando que 01:00.0 es mi tarjeta de video, ahora reiniciamos y volvemos a comprobar, si el problema persiste probemos lo siguiente:
echo "options kvm ignore_msrs=1" > /etc/modprobe.d/kvm.conf
   Ya con esto no deberíamos tener problemas de configuración, una vez confirmado que todo esta bien entonces instalamos el driver de video y listo. Ya podemos disfrutar de una máquina virtual corriendo una aceleración completa por parte del GPU y con audio HDMI sin problemas.
Ultimo

Lamentablemente hay muchos usuarios en la red que han llegado al blog para escribir obscenidades, así que la moderación se hace necesaria. Recuerda utilizar un lenguaje correcto y espera a que sea aprobado.

Si necesitas publicar código haz click en "Conversión" para hacerlo legible.
ConversiónConversión