Estás intentando hacer aquello en lo que Proxmox es famoso: passthrough PCIe. GPU, HBA, NIC, lo que sea. Entonces el host te avisa con calma: No IOMMU detected. Traducción: tu hipervisor tiene los ojos vendados y le pides que haga malabares con motosierras.
Esto normalmente no es “un bug de Proxmox”. Es una descoordinación entre el modo del firmware (UEFI/Legacy), las funciones de virtualización del CPU (VT-d / AMD-Vi) y los flags del kernel que realmente activan el IOMMU. La solución es rápida cuando sabes dónde mirar—y desesperante cuando no.
Qué significa realmente “No IOMMU detected”
En la virtualización x86, un IOMMU es el componente de hardware que permite al host controlar el DMA (acceso directo a memoria) desde dispositivos. Sin él, un dispositivo PCIe puede potencialmente leer/escribir memoria que no debería. Eso impide el passthrough seguro.
Proxmox (KVM/QEMU por debajo) necesita que el kernel exponga un IOMMU activo. Si ves “No IOMMU detected”, una de estas opciones es cierta:
- El CPU/chipset no lo soporta (raro en servidores modernos; menos raro en componentes de sobremesa económicos).
- El firmware desactivó la función (VT-d en Intel, AMD-Vi/IOMMU en AMD).
- Arrancaste en un modo/configuración donde el kernel no lo activó (flags del kernel faltantes, configuración del gestor de arranque equivocada, peculiaridades de Secure Boot).
- Está activado, pero estás comprobando la evidencia equivocada (común—la gente hace grep en el log incorrecto y persigue fantasmas).
Y aquí está la verdad operativa importante: “IOMMU activado” no es binario en la práctica. Puedes tener un IOMMU detectado con agrupamiento terrible, remapeo de interrupciones roto o un dispositivo que no se reinicia. Aún así no tendrás passthrough estable.
Guía de diagnóstico rápido (primero/segundo/tercero)
Si tienes prisa (y la tienes), haz esto en orden. No es filosófico. Es rápido.
Primero: demuestra si el kernel ve un IOMMU
Comprueba los mensajes del kernel en vivo para Intel DMAR o AMD-Vi. Esta es la fuente de verdad más rápida.
cr0x@server:~$ dmesg | egrep -i 'dmar|iommu|amd-vi|ivrs' | head -n 50
[ 0.000000] DMAR: IOMMU enabled
[ 0.000000] DMAR: Host address width 39
[ 0.000000] DMAR: DRHD base: 0x000000fed90000 flags: 0x0
Qué significa: Si ves “DMAR: IOMMU enabled” (Intel) o “AMD-Vi: IOMMU enabled” (AMD), el mensaje “No IOMMU detected” proviene de otra capa o de un arranque anterior.
Decisión: Si no hay ninguna línea relevante, ve a los ajustes del firmware y a los flags del kernel inmediatamente. Si hay líneas pero el agrupamiento es malo, salta a la sección de grupos IOMMU.
Segundo: confirma que has arrancado como crees
cr0x@server:~$ cat /sys/firmware/efi/fw_platform_size 2>/dev/null || echo "Not booted via UEFI"
64
Qué significa: “64” significa arranque UEFI. Si obtienes “Not booted via UEFI”, estás en modo legacy. Eso aún puede funcionar, pero UEFI suele ser menos problemático en plataformas modernas.
Decisión: Si la plataforma soporta UEFI, úsalo. Mezclar arranque legacy con funciones modernas de virtualización es cómo te ganas trabajo el fin de semana.
Tercero: verifica que los flags del kernel realmente están aplicados
cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.8.12-3-pve root=ZFS=rpool/ROOT/pve-1 ro quiet intel_iommu=on iommu=pt
Qué significa: Debes ver intel_iommu=on para Intel o amd_iommu=on para AMD. A menudo también querrás iommu=pt para reducir la sobrecarga en dispositivos del host.
Decisión: Si los flags no están presentes, corrige GRUB o systemd-boot. Si están presentes y dmesg aún no muestra IOMMU, el firmware es el culpable (o el hardware).
Datos interesantes (y un poco de historia) sobre IOMMU
- El DMA precede a la virtualización moderna por décadas. Los primeros sistemas permitían que los dispositivos escribieran directamente en memoria porque los CPUs eran lentos y copiar buffers era caro.
- VT-d de Intel y AMD-Vi llegaron porque los hipervisores necesitaban DMA seguro. Sin un IOMMU, el passthrough es básicamente “confiar en el dispositivo y rezar”.
- La tabla ACPI “DMAR” es un artefacto clave. En sistemas Intel, el kernel suele descubrir la capacidad IOMMU vía la tabla DMAR proporcionada por el firmware.
- El remapeo de interrupciones importa. Un IOMMU funcional no es solo traducción de direcciones; el remapeo correcto de interrupciones reduce la superficie de ataque y mejora el aislamiento.
- El agrupamiento IOMMU depende mucho de la placa base/topología. Los grupos dependen de puertos root PCIe, switches y del comportamiento ACS (Access Control Services).
- ACS no se inventó para laboratorios domésticos. Es una característica de PCIe diseñada para hacer cumplir el aislamiento en sistemas multi-función/multi-inquilino—luego los aficionados descubrieron que mejora el layout con VFIO.
- “iommu=pt” es un compromiso de rendimiento. Usa mapeos de passthrough para dispositivos del host (menos sobrecarga), mientras que los dispositivos VFIO siguen teniendo aislamiento. Si buscas máxima seguridad multi-inquilino, puedes optar por otra postura.
- UEFI no lo hizo más simple; lo hizo diferente. Muchas plataformas entregan tablas ACPI mejores en modo UEFI, pero también introducen Secure Boot y complejidades de NVRAM.
Comprobaciones previas: confirma CPU, modo de firmware y gestor de arranque de Proxmox
Antes de tocar ajustes del BIOS, confirma con qué estás lidiando. Esto es la norma en sistemas en producción: medir primero, cambiar después.
Tarea 1: Identificar el fabricante de CPU y las capacidades de virtualización
cr0x@server:~$ lscpu | egrep '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 ... dmar ...
Qué significa: En Intel, quieres VT-x (virtualización de CPU) y VT-d (IOMMU). VT-d no aparece como “VT-d” aquí de forma fiable; típicamente lo inferirás vía la plataforma y los logs DMAR. En AMD verás “svm” para la virtualización de CPU y luego comprobarás AMD-Vi en dmesg.
Decisión: Si el CPU es una pieza de gama baja o un SKU embebido extraño, confirma que soporta IOMMU antes de culpar a Proxmox.
Tarea 2: Confirmar que los módulos del kernel relacionados con IOMMU están presentes
cr0x@server:~$ lsmod | egrep 'vfio|iommu|kvm' | head
vfio_pci 16384 0
vfio_pci_core 69632 1 vfio_pci
vfio_iommu_type1 45056 0
vfio 40960 2 vfio_pci_core,vfio_iommu_type1
kvm_intel 372736 0
kvm 1036288 1 kvm_intel
Qué significa: Que los módulos VFIO estén cargados no prueba que IOMMU esté activado, pero te dice que no te faltan las canalizaciones básicas.
Decisión: Si VFIO está ausente y intentas passthrough, tendrás que cargar/configurarlo más tarde. Para “No IOMMU detected”, céntrate primero en firmware + cmdline.
Tarea 3: Determinar si Proxmox usa GRUB o systemd-boot
cr0x@server:~$ proxmox-boot-tool status 2>/dev/null || echo "proxmox-boot-tool not in use"
Re-executing '/usr/sbin/proxmox-boot-tool' in new private mount namespace
System currently booted with: uefi
Configured ESPs: /boot/efi
Qué significa: Si proxmox-boot-tool está en uso, normalmente estás en systemd-boot con una partición ESP (EFI System Partition). Si no está en uso, podrías estar con GRUB.
Decisión: No adivines qué gestor de arranque tienes. Aplica los flags del kernel en el lugar correcto según tu ruta de arranque.
Tarea 4: Confirmar entradas del bootloader actuales (ruta systemd-boot)
cr0x@server:~$ bootctl status 2>/dev/null | sed -n '1,120p'
System:
Firmware: UEFI 2.70
Secure Boot: disabled
Setup Mode: user
Boot Loader:
Product: systemd-boot 252
Features: ✓ Boot counting
Default Boot Entry: proxmox
Qué significa: Estás usando systemd-boot. Proxmox normalmente gestiona la línea de comandos del kernel a través de /etc/kernel/cmdline.
Decisión: Si estás en systemd-boot, editar /etc/default/grub puede no servir de nada. Eso es una pérdida de tiempo clásica.
Tarea 5: Confirmar que GRUB está instalado/activo (ruta GRUB)
cr0x@server:~$ grub-probe /boot 2>/dev/null && echo "GRUB tooling present"
ext2
GRUB tooling present
Qué significa: La herramienta GRUB existe, pero no prueba que sea el gestor activo. Combínalo con las comprobaciones UEFI anteriores.
Decisión: Si has arrancado en UEFI y systemd-boot está activo, trata a GRUB como una distracción a menos que lo hayas instalado explícitamente.
Ajustes UEFI/BIOS que importan (y los que no)
Los menús del firmware varían enormemente, pero los conceptos son estables. Necesitas habilitar la función IOMMU y a veces algunas opciones auxiliares que la hacen usable en la práctica.
Plataformas Intel (etiquetas comunes)
- Intel Virtualization Technology (VT-x): Habilita la virtualización de CPU. Necesario para KVM, pero no suficiente para passthrough.
- Intel VT-d: Este es el IOMMU. Es por lo que estás aquí.
- Above 4G decoding: Útil/requerido cuando haces passthrough de GPUs o múltiples dispositivos que mapean grandes BARs. En algunas placas, esto también cambia la asignación de recursos PCIe y mejora el agrupamiento.
- Resizable BAR: Puede complicar el passthrough en algunas configuraciones. Si estás depurando, considera desactivarlo temporalmente.
- SR-IOV: No es necesario para IOMMU, pero suele estar en el mismo vecindario. Actívalo solo si necesitas VFs.
Plataformas AMD (etiquetas comunes)
- SVM: Virtualización de CPU (KVM). Actívalo.
- IOMMU / AMD-Vi: El IOMMU. Actívalo.
- ACS / ACS Enable: A veces expuesto, a veces no. No confíes en que esté presente.
- Above 4G decoding: Igual que en Intel; a menudo requerido para estabilidad en passthrough de GPU.
Ajustes del firmware que la gente obsesiona (usualmente inútiles)
- “UEFI vs Legacy” como interruptor mágico: UEFI puede ayudar, pero no reemplaza habilitar VT-d/AMD-Vi.
- C-states: La gestión de energía puede causar problemas de latencia, no “No IOMMU detected.” No cambies diez parámetros a la vez.
- XMP/EXPO: Los perfiles de memoria pueden desestabilizar hosts, pero no deshabilitan IOMMU. Manténlos conservadores si esto es algo parecido a producción.
Broma #1: Si la UI de tu BIOS parece el menú de un reproductor de DVD de 2009, no te preocupes—tus ajustes IOMMU aún están escondidos por ahí.
Flags del kernel: GRUB vs systemd-boot (la solución de 10 minutos)
Una vez que el firmware esté correcto, el kernel aún debe habilitar IOMMU. En Proxmox, esto suele ser un cambio de una línea más la actualización del gestor de arranque.
Elige los flags por proveedor
- Intel:
intel_iommu=on iommu=pt - AMD:
amd_iommu=on iommu=pt
¿Por qué iommu=pt? Es una opción pragmática por defecto para muchos hosts de virtualización: los dispositivos del host usan mapeos pass-through (menos sobrecarga), mientras que los dispositivos VFIO siguen teniendo aislamiento. Si trabajas en entornos multi-inquilino de máxima seguridad, puedes elegir otra postura. La mayoría de usuarios de Proxmox no lo hace.
Tarea 6 (systemd-boot): Establecer flags en /etc/kernel/cmdline
cr0x@server:~$ sudo cat /etc/kernel/cmdline
root=ZFS=rpool/ROOT/pve-1 ro quiet
Qué significa: Esta es tu plantilla de línea de comandos del kernel.
Decisión: Añade los flags correctos para tu CPU.
cr0x@server:~$ sudo nano /etc/kernel/cmdline
Edítalo a algo como:
cr0x@server:~$ sudo cat /etc/kernel/cmdline
root=ZFS=rpool/ROOT/pve-1 ro quiet intel_iommu=on iommu=pt
Ahora aplícalo:
cr0x@server:~$ sudo proxmox-boot-tool refresh
Running hook script 'proxmox-auto-removal'..
Running hook script 'zz-proxmox-boot'..
Refreshing ESP /boot/efi
Copying kernel and creating EFI boot entry
Qué significa: Las entradas en la ESP se actualizan con el nuevo cmdline.
Decisión: Si no ves que refresque la ESP, puede que no estés usando systemd-boot—o tu ESP no esté montada correctamente.
Tarea 7 (GRUB): Establecer flags en /etc/default/grub y update-grub
cr0x@server:~$ sudo grep -n '^GRUB_CMDLINE_LINUX_DEFAULT' /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet"
Qué significa: Aquí es donde añades los flags para configuraciones típicas con GRUB.
Decisión: Añade el flag del proveedor y normalmente iommu=pt.
cr0x@server:~$ sudo sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="quiet"/GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"/' /etc/default/grub
cr0x@server:~$ sudo update-grub
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-6.8.12-3-pve
Found initrd image: /boot/initrd.img-6.8.12-3-pve
done
Qué significa: Tu configuración de GRUB ahora incluye los flags.
Decisión: Si update-grub no encuentra las imágenes de kernel de Proxmox, o no estás usando GRUB o tu diseño de /boot es inusual.
Tarea 8: Reinicia y confirma que cmdline contiene los flags
cr0x@server:~$ sudo reboot
Connection to server closed by remote host.
Tras el reinicio:
cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.8.12-3-pve root=ZFS=rpool/ROOT/pve-1 ro quiet intel_iommu=on iommu=pt
Qué significa: El kernel en ejecución tiene los flags.
Decisión: Si los flags no aparecen, editaste el sitio equivocado para tu gestor de arranque. Vuelve a las tareas de detección del bootloader.
Validar que IOMMU funciona (e interpretar la salida)
No “sientes” IOMMU. Lo demuestras. Aquí están las comprobaciones en las que confío.
Tarea 9: Revisar dmesg para la activación de IOMMU (de nuevo, después de los cambios)
cr0x@server:~$ dmesg | egrep -i 'DMAR: IOMMU enabled|AMD-Vi: IOMMU enabled|IOMMU enabled' | head
[ 0.000000] DMAR: IOMMU enabled
Qué significa: El kernel está usando el IOMMU.
Decisión: Si aún no ves nada, el firmware sigue sin habilitar VT-d/AMD-Vi o la plataforma no provee correctamente las tablas.
Tarea 10: Comprobar remapeo de interrupciones / advertencias DMAR
cr0x@server:~$ dmesg | egrep -i 'remapping|x2apic|DMAR:.*fault|AMD-Vi:.*Event' | head -n 50
[ 0.000000] DMAR: Interrupt remapping enabled
Qué significa: El remapeo de interrupciones está activo (bueno). Si ves fallos DMAR, eso puede indicar firmware defectuoso o un dispositivo haciendo DMA ilegal.
Decisión: Si ves fallos repetidos, no los ignores. Correlan fuertemente con “VM se congela aleatoriamente bajo IO”.
Tarea 11: Comprobar la presencia de IOMMU en sysfs
cr0x@server:~$ ls -1 /sys/kernel/iommu_groups 2>/dev/null | head
0
1
2
3
Qué significa: Si /sys/kernel/iommu_groups existe y tiene directorios numerados, el kernel creó grupos IOMMU.
Decisión: Si el directorio no existe, no tienes un IOMMU activo.
Tarea 12: Enumerar grupos y dispositivos (el suero de la verdad)
cr0x@server:~$ for g in /sys/kernel/iommu_groups/*; do echo "Group $(basename "$g")"; for d in "$g"/devices/*; do echo -n " "; lspci -nns "$(basename "$d")"; done; done | sed -n '1,60p'
Group 0
00:00.0 Host bridge [0600]: Intel Corporation Device [8086:3e0f]
Group 1
00:01.0 PCI bridge [0604]: Intel Corporation Device [8086:1901]
Group 7
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:1b80] (rev a1)
01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:10f0] (rev a1)
Qué significa: Los dispositivos en el mismo grupo no pueden separarse de forma segura para passthrough. Una GPU típicamente aparece con su función de audio en el mismo grupo—normal y aceptable. Pero si tu GPU comparte grupo con, por ejemplo, el controlador SATA desde el que arrancas, te espera un mal día.
Decisión: Si el grupo del dispositivo objetivo incluye dispositivos críticos no relacionados, o bien mueves la tarjeta a otro slot, cambias ajustes del firmware (Above 4G decoding a veces ayuda), o consideras ACS override (con los ojos abiertos).
Grupos IOMMU: cómo debe verse “bien”
Los grupos IOMMU son la diferencia entre “passthrough es un checkbox” y “passthrough es un proyecto trimestral”. Quieres separación limpia. Rara vez obtienes perfección. Te conformas con seguridad.
Lo que quieres
- Tu dispositivo de passthrough (GPU/HBA/NIC) esté aislado en su propio grupo, o comparta solo con sus propias funciones (dispositivos multi-función).
- Los controladores de placa base que usas para el arranque (controlador SATA/NVMe que contiene la raíz de Proxmox) no estén pegados al mismo grupo que tu objetivo de passthrough.
- Los puertos root PCIe y puentes formen separación lógica entre ranuras.
Lo que puedes tolerar
- GPU + función de audio de GPU en el mismo grupo.
- NIC con múltiples funciones agrupadas juntas (depende del hardware).
Lo que no deberías tolerar
- HBA agrupado con el controlador SATA del chipset que aloja discos de arranque de Proxmox.
- GPU agrupada con el controlador USB que necesitas para teclado/consola durante caídas (pregúntame cómo lo sé; en realidad, mejor no).
Broma #2: Los grupos IOMMU son como la asignación de escritorios en la oficina—si Finanzas y Producción comparten escritorio, algo está a punto de ser auditado.
Fundamentos de VFIO: enlazar dispositivos correctamente
Una vez que IOMMU está activado y los grupos son aceptables, todavía necesitas evitar que el host agarre el dispositivo con un driver nativo. VFIO quiere el dispositivo primero.
Tarea 13: Identificar los IDs PCI del dispositivo que vas a pasar
cr0x@server:~$ lspci -nn | egrep -i 'vga|nvidia|amd|ethernet|sas|sata' | head -n 20
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:1b80] (rev a1)
01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:10f0] (rev a1)
Qué significa: Los IDs vendor:device están entre corchetes. Aquí: 10de:1b80 y 10de:10f0.
Decisión: Generalmente enlazas todas las funciones que pretendes pasar (GPU + audio). No enlaces la mitad de un dispositivo multi-función a menos que disfrutes depurar.
Tarea 14: Comprobar qué driver posee actualmente el dispositivo
cr0x@server:~$ lspci -k -s 01:00.0
01:00.0 VGA compatible controller: NVIDIA Corporation Device 1b80 (rev a1)
Subsystem: Micro-Star International Co., Ltd. [MSI] Device 3301
Kernel driver in use: nouveau
Kernel modules: nouveau
Qué significa: El host está usando nouveau. Para passthrough, normalmente quieres vfio-pci en su lugar.
Decisión: Planea enlazar a vfio-pci y poner en blacklist los drivers del host que se adjuntan automáticamente.
Tarea 15: Configurar IDs para VFIO
cr0x@server:~$ sudo tee /etc/modprobe.d/vfio.conf >/dev/null <<'EOF'
options vfio-pci ids=10de:1b80,10de:10f0 disable_vga=1
EOF
Qué significa: Esto indica a vfio-pci que reclame esos dispositivos temprano.
Decisión: Si este host de producción también usa la GPU para la consola, reconsidera. El passthrough implica que el host no debería depender de ese dispositivo.
Tarea 16: Poner en blacklist drivers GPU conflicting (ejemplo para nouveau)
cr0x@server:~$ sudo tee /etc/modprobe.d/blacklist-gpu.conf >/dev/null <<'EOF'
blacklist nouveau
options nouveau modeset=0
EOF
Qué significa: Evita que el driver abierto de NVIDIA se enlace al arrancar.
Decisión: Haz blacklist solo de lo que choque. No te embarques en una lista negra masiva; así es como te quitas el driver de tu propia NIC y “aprendes” la política de manos remotas.
Tarea 17: Asegurar que los módulos VFIO se carguen temprano
cr0x@server:~$ sudo tee -a /etc/modules >/dev/null <<'EOF'
vfio
vfio_pci
vfio_iommu_type1
vfio_virqfd
EOF
Qué significa: Garantiza que los módulos se carguen al arrancar. Algunas configuraciones funcionan sin esto; muchas se comportan mejor con ello.
Decisión: Si persigues enlaces intermitentes, cargar VFIO temprano es una estabilización barata.
Tarea 18: Actualizar initramfs y reiniciar
cr0x@server:~$ sudo update-initramfs -u -k all
update-initramfs: Generating /boot/initrd.img-6.8.12-3-pve
Qué significa: Tu initramfs ahora incluye la configuración de módulos para el arranque temprano.
Decisión: Reinicia para probar un enlace limpio; no intentes desvincular una GPU en caliente en un sistema que necesites que siga siendo accesible.
Tarea 19: Confirmar que el dispositivo ahora está ligado a vfio-pci
cr0x@server:~$ lspci -k -s 01:00.0
01:00.0 VGA compatible controller: NVIDIA Corporation Device 1b80 (rev a1)
Subsystem: Micro-Star International Co., Ltd. [MSI] Device 3301
Kernel driver in use: vfio-pci
Kernel modules: nouveau
Qué significa: “Kernel driver in use: vfio-pci” es la condición de victoria. “Kernel modules” puede seguir listando módulos potenciales; eso está bien.
Decisión: Si sigue siendo propiedad de nouveau/nvidia/amdgpu, tu blacklist o la actualización del initramfs no surtieron efecto, o el dispositivo se usa como consola primaria.
Listas de verificación / plan paso a paso
Paso a paso: arreglar “No IOMMU detected” en el mundo real
- Confirma modo de arranque: UEFI o legacy vía
/sys/firmware/efi. Decide si estandarizar en UEFI. - Identifica el gestor de arranque: systemd-boot vs GRUB. Edita el archivo de configuración correcto.
- Activa opciones del firmware: VT-d (Intel) o IOMMU/AMD-Vi (AMD). También activa SVM/VT-x para la virtualización de CPU.
- Activa Above 4G decoding: Especialmente si haces passthrough de GPU/HBA o múltiples dispositivos PCIe.
- Añade flags del kernel:
intel_iommu=on iommu=ptoamd_iommu=on iommu=pt. - Refresca las entradas de arranque:
proxmox-boot-tool refreshpara systemd-boot, oupdate-grubpara GRUB. - Reinicia: No confíes en estados parciales.
- Valida en dmesg: “IOMMU enabled,” y preferiblemente remapeo de interrupciones.
- Revisa grupos: Asegúrate de que tu dispositivo objetivo esté en un grupo seguro.
- Enlaza VFIO: Establece ids en vfio-pci, pon en blacklist drivers en conflicto, actualiza initramfs, reinicia.
- Prueba la estabilidad de la VM: Arranca la VM, somete a carga, confirma que resets y reboots funcionan repetidamente.
Lista de seguridad antes de pasar controladores de almacenamiento
- Confirma que el HBA no esté en el mismo grupo IOMMU que el controlador de arranque.
- Asegura que la raíz de Proxmox no esté en discos conectados al controlador que vas a pasar.
- Tener acceso fuera de banda (IPMI/iKVM) o al menos un plan si se cae la red.
- Haz snapshot de la configuración de la VM y registra direcciones PCI antes de cambios.
Errores comunes: síntomas → causa raíz → solución
Aquí es donde se pierde la mayor parte del tiempo: no en la solución, sino en arreglar con seguridad la cosa equivocada.
1) Síntoma: “No IOMMU detected” incluso después de poner intel_iommu=on
- Causa raíz: Editaste GRUB, pero el host arranca por systemd-boot (o viceversa).
- Solución: Confirma con
bootctl statusyproxmox-boot-tool status. Aplica los flags en/etc/kernel/cmdlinepara systemd-boot y ejecutaproxmox-boot-tool refresh.
2) Síntoma: dmesg muestra IOMMU activado, pero la GUI de Proxmox sigue quejándose
- Causa raíz: Estás mirando información obsoleta (arranque anterior), o la advertencia proviene de una comprobación de configuración de VM que espera módulos VFIO y grupos, no solo IOMMU.
- Solución: Reinicia y valida con
cat /proc/cmdlineyls /sys/kernel/iommu_groups. Asegura que los módulos VFIO estén cargados y que el aislamiento por grupos sea aceptable.
3) Síntoma: la VM arranca, pero el dispositivo no aparece en el invitado
- Causa raíz: El driver del host todavía posee el dispositivo, o solo enlazaste parte de un dispositivo multi-función.
- Solución: Usa
lspci -kpara confirmarvfio-pci. Enlaza todas las funciones relevantes (GPU + audio). Actualiza initramfs y reinicia.
4) Síntoma: “Los grupos IOMMU no son viables” / grupos enormes que contienen media máquina
- Causa raíz: La topología de la placa base carece de aislamiento ACS; común en placas de consumo.
- Solución: Prueba diferentes ranuras PCIe, habilita Above 4G decoding, actualiza BIOS y solo entonces considera ACS override (sabiendo que puede debilitar el aislamiento).
5) Síntoma: el passthrough funciona una vez y luego falla tras reiniciar la VM
- Causa raíz: Problemas de reset del dispositivo (especialmente GPUs), bugs de firmware o peculiaridades de drivers en el invitado.
- Solución: Prueba múltiples ciclos de reinicio. Considera otra GPU, aplica workaround de reset específicos del proveedor solo si puedes validar la estabilidad. No pongas en producción algo que “funciona en el primer arranque”.
6) Síntoma: el host queda inalcanzable después de habilitar VFIO/enlazar una NIC
- Causa raíz: Enlazaste la NIC de gestión (o todo su grupo) a vfio-pci, dejando sin red al host.
- Solución: Desvincula quitando los ids/blacklists de vfio, reconstruye initramfs y reinicia. Usa consola fuera de banda. Y la próxima vez, revisa los grupos antes de enlazar.
7) Síntoma: “DMAR: DRHD: handling fault status” spam en los logs
- Causa raíz: Bugs en firmware/IOMMU, o un dispositivo haciendo DMA ilegal.
- Solución: Actualiza BIOS, confirma flags del kernel correctos, prueba desactivar ahorro de energía PCIe agresivo en el firmware. Si persiste, considera que la plataforma puede ser poco fiable para passthrough.
Tres mini-historias corporativas desde el terreno
Mini-historia 1: La caída causada por una suposición errónea
Un equipo con el que trabajé heredó un clúster Proxmox que “definitivamente soportaba passthrough”. Alguien lo había hecho una vez, en otro nodo, en otro rack, durante una ventana de migración. Eso se convirtió en verdad tribal. El siguiente paso fue pasar un HBA a una VM de almacenamiento—porque era la forma más rápida de importar un montón de discos.
Habilitaron VT-d en BIOS, añadieron intel_iommu=on a GRUB, reiniciaron y lo dieron por hecho. Luego enlazaron el HBA a vfio-pci. El host se cayó: bucle de arranque, dispositivo raíz perdido, el habitual silencio aterrador tras perder la sesión SSH. Las manos en sitio tuvieron que conectar un crash cart porque no había acceso fuera de banda. Fue una tarde larga.
La causa no fue exótica. El HBA que “pasaron” no era un HBA independiente. Era el controlador de almacenamiento integrado. Vivía en el mismo grupo IOMMU que las funciones del chipset que también alojaban el volumen de arranque. Asumieron que “el nombre del controlador parece HBA” significaba “seguro para passthrough”. El kernel no estuvo de acuerdo.
La solución fue aburrida: detenerse, mapear grupos IOMMU e instalar físicamente un HBA dedicado en una ranura que se agrupaba de forma limpia. Luego enlazar solo ese dispositivo. La lección no fue “ten cuidado”. La lección fue nunca asumir identidad por nombres de marketing. Las direcciones PCI y los grupos IOMMU son el único esquema de nombres fiable en la máquina.
Mini-historia 2: La optimización que salió mal
Otro entorno quería máximo rendimiento para una carga intensiva en GPU. Alguien leyó que la traducción IOMMU añade sobrecarga. Decidieron “optimizar” experimentando con distintos parámetros del kernel y ajustes del firmware hasta que los benchmarks parecían buenos. La configuración derivó: un nodo usaba iommu=pt, otro no, un tercero tenía ajustes PCIe distintos porque ese nodo “necesitaba eso para arrancar”.
Todo pareció bien por un tiempo. Luego empezaron a ver fallos raros y feos: VMs con passthrough de GPU colgaban bajo IO intenso mientras el host seguía en gran medida vivo. No era frecuente como para reproducir a demanda. Era frecuente como para quemar ingenieros. Buscaron drivers del invitado, luego versiones de QEMU, luego teorías sobre la fuente de alimentación. Ojalá fuera broma. No lo es.
El culpable final fue inconsistencia de configuración alrededor de IOMMU y remapeo de interrupciones combinado con versiones de BIOS ligeramente diferentes. Un nodo tuvo el remapeo de interrupciones deshabilitado por firmware tras una actualización. Bajo una carga específica, fue el que falló. La “optimización” no fue la causa directa; la falta de estandarización sí.
La recuperación fue operativa: estandarizar firmware, estandarizar la línea de comandos del kernel, aplicarlo con gestión de configuración y añadir una comprobación en arranque que alerte cuando IOMMU no esté activado. El rendimiento no bajó de forma significativa. La estabilidad mejoró mucho. Lo que salió mal no fue afinar—fue afinar sin disciplina.
Mini-historia 3: La práctica aburrida que salvó el día
Una tienda pequeña ejecutaba un par de nodos Proxmox para servicios internos. No eran sofisticados. Pero tenían un hábito que respeté: por cada nodo, mantenían un archivo simple de “mapeo de hardware” en su repo de ops—direcciones PCI, qué era cada dispositivo y para qué se permitía usarlo.
Cuando decidieron pasar una NIC a una VM firewall, no empezaron editando archivos modprobe. Empezaron verificando el mapeo, luego comprobando grupos IOMMU en vivo, luego planearon el cambio durante una ventana con acceso fuera de banda probado. También lo hicieron por etapas: enlazar VFIO, reiniciar, confirmar que el host seguía accesible, luego añadir el dispositivo a la VM.
El día del cambio, la NIC que querían pasar estaba agrupada con el controlador USB integrado. Pasarla habría dificultado la recuperación por consola remota si algo salía mal, porque su dongle IP KVM basado en USB estaba en ese controlador. No rompió nada, porque no continuaron. Movieron la NIC a otra ranura y los grupos mejoraron.
No pasó nada emocionante. Ese es el punto. La práctica “aburrida”—mantener un mapa de dispositivos y tratar los cambios como cambios—previno un incidente autoinfligido. La fiabilidad es mayormente el arte de no sorprenderse por tu propia infraestructura.
Una cita operativa (idea parafraseada)
Idea parafraseada: “La esperanza no es una estrategia.” — frecuentemente atribuida en círculos de operaciones, comúnmente asociada a la gestión de ingeniería pragmática (parafraseado)
Preguntas frecuentes
1) ¿Necesito UEFI para usar IOMMU en Proxmox?
No, pero UEFI tiende a proporcionar tablas de firmware mejores y menos sorpresas en hardware moderno. Si puedes elegir, elige UEFI y sé consistente entre nodos.
2) ¿Cuál es la diferencia entre VT-x y VT-d?
VT-x es la virtualización de CPU (ejecución eficiente de VMs). VT-d es el IOMMU (DMA seguro y passthrough PCI). Necesitas VT-x/SVM para las VMs; necesitas VT-d/AMD-Vi para passthrough.
3) ¿Debería usar siempre iommu=pt?
Para la mayoría de hosts Proxmox que hacen passthrough, sí: es un buen valor por defecto. Si buscas máximo aislamiento entre todos los dispositivos del host (mapeos más estrictos), quizá no lo uses—pero espera algo de sobrecarga.
4) Habilité IOMMU pero mis grupos son enormes. ¿Es seguro usar ACS override?
ACS override puede mejorar el agrupamiento forzando al kernel a tratar dispositivos como más aislados de lo que la topología sugiere. También puede reducir el aislamiento real. Úsalo solo si entiendes el riesgo y no pretendes que este host sea una plataforma multi-inquilino reforzada.
5) ¿Por qué Proxmox sigue quejándose después de cambiar opciones de BIOS?
Porque las opciones de BIOS no importan si los flags del kernel no se aplicaron, o cambiaste la configuración del gestor de arranque equivocado. Valida con /proc/cmdline y dmesg, no con esperanza.
6) ¿Puedo pasar mi controlador NVMe de arranque?
Puedes, pero no deberías si Proxmox arranca desde él. Si entregas el controlador a una VM, el host pierde acceso. Si quieres NVMe directo en la VM, instala un segundo controlador o usa un disco dedicado.
7) ¿ZFS cambia algo sobre IOMMU?
No directamente. ZFS afecta patrones de cmdline de arranque (por ejemplo, root=ZFS=...) y puede influir en cómo gestionas bootloaders (systemd-boot es común). IOMMU sigue siendo comportamiento de firmware + kernel.
8) ¿Cómo sé si un dispositivo es seguro para pasar?
Revisa su grupo IOMMU. Si el grupo contiene solo ese dispositivo (y sus funciones), estás bien. Si comparte con dispositivos críticos del host, mueve la tarjeta de ranura o replantea el plan.
9) Mi GPU está ligada a vfio-pci pero la VM no arranca. ¿Y ahora qué?
Comprueba quirks de reset y asegúrate de pasar todas las funciones (GPU + audio). Verifica el tipo de máquina y firmware de la VM (OVMF/UEFI es común para GPUs modernas). Luego revisa los logs de QEMU para el error real; suelen ser explícitos.
10) ¿Secure Boot puede causar “No IOMMU detected”?
Secure Boot suele afectar la carga de módulos y kernels firmados más que la detección de IOMMU en sí. Pero puede complicar la ruta de arranque y hacer que creas que aplicaste flags cuando no lo hiciste. Valida con /proc/cmdline.
Próximos pasos (qué hacer después de que funcione)
Una vez IOMMU esté activado y tus grupos se vean sensatos, no te quedes en “la VM arrancó”. Haz las comprobaciones operativas que previenen incidentes futuros:
- Pruebas de reinicio: Reinicia la VM repetidamente. Reinicia el host una vez. Si un dispositivo solo funciona tras un arranque en frío, es un problema de fiabilidad esperando a ocurrir en tu siguiente ventana de parches.
- Higiene de logs: Vigila
dmesgpor fallos DMAR/AMD-Vi durante carga. El spam de fallos no es “normal”. - Control de cambios: Registra versión de BIOS, modo de arranque, cmdline del kernel e ids vfio. Estandarízalo entre nodos si tienes más de uno.
- Limita el alcance del passthrough: Pasa solo el conjunto mínimo de dispositivos. No entregues a la VM el mundo entero porque era más fácil que pensar.
Si hiciste todo lo anterior y aún ves “No IOMMU detected”, estás en uno de esos pequeños e irritantes casos límite: firmware que miente, una plataforma sin VT-d/AMD-Vi real, o una ruta de bootloader que no habías detectado. Ahí es cuando dejas de cambiar cosas y empiezas a probar cada capa otra vez: firmware → cmdline → dmesg → groups. Los sistemas no responden a vibras. Responden a configuración.