Passthrough de GPU en Proxmox: pantalla negra, UEFI/OVMF, problemas de ROM, fallos de reinicio y soluciones comprobadas

¿Te fue útil?

Hiciste lo “simple”: pasaste una GPU a una VM. La VM arranca. El monitor permanece en negro. El invitado puede incluso estar vivo: RDP funciona, SSH funciona, pero la pantalla local está muerta como una TV de sala de reuniones con la entrada equivocada.

El passthrough de GPU en Proxmox no es difícil. Es solo implacable. Una elección de firmware equivocada, una suposición incorrecta sobre ROM/GOP, un matiz en el reseteo de la GPU, y obtienes el mismo síntoma: nada en la pantalla.

Playbook de diagnóstico rápido (revisa esto primero)

Esta es la secuencia “deja de dar vueltas”. Está optimizada para obtener la primera señal rápido y evita madrigueras como trastear con flags aleatorios de QEMU antes de confirmar lo básico.

1) Confirma si el invitado está vivo o muerto

  • Si Windows arranca y puedes conectarte por RDP: probablemente tienes un problema de inicialización de pantalla (firmware/ROM/primaria), no una falla total de passthrough.
  • Si la VM no arranca en absoluto: sospecha de IOMMU, enlace VFIO, o un problema de reseteo/congelación hard.

2) Comprueba que IOMMU esté realmente activado y que los grupos tengan sentido

Si IOMMU no está habilitado, no estás haciendo passthrough; estás haciendo una coreografía interpretativa.

3) Verifica que la GPU esté enlazada a vfio-pci en el host

Las pantallas negras ocurren con frecuencia cuando el controlador del host agarró la tarjeta primero, dejando a VFIO con sobras (o un dispositivo medio inicializado).

4) Alinea el firmware con los requisitos de la GPU: OVMF para tarjetas con GOP UEFI

Las GPUs modernas, especialmente si quieres que la GPU sea la pantalla primaria en el invitado, suelen comportarse mejor con OVMF + Q35.

5) Decide si necesitas un archivo ROM

Si la GPU nunca muestra salida hasta que carga el driver del invitado (o nunca muestra salida), puede que necesites proporcionar una ROM limpia con una sección GOP válida —o evitar que el host la publique.

6) Si funcionó una vez pero falla después de reiniciar la VM: asume un fallo de reseteo

El éxito en un solo arranque seguido de pantalla negra en arranques posteriores es territorio clásico de “la GPU no se reseteó”. Trátalo como tal hasta que se demuestre lo contrario.

Qué significa realmente una “pantalla negra” en passthrough

“Pantalla negra” es un síntoma vago. Necesitas precisar cuál de estos estás viendo:

  • Sin señal desde el monitor: la GPU nunca impulsa el conector (no se inicializó, primaria equivocada, o la GPU sigue siendo propiedad del host/firmware).
  • Señal pero imagen negra: el enlace está activo, pero no se está escaneando ningún framebuffer (desajuste driver/firmware, resolución incorrecta, invitado atascado antes del traspaso gráfico).
  • Muestra el splash de OVMF y luego negro: la inicialización del firmware tuvo éxito; el traspaso al SO/driver del invitado falla (conflictos de driver en Windows, Code 43, problemas de modesetting en Linux).
  • Funciona solo después de un arranque en frío: fallo de reseteo o problema de estado de energía (FLR ausente, transiciones D3cold, comportamiento de reseteo específico del proveedor).
  • Funciona solo con un dongle HDMI dummy: problemas de EDID/detección de monitor, especialmente en sesiones remotas o configuraciones sin pantalla física.

Una regla operativa: separa “asignación de dispositivo exitosa” de “éxito en salida de pantalla”. VFIO puede asignar una GPU perfectamente mientras el invitado nunca logra encender la pantalla.

Exactamente una cita, porque aplica aquí: la fiabilidad viene de operaciones disciplinadas y eliminar clases de falla, no de depurar como héroe a las 2 a.m. de James Hamilton (Amazon).

Hechos interesantes y contexto histórico (porque este lío tiene historia)

  1. El passthrough PCI precede a “passthrough de GPU en homelab” por décadas. Los hipervisores empresariales usaron asignación directa de dispositivos para NICs y HBAs mucho antes de que los gamers descubrieran VFIO.
  2. UEFI GOP cambió el juego de la pantalla en arranque temprano. Las ROMs VGA legadas eran suficientes en la era BIOS; el firmware UEFI prefiere una ROM con GOP para una inicialización gráfica limpia.
  3. OVMF es esencialmente UEFI para QEMU. Es el firmware de código abierto que hace prácticos los VMs UEFI en entornos KVM.
  4. IOMMU fue impulsado tanto por la seguridad DMA como por la virtualización. Sin remapeo DMA, un dispositivo puede escribir en memoria arbitraria. Passthrough sin IOMMU es una pesadilla de seguridad.
  5. ACS (Access Control Services) existe para aislar el tráfico PCIe. Las placas de consumo a menudo escatiman en ello, y por eso la gente recurre a ACS override y luego se sorprende cuando el aislamiento es imperfecto.
  6. “Reset” no es un único mecanismo. FLR, reset de bus, transiciones de estado de energía y resets específicos del proveedor se comportan de maneras diferentes.
  7. Algunas GPUs son dispositivos multifunción. La función de audio (HDMI/DP) y el controlador USB (en algunas tarjetas) deben pasarse juntos, o obtendrás comportamientos extraños.
  8. La historia de Code 43 de NVIDIA moldeó la cultura del passthrough. El comportamiento del driver en entornos virtualizados empujó a la gente a soluciones temporales y luego a configuraciones mejor soportadas.
  9. Resizable BAR cambió las expectativas. Los grandes mapeos BAR pueden estresar la configuración del firmware/host y a veces exponer fallos en la inicialización de la plataforma.

Broma 1: El passthrough de GPU es el único hobby donde “cambié una línea en GRUB y reinicié ocho veces” cuenta como una noche tranquila.

UEFI/OVMF vs SeaBIOS: elige lo que coincide con la realidad

Si recuerdas una cosa: no elijas SeaBIOS porque te parezca “más simple”. Elige el firmware según lo que la GPU y el SO invitado esperan.

Cuando OVMF es la opción correcta

  • Quieres Windows 11, Secure Boot activado/desactivado, o arranque UEFI moderno.
  • Quieres que la GPU pasada sea la pantalla primaria del invitado.
  • La ROM de la GPU es UEFI-first (común en tarjetas más nuevas).
  • Deseas un comportamiento más limpio con el tipo de máquina Q35 y la topología PCIe.

Cuando SeaBIOS aún puede funcionar

  • GPUs antiguas con ROMs VGA legacy robustas.
  • Instalaciones de sistemas invitados antiguas diseñadas para arranque por BIOS.
  • Casos concretos donde la inicialización GOP de UEFI es el problema y la inicialización legacy funciona.

Trampas comunes de OVMF que parecen “la GPU está rota”

  • Orden de dispositivos de pantalla incorrecto: si dejas un VGA virtual (como SPICE/QXL) y el invitado lo usa como primario, tu GPU pasada puede no mostrar nada hasta que carguen los drivers —o nunca.
  • Problemas con la tienda de variables de OVMF: un archivo NVRAM corrupto puede atraparte en estados de arranque extraños. Recréalo en lugar de negociar con él.
  • Expectativas CSM: los invitados solo UEFI pueden no arrancar desde discos formateados para BIOS; esto puede hacerse pasar por “sin salida de GPU”.

Archivos ROM, GOP y por qué a veces tu GPU “necesita una ROM”

Una ROM de GPU (option ROM) es el blob de firmware que inicializa la tarjeta durante el arranque temprano. En passthrough, QEMU puede intentar usar la ROM del dispositivo, pero varias cosas interfieren:

  • El firmware del host puede haber ya posteado la GPU, dejándola en un estado que el firmware del invitado no espera.
  • El dispositivo puede no exponer una región ROM legible una vez que el driver del host se enlaza a él.
  • Algunas ROMs de proveedor incluyen VGA legacy y GOP UEFI; otras incluyen una sola; otras son… “creativas”.

Cuando suministrar un archivo ROM es una solución comprobada

  • Pantalla negra al arrancar, pero la GPU funciona en otras máquinas o en bare metal.
  • OVMF nunca muestra su splash en la salida de la GPU.
  • La GPU no es la pantalla de arranque primaria y nunca se inicializa correctamente.
  • Configuraciones multi-GPU donde el host posteó una GPU y pasas la otra.

Cuando un archivo ROM empeora las cosas

  • Usas una ROM volcada de otro SKU o de una revisión del proveedor distinto.
  • La ROM contiene straps específicos de la placa que no coinciden con tu tarjeta exacta.
  • Recortas o “arreglas” la ROM incorrectamente (especialmente en tarjetas NVIDIA con cabeceras).

En términos de producción: un archivo ROM es una herramienta quirúrgica, no un amuleto de buena suerte. Si no tienes una razón, no introduzcas otra variable.

Fallos de reinicio PCIe: FLR, D3hot/D3cold y el lío de AMD

El reseteo es donde ocurren la mayoría de las historias de “ayer funcionó”. Una GPU puede pasarse limpiamente, usarse, y luego fallar al volver después de reiniciar el invitado o detener/iniciar la VM.

Tres patrones de reseteo que verás

  1. Sólo arranque en frío: la GPU funciona después de un ciclo completo de energía del host, no después de reiniciar la VM. Eso es una brecha de reseteo/inicialización.
  2. Contaminación por driver del host: el driver del host se enlaza una vez (aunque sea brevemente), inicializa la GPU, y luego VFIO entrega un dispositivo con configuración rara al invitado.
  3. Reseteo de función parcial: la función gráfica se resetea, pero la función de audio (o USB) no lo hace, causando enumeración o comportamientos extraños del driver.

FLR no está garantizado

Function Level Reset es opcional. Algunas GPUs lo anuncian, otras no lo implementan correctamente, y algunas plataformas no lo propagan bien. No puedes “creer” en FLR.

La realidad del “bug de reseteo” de AMD

Las tarjetas AMD más antiguas (y algunas no tan antiguas) son infames por fallar al reseteo a un estado limpio para la reutilización por VFIO. Las soluciones de la comunidad van desde módulos vendor-reset hasta alternar estados de energía; los resultados varían según la versión del kernel, generaciones de tarjeta y comportamiento de la placa base.

Broma 2: La forma más rápida de probar si tienes un bug de reseteo es reiniciar la VM: tu GPU inmediatamente pedirá el divorcio.

Enlace en el host, vfio-pci y la lucha de controladores

El host no debe “ayudar”. Si el host agarra la GPU con nvidia, amdgpu o nouveau antes de que VFIO lo haga, a menudo obtienes una pantalla negra, o peor: una GPU que funciona a medias y luego se bloquea.

Cómo se ve lo “correcto”

  • En el arranque, las funciones de la GPU están enlazadas a vfio-pci.
  • La consola del host usa otra GPU, iGPU o consola serial.
  • Proxmox inicia la VM, QEMU reclama el dispositivo PCIe, y el driver del invitado ve una GPU exclusiva y limpia.

Cómo se ve “casi correcto”

  • La GPU está enlazada a vfio-pci, pero el driver de framebuffer del host aún la tiene mapeada.
  • La función de audio HDMI aún está enlazada a snd_hda_intel.
  • Hay un grupo IOMMU con un controlador USB o SATA pegado a la GPU, y solo pasaste la GPU.

Q35 vs i440fx, GPU primaria y dispositivos de pantalla que te sabotean

En Proxmox, eliges un tipo de máquina. Trátalo como hardware.

Q35 suele ser la opción sensata por defecto

Q35 modela un chipset más moderno con puertos raíz PCIe. Eso importa para GPUs que esperan comportamiento PCIe, y puede influir en el reseteo y el orden de enumeración de dispositivos.

i440fx es compatibilidad legacy

A veces lo usas porque un invitado antiguo lo espera. Para passthrough de GPU moderno, Q35 tiende a reducir rarezas.

Passthrough de GPU primaria: elimina displays virtuales competidores

Si quieres que la GPU pasada sea la pantalla de arranque, no dejes un dispositivo VGA virtual como el primario evidente. En términos de Proxmox: configura vga: none si vas en serio con usar la GPU física para la salida de consola.

Tareas prácticas (comandos, qué significa la salida y qué decisión tomas)

Estas son tareas operativas reales. Ejecútalas en el host Proxmox salvo indicación contraria. Cada una incluye el “y ahora qué” porque la salida sin decisión es solo registrar por diversión.

Task 1: Confirma que la CPU y el kernel ven extensiones de virtualización

cr0x@server:~$ egrep -m1 '(vmx|svm)' /proc/cpuinfo
flags		: fpu vme de pse tsc ... vmx ...

Significado: vmx (Intel) o svm (AMD) deben existir. Si no existe, ningún viaje IOMMU/VFIO terminará bien.

Decisión: Si falta, arregla la configuración del BIOS (VT-x/AMD-V) antes de tocar las configuraciones de Proxmox.

Task 2: Confirma que IOMMU está habilitado en la línea de comandos del kernel

cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.8.12-2-pve root=/dev/mapper/pve-root ro quiet intel_iommu=on iommu=pt

Significado: Busca intel_iommu=on o amd_iommu=on. iommu=pt es común para reducir sobrecarga en dispositivos que no usan passthrough.

Decisión: Si falta, edita GRUB y reinicia; no sigas hasta que esté presente.

Task 3: Verifica que DMAR/IVRS muestre que IOMMU se inicializó

cr0x@server:~$ dmesg | egrep -i 'DMAR|IOMMU|IVRS' | head -n 8
[    0.824112] DMAR: IOMMU enabled
[    0.824980] DMAR: Host address width 39
[    0.835010] DMAR: DRHD base: 0x000000fed90000 flags: 0x0

Significado: Quieres “IOMMU enabled” y sin fallos fatales.

Decisión: Si ves mensajes de deshabilitado o fallos, arregla BIOS (VT-d/AMD-Vi) o parámetros del kernel antes de continuar.

Task 4: Identifica la GPU y todas sus funciones (gráficos + audio + extras)

cr0x@server:~$ lspci -nn | egrep -i 'vga|3d|audio|nvidia|amd'
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU116 [GeForce GTX 1660] [10de:2184]
01:00.1 Audio device [0403]: NVIDIA Corporation TU116 High Definition Audio Controller [10de:1aeb]

Significado: Anota los IDs de dispositivo y las funciones. La función de audio no es opcional en la práctica; pásala también.

Decisión: Planea pasar tanto 01:00.0 como 01:00.1.

Task 5: Comprueba los grupos IOMMU (la verdad del aislamiento)

cr0x@server:~$ for d in /sys/kernel/iommu_groups/*/devices/*; do echo "$(basename "$(dirname "$d")") $(lspci -nns ${d##*/})"; done | sort -n | sed -n '1,18p'
1 00:01.0 Host bridge [0600]: Intel Corporation Device [8086:1237]
12 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU116 [GeForce GTX 1660] [10de:2184]
12 01:00.1 Audio device [0403]: NVIDIA Corporation TU116 High Definition Audio Controller [10de:1aeb]

Significado: Las funciones de tu GPU idealmente deberían estar en un grupo por sí solas (o al menos solo entre ellas).

Decisión: Si el grupo incluye dispositivos no relacionados (USB/SATA), necesitas otra ranura/configuración de placa base, o aceptas el riesgo de ACS override (ver más adelante).

Task 6: Confirma qué driver posee actualmente la GPU

cr0x@server:~$ lspci -nnk -s 01:00.0
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU116 [GeForce GTX 1660] [10de:2184]
	Subsystem: Micro-Star International Co., Ltd. [MSI] TU116 [1462:12a3]
	Kernel driver in use: vfio-pci
	Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia

Significado: “Kernel driver in use” debe ser vfio-pci. Los módulos listados son solo disponibles, no necesariamente cargados.

Decisión: Si dice nvidia o amdgpu, arregla el enlace de drivers (Task 7/8).

Task 7: Carga los módulos VFIO y verifica que existan

cr0x@server:~$ lsmod | egrep 'vfio|kvm'
vfio_pci               16384  0
vfio_pci_core          90112  1 vfio_pci
vfio_iommu_type1       40960  0
vfio                   69632  2 vfio_iommu_type1,vfio_pci_core
kvm_intel             376832  0
kvm                  1105920  1 kvm_intel

Significado: Si los módulos VFIO no están cargados, Proxmox puede seguir cargándolos bajo demanda, pero explícito es mejor que místico.

Decisión: Si faltan, asegura que los módulos vfio estén en /etc/modules y reconstruye initramfs.

Task 8: Enlaza la GPU a vfio-pci usando IDs de dispositivo (método duradero)

cr0x@server:~$ cat /etc/modprobe.d/vfio.conf
options vfio-pci ids=10de:2184,10de:1aeb disable_vga=1

Significado: Esto le dice al kernel que enlace esos IDs PCI a VFIO temprano. disable_vga=1 puede ayudar a reducir dramas de arbitraje VGA legacy.

Decisión: Si cambias este archivo, reconstruye initramfs y reinicia (Task 9).

Task 9: Reconstruye initramfs y confirma que se actualizó

cr0x@server:~$ update-initramfs -u -k all
update-initramfs: Generating /boot/initrd.img-6.8.12-2-pve
Running hook script 'zz-proxmox-boot'..
Re-executing '/etc/kernel/postinst.d/zz-proxmox-boot' in new private mount namespace..

Significado: Tu entorno de arranque temprano ahora conoce las reglas de enlace VFIO.

Decisión: Reinicia antes de probar de nuevo; cambios en caliente no son un experimento fiable aquí.

Task 10: Comprueba si el host aún tiene un framebuffer en la GPU

cr0x@server:~$ dmesg | egrep -i 'fb0|framebuffer|efifb|simplefb|vesafb' | tail -n 8
[    0.612345] simple-framebuffer simple-framebuffer.0: framebuffer at 0xe0000000, 0x300000 bytes
[    0.612400] fb0: simplefb registered!

Significado: Si el host está usando la GPU pasada para una consola framebuffer, puedes obtener pantallas negras o reseteos que nunca funcionan del todo.

Decisión: Prefiere consola headless (serial), iGPU o una segunda GPU para el host. Si debes, deshabilita el uso de framebuffer por parte del host (específico de plataforma).

Task 11: Confirma que la configuración de la VM usa OVMF + Q35 y no roba la pantalla primaria

cr0x@server:~$ qm config 101
boot: order=scsi0;ide2;net0
bios: ovmf
machine: q35
scsi0: local-lvm:vm-101-disk-0,size=128G
hostpci0: 0000:01:00.0,pcie=1,x-vga=1
hostpci1: 0000:01:00.1,pcie=1
vga: none

Significado: bios: ovmf y machine: q35 son la combinación habitual “funciona más a menudo”. vga: none evita que Proxmox añada una pantalla competidora.

Decisión: Si ves bios: seabios y GPU/OS modernos, cambia a OVMF y reinstala o convierte el modo de arranque según sea necesario.

Task 12: Observa errores QEMU/VFIO durante el arranque de la VM

cr0x@server:~$ journalctl -u pvedaemon -u pve-qemu-server --since "10 min ago" | tail -n 60
... vfio-pci 0000:01:00.0: vfio_bar_restore: reset recovery - restoring BARs
... qemu-system-x86_64: vfio: Unable to power on device, stuck in D3
... start failed: QEMU exited with code 1

Significado: “stuck in D3” es un problema de estado de energía/reseteo. Esto no es un problema del driver de Windows; es comportamiento de reseteo del host/dispositivo.

Decisión: Trátalo como bug de reseteo: considera actualizar kernel, cambiar de ranura, deshabilitar ASPM, o enfoques vendor-reset (Task 16/17).

Task 13: Volcar la ROM de la GPU (solo si tienes una razón)

cr0x@server:~$ echo 1 | sudo tee /sys/bus/pci/devices/0000:01:00.0/rom
1
cr0x@server:~$ sudo cat /sys/bus/pci/devices/0000:01:00.0/rom > /root/gpu.rom
cr0x@server:~$ echo 0 | sudo tee /sys/bus/pci/devices/0000:01:00.0/rom
0
cr0x@server:~$ ls -lh /root/gpu.rom
-rw-r--r-- 1 root root 256K Jan  8 12:14 /root/gpu.rom

Significado: Obtuviste una imagen ROM de tamaño plausible. Si esto falla con “Operation not permitted” o bytes cero, el dispositivo puede estar enlazado/posteado de una forma que bloquea lecturas.

Decisión: Si puedes volcar, pruébalo como archivo ROM. Si no puedes, no fuerces—arregla enlace/posteo primero.

Task 14: Adjunta el archivo ROM a la VM (experimento dirigido)

cr0x@server:~$ qm set 101 --hostpci0 0000:01:00.0,pcie=1,x-vga=1,romfile=gpu.rom
update VM 101: -hostpci0 0000:01:00.0,pcie=1,x-vga=1,romfile=gpu.rom

Significado: Proxmox le pasará esa ROM a QEMU. La ROM debe existir bajo /usr/share/kvm/ o ser referenciada correctamente según expectativas de Proxmox; colócala correctamente antes de reiniciar la VM.

Decisión: Si esto arregla la salida en arranque temprano, mantenlo. Si rompe la inicialización del driver, quítalo y reevalúa (ROM equivocada o innecesaria).

Task 15: Comprueba consumidores “en uso” que bloquean el passthrough

cr0x@server:~$ fuser -v /dev/nvidia0 2>/dev/null || true
                     USER        PID ACCESS COMMAND
/dev/nvidia0:        root       1321 F....  nvidia-persistenced

Significado: Si nvidia-persistenced o un display manager está usando la GPU, la asignación VFIO se verá contaminada.

Decisión: Detén/deshabilita consumidores en el host. Hosts de passthrough no deberían ejecutar stacks de escritorio en la misma GPU que vas a pasar.

Task 16: Inspecciona capacidad de reseteo e indicios de gestión de energía

cr0x@server:~$ lspci -vv -s 01:00.0 | egrep -i 'LnkCap|LnkSta|ASPM|FLR|PM' | head -n 30
LnkCap:	Port #0, Speed 8GT/s, Width x16, ASPM L0s L1, Exit Latency L0s <1us, L1 <8us
LnkSta:	Speed 8GT/s, Width x16
Capabilities: [b0] MSI-X: Enable+ Count=32 Masked-
Capabilities: [d0] Power Management version 3
Kernel driver in use: vfio-pci

Significado: Buscas pistas: presencia de ASPM, versión de gestión de energía, y si la plataforma podría forzar estados de energía agresivos.

Decisión: Si ves errores repetidos relacionados con D3 en logs, considera deshabilitar ASPM en BIOS o parámetros del kernel como prueba.

Task 17: Detecta el bug “funciona una vez” usando un bucle controlado de reinicio

cr0x@server:~$ qm start 101
started VM 101
cr0x@server:~$ sleep 30
cr0x@server:~$ qm shutdown 101 --timeout 90
stopping VM 101 (shutdown)
cr0x@server:~$ qm start 101
started VM 101

Significado: Si el primer arranque da salida y el segundo arranque da pantalla negra, acabas de reproducir un bug de reseteo sin superstición.

Decisión: Pasa a mitigaciones de reseteo: actualización de kernel, cambiar de ranura, evitar que el host publique la GPU, o módulo vendor-reset para GPUs AMD afectadas.

Task 18: Valida que pasaste todo el grupo IOMMU cuando se requiere

cr0x@server:~$ ls -l /sys/kernel/iommu_groups/12/devices/
total 0
lrwxrwxrwx 1 root root 0 Jan  8 12:20 0000:01:00.0 -> ../../../../devices/pci0000:00/0000:00:01.0/0000:01:00.0
lrwxrwxrwx 1 root root 0 Jan  8 12:20 0000:01:00.1 -> ../../../../devices/pci0000:00/0000:00:01.0/0000:01:00.1

Significado: Solo la GPU y su audio están en el grupo. Eso es bueno. Si hubiera más, el passthrough podría requerir pasarlos también (o necesitas mejor aislamiento).

Decisión: Si el grupo incluye “otras cosas”, o pasas todo (a menudo inaceptable) o cambias hardware/topología.

Tres micro-historias corporativas (anonimizadas, plausibles, técnicamente correctas)

Incidente causado por una suposición errónea: “UEFI es opcional”

Una empresa mediana quería VMs con GPU para un equipo de CAD. El equipo de virtualización tenía Proxmox y alguien ya había pasado un HBA con éxito antes, así que la vibra era “lo mismo, otro dispositivo PCI”. Construyeron una VM plantilla con SeaBIOS porque coincidía con plantillas de servidor antiguas. Arrancó bien por SPICE, así que lo dieron por terminado.

El día de despliegue añadieron GPUs. Pantallas negras por todas partes en monitores físicos, pero RDP funcionaba. Culparon a drivers, luego cables, luego monitores, luego actualizaciones de Windows—espiral clásica de desvío.

La causa real era simple: la GPU pasada nunca se convirtió en la pantalla de arranque temprano porque la ruta de firmware no coincidía con lo que esperaba la tarjeta. SeaBIOS + el comportamiento de la ROM de la tarjeta + un VGA virtual competidor hicieron que el invitado nunca inicializara la salida en la forma que su flujo de trabajo físico requería.

La solución fue aburrida: cambiar a OVMF, poner Q35, eliminar VGA virtual (vga: none), y pasar la GPU como primaria con x-vga=1. También reconstruyeron la plantilla de VM para no repetir el error. El postmortem tuvo una línea clave: “Asumimos que la elección de firmware era cosmética”.

Optimización que salió mal: ACS override como “victoria rápida”

Otra organización corría Proxmox en placas de consumo por presupuesto. Sus grupos IOMMU eran un desastre: la GPU agrupada con un controlador USB y un NVMe detrás del mismo root complex. El equipo quería passthrough de GPU para un servicio de inferencia AI, y lo quería ya.

Habilitaron ACS override para dividir grupos y celebraron cuando la GUI mostró aislamiento “limpio”. Lo pusieron en producción rápido. Funcionó. Por un tiempo.

Semanas después tuvieron congelaciones intermitentes del host durante reinicios de VM. Los logs apuntaban a errores PCIe y ocasionales tropiezos en el sistema de ficheros del dispositivo NVMe “separado”. ACS override no añadió aislamiento hardware; cambió cómo el kernel fingía que los dispositivos estaban aislados. Bajo ciertos patrones de tráfico, los dispositivos aún interactuaban de formas que el agrupamiento IOMMU intentaba ignorar.

La solución final no fue un parámetro ingenioso del kernel. Movieron la carga a una plataforma con aislamiento PCIe real y validaron los grupos antes del despliegue. ACS override quedó como herramienta de laboratorio con una gran etiqueta de advertencia: “Puede funcionar; también puede crear modos de fallo novedosos”.

Práctica aburrida pero correcta que salvó el día: disciplina de arranque en frío y control de cambios

Un equipo que corría VMs con GPU para procesamiento de video tenía la costumbre: cada vez que cambiaban enlace VFIO, tipo de firmware o ajustes ROM, hacían un reinicio completo del host y documentaban las salidas antes/después de lspci -nnk y la config de la VM. Nada de “hot swapping” de la tubería de bajo nivel.

Sonaba lento. Lo era. También les evitó apilar cambios no verificados y luego adivinar cuál importaba.

Cuando toparon con una pantalla negra tras una actualización del kernel de Proxmox, su rollback fue limpio: compararon las salidas “conocidas buenas”, vieron que la GPU ahora era reclamada por un framebuffer en arranque temprano, y lo arreglaron con decisión en vez de “probar otra ROM porque por qué no”.

El efecto neto fue calma operativa. Trataron los cambios de passthrough como cambios de almacenamiento: medir, cambiar una cosa, reiniciar, verificar propiedad, luego seguir.

Errores comunes: síntoma → causa raíz → solución

1) Síntoma: la VM arranca (RDP funciona) pero el monitor físico queda en negro

Causa raíz: VGA virtual es primaria; la GPU pasada no se inicializa como pantalla de arranque, o el invitado elige el adaptador equivocado.

Solución: Usa bios: ovmf, machine: q35, pon vga: none, y activa x-vga=1 en la GPU. Confirma que el monitor esté conectado a la GPU pasada, no a la salida del host.

2) Síntoma: pantalla negra hasta que el OS carga, luego a veces funciona

Causa raíz: Falta/mala inicialización GOP en etapa de firmware; el driver del invitado luego habilita la pantalla.

Solución: Prefiere OVMF, considera suministrar un archivo ROM con GOP válido, y asegúrate de no usar SeaBIOS con una ROM UEFI-first.

3) Síntoma: funciona tras arranque en frío del host; falla tras reinicio de la VM

Causa raíz: Bug de reseteo (sin FLR, dispositivo atascado en D3, reseteo de función incompleto).

Solución: Actualiza kernel/Proxmox, prueba otra ranura PCIe, deshabilita gestión de energía agresiva/ASPM como prueba, y asegúrate de pasar todas las funciones de la GPU juntas. Para generaciones AMD afectadas, considera el enfoque vendor-reset.

4) Síntoma: la VM falla al iniciar, “stuck in D3” o errores de restauración de BARs

Causa raíz: El estado de energía de la GPU no puede ser reactivado por VFIO; la plataforma se niega a energizarla limpiamente después del uso previo.

Solución: Evita el enlace del driver del host, asegura un apagado limpio, prueba arranque en frío, ajusta configuraciones de energía en BIOS, y considera mover la GPU a una ranura con distinto comportamiento de gating de energía.

5) Síntoma: inestabilidad aleatoria bajo carga tras habilitar ACS override

Causa raíz: Aislamiento ficticio; los dispositivos aún comparten una ruta y pueden interferir; las suposiciones de aislamiento DMA fallan bajo contención.

Solución: Usa hardware con aislamiento real. Trata ACS override como último recurso y evítalo para cargas críticas.

6) Síntoma: el invitado ve la GPU pero el driver falla (Windows muestra error o cae a fallback)

Causa raíz: Políticas del driver, detección de virtualización, o topología de dispositivo incorrecta.

Solución: Usa Q35 + OVMF, oculta KVM donde sea apropiado en configuraciones CPU de Proxmox, y evita mezclar adaptadores de pantalla virtuales con uso primario de passthrough.

7) Síntoma: sin salida en un puerto DP/HDMI, funciona en otro

Causa raíz: Orden de inicialización de puertos y quirks de link training en arranque temprano; algunas tarjetas prefieren ciertos puertos para salida pre-OS.

Solución: Prueba puertos/cables alternativos primero. En serio. No es elegante, pero es real.

8) Síntoma: consola de VM en Proxmox sin nada tras poner vga: none

Causa raíz: Eso es esperado—no hay consola virtual.

Solución: Usa monitor físico en la GPU, o confía en RDP/SSH. Si necesitas acceso de emergencia, añade temporalmente un dispositivo de pantalla virtual para depuración, luego elimínalo.

Listas de verificación / plan paso a paso

Checklist A: Passthrough de GPU por primera vez con las menores sorpresas

  1. Habilita VT-d/AMD-Vi en BIOS/UEFI.
  2. Habilita IOMMU en GRUB (intel_iommu=on o amd_iommu=on) y reinicia.
  3. Verifica que IOMMU esté habilitado vía dmesg.
  4. Identifica funciones de GPU vía lspci -nn y anota IDs de GPU + audio.
  5. Verifica agrupamiento IOMMU limpio; si los grupos están desordenados, detente y replantea hardware/topología.
  6. Enlaza funciones de GPU a vfio-pci mediante /etc/modprobe.d/vfio.conf.
  7. Reconstruye initramfs, reinicia, confirma Kernel driver in use: vfio-pci.
  8. Crea la VM con bios: ovmf y machine: q35.
  9. Añade la GPU como hostpci con pcie=1 y (si es primaria) x-vga=1.
  10. Configura vga: none si quieres que la GPU física sea la consola.
  11. Arranca la VM, prueba la salida física e instala drivers del invitado.

Checklist B: Depurar una pantalla negra sin hacer cargo-cult

  1. Confirma que el invitado arranca vía RDP/SSH. Si no, enfócate en errores VFIO/IOMMU primero.
  2. Revisa logs de Proxmox por quejas de energía/reseteo VFIO.
  3. Confirma que la GPU está enlazada a vfio-pci y que el host no la está usando como framebuffer.
  4. Elimina VGA virtual competidor (vga: none) y usa OVMF + Q35.
  5. Pasa todas las funciones de la GPU (audio, USB si existe) juntas.
  6. Si funciona solo después de arranque en frío, deja de tocar ROMs y aborda el comportamiento de reseteo.
  7. Sólo entonces prueba un archivo ROM, y solo de tu tarjeta exacta.
  8. Si usaste ACS override, trata cualquier inestabilidad como “esperada” y planea remediación de hardware.

Checklist C: Estabilizar GPUs propensas a fallos de reseteo operacionalmente

  1. Evita ciclos stop/start de VMs; prefiere patrones de suspend/resume solo si los validaste.
  2. Usa apagado controlado y un periodo de espera antes de reiniciar; algunas tarjetas se comportan mejor tras una quietud limpia.
  3. Mantén el kernel de Proxmox razonablemente actual; el manejo de reseteo mejora con el tiempo.
  4. Documenta combinaciones conocidas buenas: versión de kernel, versión Proxmox, tipo de máquina VM, uso de ROM, ranura.
  5. Para tarjetas “que no se pueden resetear”, planea ciclos de energía del host como parte de ventanas de mantenimiento (feo, pero fiable).

Preguntas frecuentes

1) ¿Por qué RDP funciona pero la pantalla física está en negro?

El SO invitado está en ejecución, pero la GPU pasada no es la pantalla primaria o nunca se inicializó para el arranque temprano. Arregla firmware/topología: OVMF + Q35, elimina VGA virtual, usa x-vga=1 cuando corresponda.

2) ¿Siempre necesito un archivo ROM de GPU?

No. La mayoría de configuraciones estables no requieren ROM. Usa ROM solo cuando tengas un problema de inicialización temprana específico y puedas volcar una ROM correcta de tu tarjeta exacta.

3) ¿Qué significa “stuck in D3” en logs de Proxmox?

La GPU está en un estado de baja energía y VFIO/QEMU no puede despertarla. Eso es un problema de reseteo/gestión de energía/plataforma, no de driver del invitado.

4) ¿Debo usar Q35 o i440fx?

Usa Q35 para passthrough de GPU moderno a menos que tengas un requisito de compatibilidad específico. Modela la topología PCIe de forma más realista.

5) ¿Puedo pasar solo la función GPU e ignorar el audio HDMI?

A veces “funciona”, pero es mala práctica. Pasa todas las funciones en el grupo IOMMU, especialmente la función de audio. El passthrough parcial es una gran forma de obtener rarezas intermitentes.

6) ¿Por qué funciona tras reinicio en frío del host pero no tras reiniciar la VM?

Bug clásico de reseteo. La GPU no se resetea limpiamente entre asignaciones. Enfócate en mitigaciones de reseteo: actualizaciones del kernel, cambios de ranura, ajustes de gestión de energía y soluciones conocidas para tu generación de GPU.

7) ¿Es seguro ACS override?

Es un trade-off: puede hacer posible el passthrough en placas de consumo, pero también reduce las garantías de aislamiento que creías tener. Úsalo en laboratorios. Ten precaución en producción.

8) Puse vga: none y ahora la consola de Proxmox está en blanco. ¿La rompí?

No. Eliminaste el dispositivo de pantalla virtual, por eso la consola de Proxmox no muestra nada. Ese es el objetivo si la GPU física es la consola.

9) ¿Debo habilitar Resizable BAR?

Si buscas estabilidad, déjalo apagado hasta que el passthrough sea estable. ReBAR puede añadir otra capa de complejidad de plataforma y firmware. Enciéndelo más tarde como cambio controlado.

10) ¿Necesito fijar núcleos de CPU o ajustar hugepages para arreglar pantalla negra?

Casi nunca. Esos son ajustes de rendimiento. La pantalla negra suele ser firmware, enlace VFIO, agrupamiento IOMMU o comportamiento de reseteo.

Conclusión: próximos pasos prácticos

Si estás frente a una pantalla negra, deja de adivinar. Empieza con el playbook de diagnóstico rápido: confirma IOMMU, confirma enlace VFIO, confirma OVMF + Q35, elimina VGA virtual competidor y pasa todas las funciones de la GPU. Esa secuencia soluciona una gran fracción de casos reales sin folclore.

Si funciona una vez y falla en reinicios, trátalo como bug de reseteo hasta que pruebes lo contrario. Eso no es pesimismo; es reconocimiento de patrones. Estabiliza con elecciones de plataforma, actualizaciones de kernel y propiedad de dispositivo limpia. Usa archivos ROM como herramientas dirigidas, no rituales.

Próximos pasos que puedes hacer hoy:

  • Ejecuta Task 5 (grupos IOMMU) y Task 6 (propiedad del driver). Si alguno está mal, corrígelo antes de tocar otra cosa.
  • Alinea la VM con Task 11 (OVMF/Q35/vga none) y vuelve a probar.
  • Reproduce el comportamiento de reseteo con Task 17 y decide si estás en “modo mitigación de reseteo”.
← Anterior
Recuperación de pool lleno en ZFS: qué falla primero y cómo volver
Siguiente →
ZFS zpool import -d: Encontrar pools cuando cambian las rutas de dispositivos

Deja un comentario