IOMMU explicado: el interruptor del BIOS que hace (o rompe) el passthrough de GPU

¿Te fue útil?

Puedes tener la GPU correcta, el hipervisor correcto y el tutorial correcto. Y aun así acabar mirando una VM que arranca con pantalla negra,
o peor: que arranca bien hasta que de forma aleatoria deja colgado el host a las 2 a.m. El culpable habitual no es la versión del kernel ni un
driver faltante. Es un interruptor del BIOS que no trataste como infraestructura de producción.

Ese interruptor es IOMMU (Intel VT-d / AMD-Vi). Cuando está bien, el passthrough de GPU es aburrido. Cuando está mal, nada de lo que hagas en software importa.
Esta es la guía de campo para entenderlo, demostrar que funciona y diagnosticar los modos de fallo rápido—como si tuvieras un puente de incidente abierto.

Qué es realmente IOMMU (y por qué lo necesita el passthrough de GPU)

El IOMMU es una unidad de gestión de memoria para dispositivos. Los CPUs tienen una MMU que traduce direcciones virtuales a físicas,
imponiendo aislamiento entre procesos. El IOMMU realiza el mismo tipo de traducción y aislamiento, pero para solicitudes DMA (Direct Memory Access)
procedentes de dispositivos PCIe como GPUs, NICs, controladores NVMe y HBAs.

Sin un IOMMU, un dispositivo que realiza DMA puede efectivamente decir: “Quiero leer/escribir memoria física en la dirección X.”
Si ese dispositivo tiene errores, está mal configurado o es comprometido, puede corromper el kernel del host, la memoria de otra VM o una página con secretos.
Con un IOMMU, el host configura una tabla de traducción para que el dispositivo solo vea la memoria que el host pretende.

Passthrough de GPU en una frase

Passthrough de GPU significa que el driver de la VM habla con una GPU real a través de PCIe como si fuera suya, mientras el hipervisor usa los mapeos IOMMU
para mantener el DMA del dispositivo confinado a la memoria de esa VM.

Por qué “arranca” no es prueba suficiente

Una VM a veces puede arrancar con una GPU pasada a través incluso cuando faltan funcionalidades clave de IOMMU o están mal configuradas, especialmente si la carga
no genera patrones de DMA intensos de inmediato. Entonces ejecutas un juego, una tarea CUDA o un reset del driver—y el host se vuelve inestable.
Eso no es mala suerte. Es la física del DMA encontrándose con una frontera de aislamiento incompleta.

Las capas que realmente estás depurando

  • Firmware: interruptores del BIOS/UEFI (VT-d / AMD-Vi), SR-IOV, “Above 4G decoding”, “Resizable BAR”.
  • Kernel: IOMMU habilitado, remapeo de interrupciones habilitado, modo de traducción DMA (estricto vs lazy).
  • Topología PCIe: puertos raíz, ACS, y si los dispositivos caen en grupos IOMMU separables.
  • Vinculación de drivers: driver del host vs driver VFIO, y quién agarra la GPU al arrancar.
  • Configuración del hipervisor: argumentos de QEMU/KVM, OVMF vs SeaBIOS, tipo de máquina (q35 importa).

Si tratas IOMMU como “alguna cosa de virtualización”, seguirás haciendo cambios por ritual hasta que funcione… y luego dejará de hacerlo.
Trátalo como un primitivo de aislamiento con estados observables, y obtendrás resultados predecibles.

Hechos e historia interesantes que puedes usar en reuniones

A continuación puntos concretos, no triviales, que ayudan a explicar por qué IOMMU existe y por qué sigue siendo fácil de configurar mal:

  1. DMA es anterior a la virtualización moderna por décadas. Los primeros dispositivos de alto rendimiento usaban DMA para evitar la copia por CPU—genial para velocidad, incómodo para el aislamiento.
  2. IOMMU es la respuesta al caos del bus compartido. A medida que PCI y luego PCIe proliferaron, el modelo de “confiar en cada dispositivo” se volvió una responsabilidad de seguridad y fiabilidad.
  3. Intel lo llama VT-d; AMD lo llama AMD-Vi. Distinto branding, misma idea: remapear el DMA de dispositivos mediante tablas de traducción.
  4. Los sistemas operativos modernos cada vez asumen más que IOMMU existe. No es solo para VMs; también se usa para endurecer el kernel y asignación segura de dispositivos.
  5. El remapeo de interrupciones pasó a formar parte de la historia. No solo es DMA. Los dispositivos también generan interrupciones; el remapeo ayuda a prevenir clases de desvíos o inyección de interrupciones.
  6. ACS (Access Control Services) no es un “lujo”. ACS afecta cómo se aísla el tráfico PCIe entre endpoints; un ACS débil a menudo significa “todo está en un mismo grupo IOMMU”.
  7. Los proveedores de GPU no estaban encantados al principio. El passthrough temprano era temperamental porque las GPUs de consumo y sus drivers no fueron diseñados esperando asignación en VM.
  8. Above 4G decoding importa porque las GPUs consumen mucha memoria. Mapear grandes BARs y plataformas modernas te empuja a características de espacio de direcciones que los valores por defecto antiguos no manejan bien.

El interruptor del BIOS/UEFI: nombres, trampas y qué significa realmente “enabled”

El error más caro en passthrough de GPU es asumir que la etiqueta del BIOS coincide con el estado real del hardware.
En muchos sistemas debes habilitar varias opciones, y las etiquetas varían según el proveedor y la generación de placa.
El requisito central es: la CPU + chipset deben exponer un IOMMU y el firmware no debe deshabilitarlo.

Cómo se llama el ajuste

  • Intel: “Intel VT-d,” “VT-d,” “IOMMU,” a veces “Directed I/O.”
  • AMD: “SVM” (virtualización de CPU) no es IOMMU; quieres “IOMMU,” “AMD-Vi,” a veces “PCIe ARI support.”
  • Plataformas servidor: También puedes ver “Interrupt Remapping,” “DMA Protection,” “PCIe ACS,” “SR-IOV.”

Trampas del BIOS que parecen no relacionadas pero sí lo están

  • CSM vs UEFI puro: Muchas configuraciones de passthrough de GPU funcionan mejor con OVMF (UEFI) y CSM deshabilitado.
  • Above 4G decoding: A menudo requerido para GPUs modernas, especialmente si pasas múltiples dispositivos o usas grandes BARs.
  • Resizable BAR: Puede cambiar el tamaño y el mapeo de BAR. Útil a veces, inestable otras. No lo habilites “por rendimiento” sin pruebas.
  • Bifurcación de ranuras PCIe: Puede cambiar la topología; la topología cambia los grupos IOMMU.

Broma #1: Los menús del BIOS son el único lugar donde “Enabled” puede significar “tal vez, dependiendo de tu humor y microcódigo.”

Una cita para mantener al equipo honesto

La esperanza no es una estrategia. — idea parafraseada a menudo atribuida en círculos de ingeniería/ops

Traducción para IOMMU: no “esperes” que esté habilitado porque marcaste algo una vez. Verifícalo desde el sistema operativo.

Grupos IOMMU: la frontera que decide si puedes aislar una GPU

Incluso con IOMMU habilitado, aún puedes quedarte atascado si tu GPU comparte un grupo IOMMU con otros dispositivos que necesitas mantener en el host
(como un controlador USB que requieres para el teclado, o un controlador SATA que contiene el disco de arranque del host). Los grupos IOMMU representan
las unidades mínimas de aislamiento que tu plataforma puede aplicar de manera segura para DMA.

Por qué existen los grupos

Dispositivos detrás del mismo puente PCIe ascendente podrían ser capaces de ver el tráfico entre sí a menos que la plataforma soporte ACS y aislamiento adecuado.
El kernel agrupa esos dispositivos porque no puede garantizar separación. Pasar uno significa pasar todo el grupo.

Qué quieres ver

  • La GPU (y su función de audio HDMI) en un grupo IOMMU que contenga solo esas funciones.
  • NICs y controladores de almacenamiento en grupos separados a menos que intencionadamente los pases.
  • Comportamiento “todo en el grupo 0” mínimo; eso suele indicar que IOMMU no está habilitado o no se expone correctamente.

ACS override: el truco tentador

En algunas placas de consumo puedes forzar al kernel a dividir grupos con un parámetro ACS override. A esto se le presenta a menudo como una solución mágica.
No es magia; es decirle al kernel que finja que existe aislamiento incluso si el hardware no lo proporciona completamente.

Usa ACS override solo cuando entiendas el riesgo: puede que obtengas passthrough funcional, pero el aislamiento de DMA podría ser más débil de lo que piensas.
Para un laboratorio casero está bien. Para cualquier cosa que toque datos de producción, es una conversación de gobernanza.

Guion de diagnóstico rápido

Esta es la secuencia “tengo 20 minutos antes de que termine la ventana de cambios”. No improvises. Revisa estos pasos en orden; cada paso descarta una clase de problemas.

Primero: demuestra que IOMMU está realmente activado

  • Comprueba los parámetros de arranque del kernel y dmesg para la inicialización de IOMMU.
  • Confirma tablas DMAR (Intel) o AMD-Vi detectadas.
  • Confirma el estado del remapeo de interrupciones si te importa la estabilidad y seguridad.

Segundo: valida los grupos IOMMU y la topología

  • Lista los grupos IOMMU; asegúrate de que la GPU y su función de audio estén aisladas.
  • Identifica qué más comparte el grupo; decide si puedes pasarlo también.
  • Si los grupos son demasiado gruesos: prefiere mover ranuras / cambiar la topología del BIOS antes de usar ACS override.

Tercero: confirma vinculación de drivers y propiedad VFIO

  • Asegúrate de que el host no esté enlazando la GPU a nouveau/nvidia/amdgpu.
  • Vincula las funciones GPU a vfio-pci temprano en el arranque; no confíes en “desenlazar después” a menos que te gusten las fallas intermitentes.
  • Confirma que los nodos /dev/vfio/* existen y coinciden con tus IDs de grupo.

Cuarto: comprueba firmware de la VM, tipo de máquina y comportamiento de reset

  • Usa OVMF (UEFI) y q35 a menos que tengas una razón para no hacerlo.
  • Si la GPU no se reinicia limpiamente entre reinicios de VM, planifica vendor-reset (donde aplique) o un reinicio del host.
  • Comprueba problemas de ROM, selección de GPU primaria y enrutamiento de la salida de la consola.

Tareas prácticas: comandos, salidas y las decisiones que tomas

Las siguientes tareas son intencionalmente prácticas. Cada una incluye: el comando, cómo suele ser la salida, qué significa,
y la decisión que debes tomar a continuación. Si haces passthrough de GPU sin ejecutar estas, estás operando por impresiones.

Task 1: Identify your CPU vendor and virtualization flags

cr0x@server:~$ lscpu | egrep -i 'Vendor ID|Model name|Virtualization|Flags'
Vendor ID:             GenuineIntel
Model name:            Intel(R) Xeon(R) CPU E-2278G @ 3.40GHz
Virtualization:        VT-x
Flags:                 ... vmx ...

Meaning: VT-x (Intel) o SVM (AMD) es virtualización de CPU, no IOMMU. Aun así, si no tienes esto, estás muerto para KVM.

Decision: Si falta virtualización, arregla primero la virtualización de CPU en BIOS. Luego vuelve aquí.

Task 2: Confirm IOMMU is enabled in the kernel command line

cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-6.5.0 root=/dev/mapper/vg0-root ro quiet intel_iommu=on iommu=pt

Meaning: intel_iommu=on (o amd_iommu=on) solicita IOMMU. iommu=pt usa modo pass-through para dispositivos del host para reducir la sobrecarga.

Decision: Si no ves el parámetro, añádelo vía GRUB/systemd-boot. Si está presente, pasa a la prueba en dmesg.

Task 3: Check dmesg for DMAR/AMD-Vi initialization

cr0x@server:~$ dmesg | egrep -i 'DMAR|IOMMU|AMD-Vi' | head -n 25
[    0.012345] DMAR: IOMMU enabled
[    0.012678] DMAR: Host address width 39
[    0.013000] DMAR: DRHD base: 0x000000fed90000 flags: 0x0
[    0.013250] DMAR: Queued invalidation will be enabled to support IOMMU
[    0.013500] DMAR: Intel(R) Virtualization Technology for Directed I/O

Meaning: Esto es el kernel diciéndote que encontró las tablas y habilitó el remapeo DMA.

Decision: Si ves errores como “IOMMU disabled” o nada en absoluto, para. Vuelve al BIOS/UEFI y al modo de arranque.

Task 4: Validate interrupt remapping status (stability/security)

cr0x@server:~$ dmesg | egrep -i 'remapping|x2apic|IR' | head -n 30
[    0.020000] DMAR-IR: Enabled IRQ remapping in x2apic mode
[    0.020500] DMAR-IR: Queued invalidation will be enabled

Meaning: El remapeo de IRQ está habilitado; es una buena señal para la corrección en entornos complejos.

Decision: Si el remapeo está deshabilitado por bugs de firmware, considera actualizar BIOS o probar otros parámetros del kernel. En entornos regulados, trata la falta de remapeo como un riesgo, no como una excusa.

Task 5: Enumerate PCI devices and find the GPU functions

cr0x@server:~$ lspci -nn | egrep -i 'vga|3d|audio|nvidia|amd'
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU104 [GeForce RTX 2080] [10de:1e87] (rev a1)
01:00.1 Audio device [0403]: NVIDIA Corporation TU104 HD Audio Controller [10de:10f8] (rev a1)

Meaning: Tu GPU suele ser dos funciones: gráficos y audio HDMI/DP. Pasas ambas.

Decision: Anota las direcciones PCI (01:00.0 y 01:00.1) y los vendor:device IDs (10de:1e87, 10de:10f8) para vincular a vfio-pci.

Task 6: List IOMMU groups and confirm isolation

cr0x@server:~$ for g in /sys/kernel/iommu_groups/*; do echo "IOMMU Group ${g##*/}:"; ls -l "$g/devices"; done | sed -n '1,80p'
IOMMU Group 12:
total 0
lrwxrwxrwx 1 root root 0 Feb  4 09:12 0000:01:00.0 -> ../../../../devices/pci0000:00/0000:00:01.0/0000:01:00.0
lrwxrwxrwx 1 root root 0 Feb  4 09:12 0000:01:00.1 -> ../../../../devices/pci0000:00/0000:00:01.0/0000:01:00.1

Meaning: El Grupo 12 contiene solo la GPU y su función de audio. Así es como “bueno” se ve.

Decision: Si otros dispositivos están en el mismo grupo, decide si puedes pasarlos también. Si no, intenta otra ranura o ajustes del BIOS antes de considerar ACS override.

Task 7: Check what driver currently owns the GPU

cr0x@server:~$ lspci -nnk -s 01:00.0
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU104 [GeForce RTX 2080] [10de:1e87] (rev a1)
	Subsystem: Gigabyte Technology Co., Ltd Device [1458:3fdd]
	Kernel driver in use: nouveau
	Kernel modules: nouveau, nvidiafb

Meaning: El host agarró la GPU con nouveau. VFIO no la tomará de forma fiable después.

Decision: Evita el binding del host (blacklist de drivers o bind a vfio-pci temprano). No intentes “desenlazar luego” en producción a menos que disfrutes sorpresas.

Task 8: Bind the GPU to vfio-pci via modprobe options

cr0x@server:~$ sudo tee /etc/modprobe.d/vfio.conf >/dev/null <<'EOF'
options vfio-pci ids=10de:1e87,10de:10f8 disable_vga=1
EOF
cr0x@server:~$ sudo tee /etc/modprobe.d/blacklist-gpu.conf >/dev/null <<'EOF'
blacklist nouveau
blacklist nvidia
blacklist nvidia_drm
blacklist nvidia_modeset
EOF

Meaning: Estás indicando al kernel que vincule esos device IDs a vfio-pci y que impida que los drivers comunes de GPU los reclamen.

Decision: Reconstruye initramfs (tarea siguiente) para que esto ocurra temprano, luego reinicia.

Task 9: Rebuild initramfs so vfio binding happens at boot

cr0x@server:~$ sudo update-initramfs -u
update-initramfs: Generating /boot/initrd.img-6.5.0

Meaning: Tu initramfs ahora incluye las opciones de módulo/blacklists actualizadas, afectando el binding temprano de dispositivos.

Decision: Reinicia y vuelve a comprobar lspci -nnk para confirmar que vfio-pci posee la GPU.

Task 10: After reboot, confirm vfio-pci is the kernel driver in use

cr0x@server:~$ lspci -nnk -s 01:00.0
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU104 [GeForce RTX 2080] [10de:1e87] (rev a1)
	Subsystem: Gigabyte Technology Co., Ltd Device [1458:3fdd]
	Kernel driver in use: vfio-pci
	Kernel modules: nouveau, nvidiafb

Meaning: Perfecto. La lista de módulos puede seguir mencionando módulos potenciales; la línea clave es “Kernel driver in use.”

Decision: Procede a la configuración de la VM. Si el driver no es vfio-pci, todavía tienes una carrera de binding (a menudo initramfs no actualizado, o IDs equivocados).

Task 11: Confirm VFIO devices exist for the group

cr0x@server:~$ ls -l /dev/vfio/
total 0
crw------- 1 root root 244,   0 Feb  4 09:15 12
crw------- 1 root root  10, 196 Feb  4 09:15 vfio

Meaning: El nodo numérico (12) corresponde al grupo IOMMU 12. Así es como VFIO aplica “todos los dispositivos de un grupo se mueven juntos.”

Decision: Si no existe el nodo de grupo, VFIO no está configurado o IOMMU no funciona como crees. Vuelve a las Tareas 2–6.

Task 12: Check whether the GPU is the boot VGA device (can complicate things)

cr0x@server:~$ lspci -vv -s 01:00.0 | egrep -i 'Kernel driver|VGA|boot'
VGA compatible controller: NVIDIA Corporation TU104 [GeForce RTX 2080] (rev a1)
	Kernel driver in use: vfio-pci
	Capabilities: [60] Power Management version 3
	Flags: bus master, fast devsel, latency 0, IRQ 16

Meaning: En algunos sistemas verás “Boot VGA” en las flags para la GPU primaria. Si tu GPU de passthrough también es la GPU de consola del host, te apuntas a trabajo extra.

Decision: Prefiere un iGPU o una GPU secundaria barata para la consola del host. Si no puedes, tendrás que manejar framebuffer/console y posiblemente quirks de ROM.

Task 13: Confirm KVM acceleration is present (so you’re not debugging slowness as “IOMMU issues”)

cr0x@server:~$ sudo kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used

Meaning: KVM está disponible. Si /dev/kvm falta, tendrás un rendimiento terrible y comportamiento de temporización extraño.

Decision: Soluciona virtualización de CPU y módulos KVM antes de culpar a VFIO.

Task 14: Spot group cohabitation quickly for a specific device

cr0x@server:~$ readlink -f /sys/bus/pci/devices/0000:01:00.0/iommu_group
/sys/kernel/iommu_groups/12

Meaning: Este es el mapeo canónico de grupo. Es apto para scripts y elimina conjeturas.

Decision: Si el grupo contiene otros dispositivos, decide si puedes pasarlos también. Si no, cambia la topología (ranura/bifurcación) antes de hacks del kernel.

Task 15: Check for IOMMU being “enabled” but effectively bypassed

cr0x@server:~$ dmesg | egrep -i 'iommu.*(pt|passthrough)|DMA' | head -n 20
[    0.050000] DMAR: IOMMU enabled
[    0.050500] DMAR: Default domain type: Passthrough (set via iommu=pt)

Meaning: iommu=pt es normal para rendimiento del host. Los dispositivos asignados a VFIO aún obtienen dominios IOMMU aislados.

Decision: Si persigues requisitos de seguridad de borde, considera modo estricto; de lo contrario déjalo. No quites iommu=pt por superstición.

Task 16: Inspect QEMU/libvirt log for VFIO attach errors

cr0x@server:~$ sudo tail -n 60 /var/log/libvirt/qemu/win11-gpu.log
2026-02-04T09:21:10.123456Z qemu-system-x86_64: -device vfio-pci,host=0000:01:00.0,id=hostdev0: vfio 0000:01:00.0: failed to setup container for group 12: Failed to set iommu for container: Operation not permitted
2026-02-04T09:21:10.123789Z qemu-system-x86_64: -device vfio-pci,host=0000:01:00.0,id=hostdev0: failed to initialize VFIO device

Meaning: Esto es un problema de permisos / contenedor / propiedad del grupo (o una capacidad faltante en el runtime).

Decision: Ejecuta QEMU con los privilegios apropiados (libvirt gestiona esto), confirma permisos del grupo vfio y verifica si estás dentro de un contenedor sin privilegios intentando passthrough.

Broma #2: Los errores de VFIO son como galletas de la fortuna—crípticos, ligeramente acusatorios y siempre entregados justo antes de que quisieras irte a casa.

Tres microhistorias corporativas desde las trincheras

Microhistoria 1: El incidente causado por una suposición equivocada

Una empresa mediana desplegó un host de virtualización con GPU “temporal” para acelerar una cola de machine learning. Funcionó bien durante una semana.
Luego un reinicio de mantenimiento rutinario se convirtió en una tarde de outage para las pipelines del equipo de ML.

La suposición: “Habilitamos virtualización en BIOS, así que el passthrough está cubierto.” Habían habilitado VT-x, pero no VT-d.
El host seguía arrancando, las VMs seguían arrancando y la GPU aparecía en la configuración de la VM—hasta el momento en que VFIO intentó adjuntar de verdad.
Tras el reinicio, la GPU se enumeró de forma distinta (ocurre training de ranuras), y ahora la VM fallaba con un error de grupo/contenedor VFIO.

El equipo quemó horas en versiones de drivers y argumentos de QEMU porque el mensaje de error no decía “ve al BIOS”.
Cuando alguien finalmente miró dmesg, no había inicialización DMAR. El hipervisor había estado operando en un estado de “parece bien”,
no en un estado de “está correcto”.

La solución fue aburrida: habilitar VT-d, actualizar el BIOS a una revisión estable y escribir un script preflight que haga grep en dmesg por DMAR/AMD-Vi antes
de permitir cargas GPU en el nodo. También actualizaron su checklist de build para que “virtualización habilitada” se convirtiera en dos comprobaciones explícitas:
virtualización de CPU e IOMMU habilitado.

Microhistoria 2: La optimización que salió mal

Otra compañía quiso exprimir un poco más de rendimiento de sus VMs de cómputo GPU. Alguien sugirió habilitar Resizable BAR y alternar
todas las opciones de firmware que sonaban a rendimiento PCIe: Above 4G decoding, ReBAR, ajustes agresivos de ASPM y una nueva disposición de bifurcación de ranuras PCIe.
Los números de benchmark en una sola VM mejoraron ligeramente.

Luego empezó lo raro: fallos intermitentes al arrancar VMs, bloqueos ocasionales del host bajo DMA intensivo de GPU y un patrón donde la segunda VM
que arrancaba después de un reinicio fallaba mientras la primera tenía éxito. Olía a problema de driver hasta que dejó de serlo.

El problema real fue la inestabilidad de la topología y del agrupamiento. El cambio de bifurcación movió dispositivos detrás de puentes distintos, cambiando los grupos IOMMU.
Su automatización aún vinculaba los IDs antiguos correctamente, pero la agrupación ahora era más gruesa e incluía un controlador USB que el host necesitaba.
A veces la asignación del grupo quedaba “segura”, a veces no, dependiendo del orden de enumeración y del comportamiento del firmware.

El rollback lo solucionó al instante. Mantuvieron Above 4G decoding (requerido), deshabilitaron ReBAR por ahora y trataron la topología PCIe como un ítem con gestión de cambios
con checklist de regresión: verificar grupos, verificar binding VFIO, verificar ciclos de arranque/parada de VM, verificar comportamiento de reset.

Microhistoria 3: La práctica aburrida pero correcta que salvó el día

Un equipo de servicios financieros ejecutaba passthrough de GPU en una pequeña pool de hosts para cargas analíticas. Nada llamativo, pero el control de cambios
era estricto. Tenían un runbook preflight que parecía casi cómicamente simple: confirmar IOMMU habilitado, confirmar grupos sin cambios, confirmar binding VFIO,
confirmar que una VM de prueba puede arrancar y apagar dos veces.

Se programó una actualización de firmware como parte de un ciclo de parches de seguridad. Las notas del proveedor mencionaban “mejorada compatibilidad PCIe”.
El equipo trató esa frase como un dispositivo sin detonar. Evacuaron un host, lo parchearon y ejecutaron el preflight completo.

El preflight detectó que el remapeo de interrupciones había sido deshabilitado por defecto después de la actualización (el firmware reinició una configuración).
Todo aún “funcionaba”, pero los logs del kernel mostraban una degradación en el manejo DMA/interrupciones. Revirtieron el firmware en ese host,
y luego lo aplicaron de nuevo con aplicación explícita de ajustes BIOS y capturas de pantalla guardadas en el registro de cambios interno.

La parte de “salvar el día” no fue heroica. Fue que no descubrieron la regresión durante un pico de producción. La descubrieron en un nodo evacuado, con tiempo para pensar y con evidencia.

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

1) “No se detectó IOMMU” o no aparecen líneas DMAR/AMD-Vi en dmesg

Symptom: VFIO attach falla; dmesg no menciona DMAR/AMD-Vi.

Root cause: IOMMU deshabilitado en BIOS/UEFI, o parámetros de arranque del kernel faltantes/ignorados, o arrancando en un modo que oculta características.

Fix: Habilita VT-d/AMD-Vi, confirma parámetros del kernel, actualiza firmware si las tablas DMAR están rotas. Verifica con la Tarea 3.

2) La GPU comparte grupo IOMMU con SATA/USB/NIC que necesitas en el host

Symptom: No puedes pasar la GPU sin pasar también otros dispositivos críticos.

Root cause: Topología PCIe + falta de aislamiento ACS; las placas de consumo suelen agrupar dispositivos agresivamente.

Fix: Prueba otra ranura PCIe, deshabilita/habilita dispositivos onboard para reordenar, ajusta bifurcación, actualiza BIOS. Último recurso: ACS override, con los ojos abiertos.

3) La VM arranca pero el rendimiento es terrible; uso extraño de GPU

Symptom: La VM es lenta; frame pacing malo; trabajos de cómputo con stutter.

Root cause: KVM no activo, o la VM usa dispositivos emulados, o desajuste de pinning de CPU/NUMA—no IOMMU en sí.

Fix: Confirma /dev/kvm, usa dispositivos virtio, usa q35 + OVMF y verifica la colocación NUMA respecto al root complex PCIe de la GPU.

4) La VM arranca una vez, pero tras apagarla no vuelve a arrancar hasta reiniciar el host

Symptom: El primer attach funciona; los attaches posteriores fallan; la GPU aparece “atascada.”

Root cause: Quirks de reset de GPU (FLR no soportado o poco fiable), o el driver deja el dispositivo en mal estado.

Fix: Usa vendor-reset donde esté soportado, asegúrate de pasar todas las funciones, evita el binding del driver del host por completo y planifica reinicios de mantenimiento si es necesario.

5) Pantalla negra en la VM a pesar de attach VFIO exitoso

Symptom: La VM corre, pero no hay salida de pantalla desde la GPU pasada.

Root cause: Firmware de VM equivocado (SeaBIOS vs OVMF), ROM de GPU faltante, confusión de GPU primaria o salida de vídeo en otro puerto.

Fix: Cambia a OVMF, usa q35, considera especificar un archivo ROM si hace falta y asegúrate de que el monitor esté conectado a la GPU pasada.

6) VFIO “failed to set iommu for container: Operation not permitted”

Symptom: Logs de Libvirt/QEMU muestran fallos de permisos/contenedor.

Root cause: Intentar passthrough desde un contenedor sin privilegios, permisos de dispositivo incorrectos o modelo de seguridad de libvirt mal configurado.

Fix: Ejecuta el hipervisor en el host, no en un contenedor sin privilegios; valida permisos de /dev/vfio; usa QEMU gestionado por libvirt con privilegios adecuados.

7) Habilitaste “SVM” en AMD y pensaste que eso era IOMMU

Symptom: Virtualización de CPU funciona; IOMMU no.

Root cause: SVM es virtualización de CPU; AMD-Vi es IOMMU. Son toggles distintos.

Fix: Habilita AMD-Vi/IOMMU explícitamente y verifica dmesg por AMD-Vi.

8) ACS override “arregla” el agrupamiento pero introduce inestabilidad o riesgo

Symptom: Los grupos parecen perfectos después de ACS override, pero ves cuelgues raros del host o rechazo en la revisión de seguridad.

Root cause: Forzaste al kernel a partir grupos más allá de lo que el hardware garantiza aislar.

Fix: Prefiere hardware que soporte ACS correctamente; en entornos serios, no uses ACS override como solución permanente.

Listas de verificación / plan paso a paso

Paso a paso: llegar al primer passthrough de GPU exitoso (repetible)

  1. Firmware: Habilita VT-d (Intel) o AMD-Vi/IOMMU (AMD). Habilita Above 4G decoding. Prefiere arranque UEFI puro.
  2. Parámetros del kernel: Añade intel_iommu=on o amd_iommu=on. Opcionalmente añade iommu=pt.
  3. Reinicia y verifica: Usa dmesg para confirmar DMAR/AMD-Vi habilitado y ausencia de errores graves de IOMMU.
  4. Descubre dispositivos: Usa lspci -nn para registrar las IDs y direcciones de la GPU y función de audio.
  5. Verifica grupos: Asegura que las funciones de la GPU están aisladas en su propio grupo IOMMU.
  6. Vincula a vfio-pci temprano: Configura IDs en vfio-pci y haz blacklist de drivers del host; reconstruye initramfs.
  7. Reinicia y confirma binding: lspci -nnk debería mostrar vfio-pci en uso para las funciones GPU.
  8. Config de VM: Usa q35 + OVMF. Pasa ambas funciones de GPU. Prefiere virtio para disco y NIC.
  9. Prueba el ciclo de vida: Arranca VM, ejecuta carga, apaga VM, arranca de nuevo. Repite. Estás probando comportamiento de reset, no solo el primer arranque.
  10. Operativiza: Escribe checks preflight (IOMMU habilitado, grupos estables, binding vfio correcto) y ejecútalos tras actualizaciones de firmware/kernel.

Checklist de gestión de cambios (porque las actualizaciones de firmware son caóticas)

  • Antes del cambio: captura dmesg líneas IOMMU y el listado de grupos IOMMU para la GPU.
  • Antes del cambio: captura lspci -nnk para las funciones de la GPU (driver en uso).
  • Después del cambio: vuelve a ejecutar los mismos comandos; haz diff de las salidas.
  • Después del cambio: inicia/detén la VM de prueba dos veces; confirma ausencia de regresiones.
  • Si cambiaron los grupos: trátalo como un cambio de topología y reevalúa la seguridad antes de restaurar cargas de producción.

Cuándo dejar de intentar y comprar mejor hardware

  • Tu GPU comparte un grupo con dispositivos críticos del host y no puedes cambiar la topología para aislarla.
  • Requieres garantías de aislamiento estricto y te apoyas en ACS override para hacer que los grupos “parezcan correctos”.
  • Necesitas comportamiento de reset fiable y tu combinación GPU/placa no lo ofrece sin reinicios del host.

Preguntas frecuentes

1) ¿IOMMU es solo para virtualización?

No. También se usa para aislamiento DMA y endurecimiento del kernel en bare metal. La virtualización es solo el caso de uso más visible.

2) ¿Cuál es la diferencia entre VT-x y VT-d?

VT-x es virtualización de CPU (ejecución eficiente de código invitado). VT-d es IOMMU (remapeo de DMA de dispositivos). Necesitas VT-d para passthrough PCI seguro.

3) En AMD, ¿SVM es lo mismo que AMD-Vi?

No. SVM es virtualización de CPU. AMD-Vi (a menudo etiquetado como IOMMU) es lo que necesitas para passthrough.

4) ¿Por qué tengo que pasar también la función de audio de la GPU?

Porque normalmente es una función PCI separada en el mismo paquete de dispositivo. Dejarla en el host puede romper el comportamiento de reset o causar conflictos de drivers en el invitado.

5) ¿Los grupos IOMMU son una limitación de Linux?

El agrupamiento refleja fronteras de aislamiento del hardware (puentes, capacidades ACS). Linux es conservador: no promete aislamiento que no pueda garantizar.

6) ¿Debería usar siempre iommu=pt?

Generalmente sí para un host hipervisor: reduce la sobrecarga para dispositivos propiedad del host. Los dispositivos asignados a VFIO aún obtienen dominios IOMMU aislados.
Si buscas aislamiento DMA estricto para todos los dispositivos, reconsidera y prueba.

7) ¿Hace ACS override que el passthrough sea “seguro”?

Puede hacer que funcione. “Seguro” depende del aislamiento que tu hardware realmente proporcione. Para modelos de riesgo de producción o multi-tenant, evita confiar en ello.

8) Mi VM funciona hasta que reinicio la VM. ¿Por qué?

Probablemente un problema de reset del dispositivo. Muchas GPUs no se reinician limpiamente vía FLR en todos los escenarios. Puede que necesites vendor-reset, hardware distinto o reinicios del host entre asignaciones.

9) ¿Necesito UEFI (OVMF) en la VM?

Para muchas GPUs modernas y huéspedes Windows, sí. OVMF + q35 reduce rutas VGA legacy raras y generalmente se comporta mejor para passthrough.

10) ¿Puedo ejecutar passthrough de GPU desde dentro de un contenedor?

En la práctica, el passthrough de GPU es una tarea a nivel host. Los contenedores sin privilegios suelen carecer de permisos y gestión de dispositivos requeridos para VFIO.

Conclusión: siguientes pasos que realmente marcan la diferencia

IOMMU no es “una característica.” Es el contrato que hace que la asignación de dispositivos tenga sentido. Si quieres que el passthrough de GPU sea estable, deja de tratar la opción del BIOS
como una casilla y empieza a tratarla como una dependencia que verificas de forma continua.

Pasos prácticos siguientes

  1. Ejecuta las Tareas 2–6 en tu host y guarda las salidas como línea base (cmdline del kernel, líneas IOMMU en dmesg, lista de grupos IOMMU).
  2. Vincula tu GPU a vfio-pci temprano (Tareas 7–10). Si sigues desenlazando en vivo, eliges fragilidad.
  3. Prueba el ciclo de vida de la VM dos veces (arrancar → carga → apagar → arrancar). Si solo funciona una vez, no tienes un sistema—tienes una demo.
  4. Si los grupos son problemáticos, arregla la topología primero. Si debes usar ACS override, documenta el riesgo y mantenlo fuera de entornos que requieran fuertes garantías de aislamiento.

La condición de victoria es aburrida: grupos consistentes, binding predecible, arranque/parada de VM repetible. Cuando se vuelve aburrido, lo hiciste bien.

← Anterior
Lista de verificación de passthrough PCI en Proxmox: 12 cosas que verificar antes de culpar a VFIO
Siguiente →
Almacenamiento Linux: La opción de montaje que puede corromper tus expectativas

Deja un comentario