IOMMU activado, pero los dispositivos siguen compartiendo grupo: arregla la topología PCIe como un profesional

¿Te fue útil?

Has activado los interruptores del BIOS. Linux dice que IOMMU está habilitado. Incluso ves DMAR o AMD-Vi en dmesg. Y aun así: tu GPU comparte un grupo IOMMU con un controlador USB, un HBA SATA y lo que parece la mitad de la placa base. VFIO se ríe en silencio en una esquina.

Aquí es donde la mayoría de las “guías de passthrough de GPU” se detienen y comienzan a recomendar parámetros de kernel al azar como si fueran condimentos. No lo hagas. Los grupos IOMMU compartidos no son moda; son un problema de topología. Arregla la topología y el aislamiento se vuelve aburrido. Aburrido es bueno.

El modelo mental: qué es realmente un grupo IOMMU

Un grupo IOMMU es el conjunto de funciones PCIe que no pueden aislarse de forma fiable entre sí para DMA. Si un dispositivo en un grupo puede iniciar transacciones DMA que alcancen las asignaciones de memoria de otro dispositivo sin ser bloqueadas, el kernel los trata como inseparables. VFIO no “quiere” grupos; aplica el aislamiento que el hardware puede demostrar.

Por qué “IOMMU habilitado” no es la victoria que crees

Activar IOMMU (Intel VT-d / AMD-Vi) da a la plataforma la capacidad de traducir y restringir DMA. No garantiza que cada endpoint PCIe obtenga su propia caja de arena ordenada. El aislamiento depende de la cadena de confianza entre el endpoint y la CPU: el root port, cualquier puerto aguas abajo, cualquier switch PCIe y la disponibilidad de Access Control Services (ACS) y controles relacionados a lo largo de esa ruta.

El límite de grupo suele ser el límite de un puente

En la práctica, los límites de grupos IOMMU suelen alinearse con puentes/puertos PCIe que pueden aplicar separación. Si tienes un solo puerto aguas abajo que alimenta múltiples endpoints (o un switch que no expone o no habilita ACS correctamente), Linux puede agruparlos. Esto no es que Linux sea antipático. Es Linux negándose a prometer aislamiento que no puede demostrar.

Idea parafraseada de James Hamilton (Amazon): “Mide todo, asume nada.” Se aplica dolorosamente bien a los grupos IOMMU: las suposiciones sobre topología son cómo terminas pasando tu controlador USB junto con la GPU.

Guía rápida de diagnóstico (qué comprobar primero)

Primero: confirma que IOMMU está realmente activo, no solo “configurado”

  • Revisa dmesg para líneas que indiquen DMAR/AMD-Vi habilitados y el estado de remapeo.
  • Comprueba que existen grupos IOMMU en /sys/kernel/iommu_groups.

Segundo: identifica los dispositivos exactos que te importan y su ruta aguas arriba

  • Asocia la GPU/HBA/NIC a direcciones PCI con lspci -nn.
  • Recorre el árbol PCIe con lspci -tv y lspci -vv.
  • Encuentra el puente aguas arriba y si ACS está presente/habilitado.

Tercero: decide si esto es solucionable en hardware/firmware o solo “solucionable” con overrides

  • Si los dispositivos comparten un grupo porque están detrás del mismo puerto aguas abajo sin ACS: cambia la ranura, habilita funciones del BIOS o cambia la plataforma.
  • Si comparten grupo porque el fabricante de la placa conectó varias ranuras a un mismo root port: acepta la realidad, rediseña o usa ACS override sabiendo lo que sacrificas.

Regla: si lo haces para fiabilidad en producción o cumplimiento, trata ACS override como último recurso y documentalo como si fuera una sustancia controlada.

Hechos e historia que explican el desorden actual

  1. VT-d y AMD-Vi llegaron mucho después de la virtualización de CPU. La virtualización temprana se centró en niveles de privilegio de CPU; el aislamiento DMA llegó más tarde y maduró lentamente entre chipsets.
  2. PCIe ACS es opcional. ACS es una capacidad que los dispositivos/puertos pueden o no implementar. Las características opcionales son donde los sueños van a morir.
  3. Los grupos IOMMU son una capa de política de Linux sobre realidades de hardware. El kernel forma grupos según garantías de aislamiento; no es una “función de passthrough”, es un límite de seguridad.
  4. Muchas placas de consumo optimizan líneas, no aislamiento. Dividir x16 en x8/x8 mediante el mismo root complex puede ser adecuado para rendimiento pero terrible para el agrupamiento.
  5. Los switches PCIe no son cajas mágicas de aislamiento. Algunos switches implementan ACS correctamente; otros no, o el firmware lo deja deshabilitado. Mismo número de pieza, distinto resultado según la placa.
  6. Los dispositivos multifunción pueden ser inseparables por diseño. Una GPU con función de audio suele ser un único dispositivo físico con múltiples funciones; esas funciones a menudo permanecen en el mismo grupo IOMMU.
  7. “ACS override” existe porque la gente lo siguió pidiendo. El kernel ganó perillas para relajar el agrupamiento para casos de virtualización. Es pragmático, no puro.
  8. Thunderbolt y PCIe externo introducen rarezas adicionales de topología. Los bridges de hotplug y los niveles de seguridad complican la confianza DMA y el comportamiento de agrupamiento.
  9. SR-IOV cambió expectativas. Cuando las NIC pudieron exponer múltiples VFs, todos esperaron un aislamiento ordenado—y luego descubrieron que la plataforma aún decide los grupos.

Tareas prácticas: comandos, salidas y decisiones (12+)

Estos son los chequeos que hago cuando alguien pregunta: “IOMMU está activado pero los grupos siguen compartidos”. Cada tarea incluye: un comando, lo que podrías ver y qué deberías hacer a continuación.

Tarea 1: Confirma que el kernel ve un IOMMU activo (Intel)

cr0x@server:~$ dmesg | grep -E "DMAR|IOMMU"
[    0.012345] DMAR: IOMMU enabled
[    0.012678] DMAR: Host address width 39
[    0.013210] DMAR: DRHD base: 0x000000fed90000 flags: 0x0
[    0.015432] DMAR: Intel(R) Virtualization Technology for Directed I/O

Significado: “IOMMU enabled” es la línea que quieres ver. Si solo ves tablas DMAR pero no habilitación, no estás remapeando DMA realmente.

Decisión: Si falta, arregla el BIOS (VT-d) y los argumentos del kernel (intel_iommu=on) antes de perder tiempo con los grupos.

Tarea 2: Confirma que el kernel ve un IOMMU activo (AMD)

cr0x@server:~$ dmesg | grep -E "AMD-Vi|IOMMU"
[    0.010101] AMD-Vi: IOMMU performance counters supported
[    0.010202] AMD-Vi: Found IOMMU at 0000:00:00.2 cap 0x40
[    0.010303] AMD-Vi: Interrupt remapping enabled

Significado: AMD-Vi detectado más remapeo de interrupciones habilitado es una buena señal para asignación segura de dispositivos.

Decisión: Si el remapeo de interrupciones está apagado, considera actualizaciones de firmware y toggles del BIOS; algunos sistemas son frágiles sin esto.

Tarea 3: Verifica que existan grupos IOMMU

cr0x@server:~$ ls -1 /sys/kernel/iommu_groups | head
0
1
2
3
4
5
6
7
8
9

Significado: Los grupos existen. Si el directorio está vacío o falta, no tienes agrupamiento IOMMU activo.

Decisión: No tener grupos significa parar y arreglar la habilitación (BIOS/kernel). Si hay grupos, sigue con la topología.

Tarea 4: Imprimir grupos con nombres de dispositivos (inventario rápido)

cr0x@server:~$ for g in /sys/kernel/iommu_groups/*; do echo "Group ${g##*/}"; for d in $g/devices/*; do lspci -nns ${d##*/}; done; echo; done | sed -n '1,35p'
Group 0
00:00.0 Host bridge [0600]: Intel Corporation Device [8086:1234]
00:01.0 PCI bridge [0604]: Intel Corporation Device [8086:5678]

Group 1
00:14.0 USB controller [0c03]: Intel Corporation Device [8086:a36d]
00:14.2 RAM memory [0500]: Intel Corporation Device [8086:a36f]

Group 2
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:2484]
01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:228b]

Significado: Esto te dice si la GPU está aislada (a menudo comparte con su función de audio, lo cual es normal) o atrapada con dispositivos no relacionados (malo).

Decisión: Si tu dispositivo objetivo comparte con controladores no relacionados, necesitas entender el puerto aguas arriba y ACS.

Tarea 5: Identifica el dispositivo y su driver del kernel (quién lo posee)

cr0x@server:~$ lspci -nnk -s 01:00.0
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:2484] (rev a1)
	Subsystem: Micro-Star International Co., Ltd. [MSI] Device [1462:xxxx]
	Kernel driver in use: nouveau
	Kernel modules: nouveau, nvidiafb

Significado: Si un driver del host está ligado, VFIO passthrough peleará contigo al iniciar o cuando la VM arranque.

Decisión: Vincula a vfio-pci (o un stub) solo después de confirmar que el grupo es aceptable. No “arregles” el agrupamiento cambiando drivers; no servirá.

Tarea 6: Mostrar la topología PCIe como árbol (encuentra el puente padre)

cr0x@server:~$ lspci -tv
-+-[0000:00]-+-00.0  Host bridge
 |           +-01.0-[01]----00.0  VGA compatible controller
 |           |            \-00.1  Audio device
 |           +-14.0  USB controller
 |           +-17.0  SATA controller
 |           \-1d.0-[02]----00.0  Ethernet controller

Significado: Tu GPU está detrás de 00:01.0. Si múltiples endpoints están bajo el mismo segmento aguas abajo y agrupados, el puerto aguas arriba puede no aislar.

Decisión: Si la ranura de la GPU y un controlador onboard están bajo el mismo puente en el árbol, probablemente tengas una limitación de cableado/topología. Considera mover tarjetas/ranuras.

Tarea 7: Inspeccionar capacidades ACS en el puerto aguas arriba

cr0x@server:~$ sudo lspci -vv -s 00:01.0 | grep -A8 -i "Access Control Services"
	Access Control Services
		ACSCap: SrcValid+ TransBlk+ ReqRedir+ CmpltRedir+ UpstreamFwd+ EgressCtrl+ DirectTrans+
		ACSCtl: SrcValid+ TransBlk- ReqRedir- CmpltRedir- UpstreamFwd- EgressCtrl- DirectTrans-

Significado: La capacidad existe, pero los controles pueden estar deshabilitados. Algunas plataformas dejan los bits ACSCtl apagados.

Decisión: Si ACSCap falta por completo en los puertos relevantes, es improbable obtener divisiones limpias sin overrides o hardware distinto. Si está presente pero deshabilitado, el firmware/kernel podría permitir habilitarlo.

Tarea 8: Comprueba si la plataforma usa el modo de traducción que esperas

cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.8.0 root=UUID=... ro quiet intel_iommu=on iommu=pt

Significado: intel_iommu=on habilita el remapeo. iommu=pt establece passthrough para dispositivos del host (a menudo mejora rendimiento para dispositivos no asignados).

Decisión: Si estás depurando aislamiento, mantenlo simple: habilita explícitamente IOMMU y evita parámetros exóticos hasta entender la línea base.

Tarea 9: Confirma el estado de remapeo de interrupciones / posted interrupts (sanidad para passthrough)

cr0x@server:~$ dmesg | grep -E "Interrupt Remapping|IR|x2apic" | head -n 20
[    0.013333] DMAR-IR: Enabled IRQ remapping in x2apic mode
[    0.013444] DMAR-IR: Queued invalidation will be enabled to support x2apic and Intr-remapping.

Significado: El remapeo de IRQ reduce la probabilidad de que interrupciones se entreguen al lugar equivocado bajo asignación.

Decisión: Si está deshabilitado, trata el passthrough como de mayor riesgo; prioriza actualizaciones de firmware o cambios de plataforma si es producción.

Tarea 10: Comprueba si tu GPU está en un grupo con un puente que no controlas

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

Significado: Confirma el número de grupo desde la perspectiva del dispositivo.

Decisión: Si el grupo contiene dispositivos que no puedes pasar juntos, tu siguiente paso es la remediación de topología, no ajustes de VFIO.

Tarea 11: Identifica qué dispositivos comparten el grupo (quién más está en la sala)

cr0x@server:~$ G=$(basename $(readlink /sys/bus/pci/devices/0000:01:00.0/iommu_group)); for d in /sys/kernel/iommu_groups/$G/devices/*; do lspci -nnk -s ${d##*/}; echo; done
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:2484] (rev a1)
	Kernel driver in use: nouveau
	Kernel modules: nouveau, nvidiafb

01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:228b] (rev a1)
	Kernel driver in use: snd_hda_intel
	Kernel modules: snd_hda_intel

Significado: ¿Solo GPU + su función de audio? Eso suele estar bien. ¿GPU + USB + SATA? Eso es una restricción de diseño.

Decisión: Si ves dispositivos no relacionados, decides entre: mover tarjetas/ranuras, ajustes de BIOS, otra placa/CPU, o ACS override (con riesgo).

Tarea 12: Comprueba si hay un switch PCIe en la ruta (común en servidores, furtivo en estaciones de trabajo)

cr0x@server:~$ lspci -nn | grep -i "PCI bridge\|PLX\|Broadcom\|PEX"
00:01.0 PCI bridge [0604]: Intel Corporation Device [8086:5678]
03:00.0 PCI bridge [0604]: Broadcom / PLX Device [10b5:8725]
03:01.0 PCI bridge [0604]: Broadcom / PLX Device [10b5:8725]

Significado: Los switches suelen aparecer como múltiples funciones de puente. Si aíslan depende de ACS y configuración.

Decisión: Si hay un switch involucrado, debes inspeccionar ACS en esos puertos aguas abajo, no solo en el root port.

Tarea 13: Valida la vista del kernel sobre el aislamiento con un escaneo ACS dirigido

cr0x@server:~$ for dev in 00:01.0 03:00.0 03:01.0; do echo "== $dev =="; sudo lspci -vv -s $dev | grep -A6 -i "Access Control Services"; done
== 00:01.0 ==
	Access Control Services
		ACSCap: SrcValid+ TransBlk+ ReqRedir+ CmpltRedir+ UpstreamFwd+ EgressCtrl+ DirectTrans+
		ACSCtl: SrcValid+ TransBlk- ReqRedir- CmpltRedir- UpstreamFwd- EgressCtrl- DirectTrans-
== 03:00.0 ==
	Access Control Services
		ACSCap: SrcValid+ TransBlk- ReqRedir+ CmpltRedir+ UpstreamFwd+ EgressCtrl- DirectTrans-
		ACSCtl: SrcValid+ TransBlk- ReqRedir- CmpltRedir- UpstreamFwd- EgressCtrl- DirectTrans-

Significado: Las capacidades varían por puerto. Algunos puertos pueden hacer request redirection pero no upstream forwarding, etc.

Decisión: Si los puertos necesarios carecen de ACS, no obtienes aislamiento seguro, punto. Planea cambios de hardware o acepta el agrupamiento.

Tarea 14: Comprueba si la plataforma fuerza “Above 4G decoding” / efectos Resizable BAR

cr0x@server:~$ dmesg | grep -iE "Resizable BAR|Above 4G|pci 0000"
[    0.222222] pci 0000:01:00.0: BAR 0: assigned [mem 0x8000000000-0x800fffffff 64bit pref]
[    0.222333] pci 0000:01:00.0: BAR 2: assigned [mem 0x8010000000-0x8011ffffff 64bit pref]

Significado: Mapas de BAR grandes no son un problema de agrupamiento, pero pueden exponer bugs de firmware y problemas de asignación de recursos que se hacen pasar por dolores de cabeza de VFIO.

Decisión: Si ves errores de asignación de recursos o BARs faltantes, arregla eso primero; una inicialización de dispositivo rota puede hacerte perseguir “problemas IOMMU” fantasma.

Tarea 15: Confirma la viabilidad de VFIO sin comprometer (pensamiento de ensayo)

cr0x@server:~$ sudo dmesg | tail -n 20
[  120.123456] vfio-pci 0000:01:00.0: enabling device (0000 -> 0003)
[  120.123789] vfio-pci 0000:01:00.0: vfio_bar_restore: reset recovery - restoring BARs
[  120.124111] vfio-pci 0000:01:00.1: enabling device (0000 -> 0002)

Significado: Cuando enlazas, el kernel registra lo que hace. Los errores aquí a menudo indican quirks de reset, no agrupamiento.

Decisión: Si el binding funciona limpiamente pero el grupo está compartido, no te alegres. Aún no puedes asignar de forma segura parte de un grupo compartido.

Broma #1: Un grupo IOMMU es como una sala de reuniones reservada: si aparece tu controlador USB, todos se van con tus rotuladores del pizarrón.

Clínica de topología PCIe: puertos raíz, puentes, switches y ACS

Empieza por la ruta aguas arriba, no por el endpoint

La gente se obsesiona con el modelo de GPU y olvida lo aburrido: el tejido PCIe. Tu dispositivo endpoint solo es tan aislable como el puente menos capaz entre él y la CPU. Eso incluye:

  • Root port / root complex en la CPU o el chipset.
  • Puertos aguas abajo (a menudo parte de un switch o tejido del chipset).
  • Switches PCIe (PLX/Broadcom, ASMedia, etc.).
  • Endpoints integrados (audio integrado, controladores USB, SATA, Wi‑Fi).

ACS: qué hace y por qué cambia el agrupamiento

Access Control Services es un conjunto de funciones que ayudan a prevenir o controlar el tráfico peer-to-peer y garantizar que las solicitudes se encaminen correctamente hacia arriba donde IOMMU puede aplicar políticas. En términos sencillos: ACS ayuda a evitar que dispositivos detrás del mismo switch/puerto se comuniquen entre sí sin pasar por IOMMU.

Linux usa la información de ACS (y otras pistas de topología) para decidir si los dispositivos pueden separarse en distintos grupos IOMMU. Si la plataforma no puede garantizar aislamiento, el grupo permanece grande.

Patrones típicos “¿por qué mi GPU está agrupada con X?”

  • Fan-out del puerto aguas abajo del chipset: múltiples controladores onboard están detrás de un puerto del chipset sin ACS, por lo que se agrupan.
  • Switch compartido: dos ranuras físicas están realmente detrás de un switch PCIe sin configuración ACS adecuada.
  • Multiplexado de líneas en la placa: habilitar una segunda ranura M.2 rerutea líneas y cambia qué dispositivos comparten un root port.
  • Dispositivos multifunción: video + audio de GPU comparten. Esto es normal y normalmente deseable para passthrough.

Qué significa realmente “arreglar la topología”

No es místico. Es una de estas acciones:

  1. Mover la tarjeta a otra ranura que dependa de un root port distinto (idealmente conectado a la CPU).
  2. Dejar de usar una ranura/M.2 que obliga a compartir líneas con algo que necesitas aislar.
  3. Habilitar las funciones de firmware que exponen ACS o el remapeo correcto (cuando existan).
  4. Usar hardware que realmente soporte aislamiento: placas workstation/servidor, switches conocidos, CPUs con suficientes líneas.
  5. Aceptar el agrupamiento y pasar todo el grupo si eso es seguro y operativamente aceptable.

La mayoría de los “problemas de grupos IOMMU” son tu placa base diciéndote en secreto que fue diseñada para RGB de juegos, no para límites de DMA confiables.

Ajustes de BIOS/firmware que importan (y los que no)

Ajustes que suelen importar

  • Intel: VT-d (Directed I/O) debe estar habilitado. VT-x por sí solo no es suficiente.
  • AMD: SVM habilita la virtualización de CPU; IOMMU (o “AMD-Vi”) habilita el remapeo DMA. Normalmente necesitas ambos para passthrough.
  • Above 4G decoding: a menudo requerido para GPUs modernas y múltiples dispositivos PCIe; también puede influir en cómo el firmware asigna recursos.
  • SR-IOV: habilitarlo puede cambiar cómo el firmware configura puertos aguas abajo y ARI; no es obligatorio para passthrough, pero relevante para VFs de NIC.
  • PCIe ACS / toggles “PCIe ARI”: si tu BIOS expone algo semejante a ACS, habilítalo. Si expone ARI, habilítalo cuando uses muchas VFs SR-IOV.

Ajustes que la gente cambia por desesperación

  • CSM (Compatibility Support Module): desactivarlo puede ayudar a la inicialización de GPUs modernas y al dimensionado de BARs, pero no dividirá mágicamente los grupos IOMMU.
  • Forzar velocidad PCIe Gen: a veces arregla estabilidad del enlace; rara vez afecta el agrupamiento.
  • “Modo gaming”: si el BIOS tiene esto, aléjate despacio.

Actualizaciones de firmware: la solución poco glamorosa

Las actualizaciones del BIOS de la placa base y del BMC/UEFI del servidor pueden cambiar la exposición de ACS, los quirks de remapeo y la asignación de recursos PCIe. No es divertido. También es la diferencia entre “funciona durante meses” y “fallo DMA aleatorio a las 3 AM”.

Parámetros del kernel, ACS override y cuándo rechazarlos

Los parámetros que verás en el campo

  • intel_iommu=on / amd_iommu=on: habilitación explícita.
  • iommu=pt: modo passthrough para dispositivos del host (compensaciones rendimiento/latencia).
  • pcie_acs_override=downstream,multifunction: fuerza al kernel a tratar algunos puertos como si existiera separación ACS.

Qué hace realmente ACS override

Cambia las decisiones de agrupamiento de Linux fingiendo que ciertos componentes PCIe proporcionan límites de aislamiento incluso cuando no anuncian las capacidades ACS correctas. Eso puede producir grupos IOMMU más pequeños y hacer feliz a VFIO.

También puede crear un límite de aislamiento que no es real. En un modelo de amenaza con dispositivos hostiles o comprometidos, eso no es aceptable. En un homelab, la gente acepta el riesgo. En producción, necesitas una conversación seria con seguridad y propietarios de riesgo.

Cuándo usaré ACS override

  • Entornos de laboratorio donde el único “atacante” es mi propia impaciencia.
  • Validaciones temporales en una plataforma que ya planeamos reemplazar, para demostrar que la carga es viable.
  • Situaciones donde el dispositivo passthrough es el único endpoint DMA significativo en el grupo y el resto está esencialmente inerte (raro).

Cuándo rechazo ACS override

  • Entornos multi-inquilino.
  • Cualquier cosa con requisitos de cumplimiento sobre aislamiento.
  • Sistemas donde el grupo compartido contiene almacenamiento o red de los que depende el host para sobrevivir.

Broma #2: ACS override es como poner cinta de “No Entrar” en una puerta sin puerta. Te hace sentir más seguro hasta que alguien pasa por ella.

Detalles del stack de virtualización: Proxmox/KVM, metal desnudo y equipos “enterprise”

Chequeo de realidad KVM/VFIO

VFIO es estricto porque es el último adulto en la sala. Si un grupo contiene múltiples dispositivos, VFIO quiere que asignes todo el grupo a un único invitado, porque dividirlo es como terminas con comportamiento indefinido y agujeros de seguridad.

En la práctica, “necesito pasar solo la GPU” significa que la grupo de la GPU debe contener solo las funciones de la GPU (y quizá un controlador USB si realmente vas a pasar todo un controlador para dispositivos de entrada).

Proxmox y stacks similares

Proxmox facilita ver grupos y configurar VFIO, pero no puede arreglar una placa base que soldó tu ranura de GPU al mismo puerto aguas abajo que tu controlador SATA. Si Proxmox muestra un grupo gordo, créelo.

Placas de estación de trabajo vs servidor

Los servidores a menudo tienen mejor distribución de líneas y diseños de switches PCIe más previsibles. Las estaciones de trabajo también pueden ser buenas. Las placas de consumo son el salvaje oeste: a veces tienes suerte, a veces el tejido del chipset es un autobús de fiesta.

Nota del ingeniero de almacenamiento: no compartas grupos con HBAs a la ligera

Si el grupo contiene tu HBA o controlador NVMe usado por el host, estás a una mala decisión de entregar tu controlador de almacenamiento a una VM. Eso no es “ajuste de rendimiento.” Es ruleta de pérdida de datos.

Tres mini-historias corporativas desde el frente

1) El incidente causado por una suposición errónea

Estaban construyendo un pequeño clúster interno de GPU para acelerar builds y algo de inferencia ML. Nada exótico: KVM, VFIO, unas GPUs de gama media y una placa estandarizada porque compras quería “estandarización”. Alguien verificó que IOMMU estaba habilitado en BIOS y comprobó que dmesg mostraba DMAR. Declararon la plataforma “lista para passthrough”.

Los dos primeros nodos funcionaron porque las GPUs estaban en una ranura conectada directamente a los root ports de la CPU. El tercer nodo se ensambló ligeramente distinto—misma placa, pero se añadió un carrier NVMe extra. Ese carrier cambió la bifurcación de líneas y empujó la ranura de la GPU detrás de una ruta por switch del chipset. Nadie lo notó porque las GPUs seguían apareciendo bien en lspci.

En ese nodo, la GPU terminó en el mismo grupo IOMMU que un controlador USB y un controlador SATA. El ingeniero que configuraba VFIO asumió “los grupos son solo cosa de Linux” y forzó ACS override para separarlos. El sistema pasó las pruebas iniciales. Una semana después, durante un pico de trabajo, el host experimentó errores intermitentes de SATA y después un sistema de archivos se volvió de solo lectura. El postmortem no fue glamuroso: habían creado un límite de aislamiento falso, y el DMA intenso de la carga de GPU se correlacionó con anomalías de I/O del host.

La solución fue dolorosamente ordinaria: mover la GPU a otra ranura, deshabilitar la opción de compartición de líneas y estandarizar el ensamblaje para que cada nodo tuviera la misma topología PCIe. También prohibieron ACS override en producción salvo aprobación. La lección real no fue “ACS override es malvado.” Fue que “IOMMU habilitado” no es lo mismo que “aislamiento IOMMU conseguido”, y la deriva de topología es un bug de fiabilidad.

2) La optimización que salió mal

Un equipo quería reducir la latencia para una VM de procesamiento de paquetes de alto rendimiento. Planeaban pasar una NIC y una GPU a la VM para inferencia en línea. El host también tenía un NVMe rápido usado para caché local. Alguien notó que la NIC y el NVMe estaban en el mismo grupo IOMMU en una generación de plataforma particular.

En lugar de cambiar hardware, hicieron un movimiento “ingenioso”: pasaron todo el grupo a la VM, razonando que la VM era “la carga real” y que el host podía arrancar desde un DOM SATA espejado. En papel, redujo la sobrecarga y evitó lidiar con divisiones de grupo. Incluso mejoró en benchmarks.

Entonces operaciones planteó las preguntas aburridas. ¿Cómo parcheas el host si la VM posee el controlador de almacenamiento usado para caché y logs? ¿Cómo capturas volcados de kernel? ¿Qué pasa si la VM se queda colgada y mantiene la función PCIe en un estado de reset malo? La respuesta fue: reinicias y rezas. Eso no es un plan, es un ritual.

La optimización falló cuando la VM encontró un bug de driver y dejó de responder. El host seguía “arriba” pero perdió acceso a los dispositivos passthrough, incluido el NVMe de caché. El monitoreo se volvió ruidoso y el nodo empezó a subir y bajar del servicio. Revirtieron a un diseño menos “eficiente”: separar grupos IOMMU eligiendo una disposición de ranuras diferente y usar una plataforma con más root ports, manteniendo el almacenamiento crítico del host fuera de cualquier grupo passthrough. El rendimiento bajó un poco. La disponibilidad mejoró mucho. Nadie extrañó las heroicidades.

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

Otra organización corría cargas mixtas: algunas VMs con passthrough de NIC (VFs SR-IOV), otras con passthrough completo de dispositivos aceleradores. Ya les había pasado antes, así que tenían una política: cada SKU de hardware tenía un “manifiesto de topología PCIe” en el mismo repo que el código de aprovisionamiento.

Cuando llegó un nuevo lote de servidores, procurement sustituyó una revisión de placa “compatible” por restricciones de suministro. Misma familia de CPU, mismo chasis, todo igual para un no experto. El chequeo del manifiesto en CI comparó el layout de grupos IOMMU esperado con lo que reportaba un nodo recién arrancado. Falló inmediatamente.

En lugar de descubrir el problema en producción tras una actualización nocturna del kernel, pusieron la tanda en cuarentena. La causa raíz fue una configuración distinta del switch PCIe en la nueva revisión: la ranura del acelerador y un controlador RAID onboard ahora compartían un puerto aguas abajo sin separación ACS usable. El proveedor pudo ofrecer una actualización de firmware para algunos, y para otros la solución fue un riser distinto.

La práctica fue aburrida: arrancar, recoger lspci, recoger mapeos de grupos, comparar con lo esperado, fallar rápido. Les ahorró días de debugging y evitó un incidente lento. Este tipo de “paperwork” realmente aumenta la disponibilidad del sistema, por eso la gente lo odia hasta que les salva.

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

1) “Habilité IOMMU pero /sys/kernel/iommu_groups está vacío”

Síntoma: No hay entradas en el directorio de grupos, VFIO se queja, las guías dicen “habilita IOMMU”.

Causa raíz: VT-d/AMD-Vi está apagado en BIOS, o los parámetros de arranque del kernel no lo habilitan, o estás en un modo de firmware que oculta el remapeo.

Solución: Habilita VT-d/AMD IOMMU en BIOS; añade intel_iommu=on o amd_iommu=on; actualiza BIOS si las tablas DMAR están rotas.

2) “Mi GPU comparte un grupo con USB/SATA/NIC en la placa”

Síntoma: El grupo incluye GPU más controladores onboard no relacionados.

Causa raíz: Los dispositivos están detrás del mismo puerto/switch aguas abajo sin aislamiento ACS; el cableado de la placa prioriza compartición de líneas sobre aislamiento.

Solución: Mueve la GPU a una ranura conectada a la CPU; deshabilita características de compartición de líneas; evita combos M.2/riser que rerutean líneas; elige una placa con mejor distribución de root ports.

3) “Usé ACS override y funciona, pero obtengo errores aleatorios de I/O del host”

Síntoma: El passthrough funciona, pero el host tiene raros problemas PCIe/SATA/NVMe bajo carga.

Causa raíz: Forzar la división creó un límite que el hardware no hace cumplir; las interacciones peer-to-peer y DMA se vuelven indefinidas.

Solución: Quita ACS override; rediseña la topología; aísla mediante puertos con ACS real o pasa todo el grupo real si es seguro.

4) “Los problemas de reset de GPU parecen problemas IOMMU”

Síntoma: El apagado de la VM deja la GPU inutilizable, el siguiente arranque de VM falla, errores en dmesg sobre reset.

Causa raíz: Quirks de reset de GPU (FLR no soportado bien), comportamiento del driver del proveedor, o manejo de multifunción—no el agrupamiento IOMMU.

Solución: Usa mecanismos de reset soportados por el proveedor (cuando aplique), considera modelos de GPU distintos, asegura que ambas funciones de la GPU estén ligadas apropiadamente, evita reasignaciones en caliente en producción.

5) “VFs SR-IOV están en grupos enormes y no se pueden asignar limpiamente”

Síntoma: Las VFs comparten grupos con PFs y otros dispositivos de formas inesperadas.

Causa raíz: ARI/ACS/configuración de firmware; la plataforma los agrupa porque no puede garantizar aislamiento.

Solución: Habilita SR-IOV y ARI en BIOS si está disponible; asegura firmware actualizado; usa NICs y plataformas conocidas por comportarse bien con VFIO.

6) “Todo está en un solo grupo en un portátil/mini PC”

Síntoma: Un grupo gigante, sin divisiones limpias, los sueños de GPU externa se desvanecen.

Causa raíz: Topología integrada con ACS limitado, tejido enraizado en el chipset y un modelo de seguridad no diseñado para aislamiento determinista.

Solución: Acepta las limitaciones; usa dispositivos paravirtualizados; o cambia a hardware diseñado para esto.

Listas de verificación / plan paso a paso

Paso a paso: pasar de “grupo compartido” a “aislamiento limpio”

  1. Habilitación base: confirma DMAR/AMD-Vi habilitado en dmesg y que existen grupos.
  2. Identifica objetivos: lista direcciones PCI de los dispositivos que quieres asignar.
  3. Mapea grupos: imprime la pertenencia a grupos y confirma quién comparte con quién.
  4. Dibuja la cadena aguas arriba: usa lspci -tv para localizar los puentes/puertos aguas arriba.
  5. Revisa ACS en cada puerto relevante: lspci -vv en los puertos root/downsream en la ruta.
  6. Prueba la solución de topología fácil: mueve la tarjeta a otra ranura; quita/reloca tarjetas M.2/riser que causan reruteo de líneas.
  7. Vuelve a comprobar los grupos tras cada cambio físico: no hagas cambios en lote; perderás causalidad.
  8. Ajustes de firmware: habilita VT-d/AMD IOMMU, Above 4G decoding, SR-IOV/ARI si corresponde; actualiza BIOS.
  9. Decide tu postura de riesgo: si necesitas ACS override, documenta por qué, qué hay en el grupo y cuál es el radio de impacto.
  10. Enlaza drivers solo después de que el aislamiento sea correcto: asigna dispositivos a vfio-pci cuando los grupos sean sensatos.
  11. Prueba rutas de reset: arranca/para la VM repetidamente y vigila si el dispositivo queda bloqueado.
  12. Operationaliza: captura topología + mapeo de grupos como artefacto para detectar deriva futura.

Checklist: preparación para producción del passthrough

  • Los dispositivos críticos del host para almacenamiento/red no están en ningún grupo que planees asignar.
  • No hay ACS override en producción salvo aceptación explícita del riesgo.
  • Las versiones de firmware están fijadas y testeadas con chequeos de regresión de topología.
  • El comportamiento de reset de los dispositivos está validado (cold boot, warm reboot, ciclos start/stop de VM).
  • El monitoreo incluye errores PCIe AER, fallos IOMMU y resets de drivers de dispositivos.

Checklist: cuándo debes parar y comprar hardware distinto

  • Tu dispositivo objetivo comparte grupo con SATA/USB/NVMe del chipset que necesitas en el host, y no hay ranura/root port alternativa.
  • Los puertos aguas arriba carecen de ACS y no puedes cambiar la topología.
  • El firmware no ofrece toggles relevantes y las actualizaciones no cambian el comportamiento.
  • El sistema necesita ACS override para funcionar y estás en un entorno multi-inquilino o regulado.

Preguntas frecuentes

1) Si IOMMU está habilitado, ¿por qué mis dispositivos siguen en el mismo grupo?

Porque habilitar no es aislar. El agrupamiento refleja si el tejido PCIe puede aplicar separación (ACS/comportamiento de puentes), no si el remapeo DMA existe en teoría.

2) ¿Es normal que una GPU y su función de audio compartan grupo?

Sí. Es un dispositivo físico exponiendo múltiples funciones PCI. Normalmente pasas ambas juntas.

3) ¿Puedo pasar solo un dispositivo de un grupo compartido?

No de forma segura. VFIO requiere asignación a nivel de grupo porque cualquier dispositivo del grupo podría hacer DMA que afecte a los demás. Si lo separas igual (por hacks), aceptas comportamiento indefinido y riesgo de seguridad.

4) ¿Habilitar “Above 4G decoding” dividirá mis grupos IOMMU?

Normalmente no. Ayuda a la asignación de recursos y al mapeo de BARs grandes, lo que puede arreglar problemas de arranque/probe, pero no crea por sí mismo límites de aislamiento.

5) ¿Afecta iommu=pt al agrupamiento?

No. Afecta cómo el host mapea DMA para dispositivos que el host conserva, a menudo mejorando rendimiento. La formación de grupos trata sobre topología y ACS, no sobre passthrough vs mappings traducidos.

6) ¿Cuál es la alternativa más segura si no consigo grupos limpios?

No hagas passthrough completo de dispositivos. Usa dispositivos paravirtualizados (virtio), compartición a nivel de API para GPU (cuando aplique), o cambia a hardware con mejor aislamiento PCIe.

7) ¿Por qué mis grupos IOMMU cambian al añadir una unidad NVMe o usar otra ranura M.2?

Compartición de líneas y bifurcación. Muchas placas rerutean líneas según qué sockets estén poblados. Eso puede mover dispositivos detrás de distintos puentes/switches, cambiando el aislamiento.

8) ¿ACS override es siempre inseguro?

Relaja las suposiciones de aislamiento del kernel. En un modelo de amenaza estricto, sí, socava la garantía que crees tener. En un laboratorio de un solo usuario, muchos lo aceptan. La clave es ser honesto sobre el límite que estás fingiendo.

9) Mis grupos están bien, pero el passthrough sigue fallando. ¿Y ahora?

Revisa el binding del driver, el comportamiento de reset del dispositivo, errores de asignación de recursos en firmware y si el dispositivo soporta FLR. El agrupamiento es necesario, no suficiente.

10) ¿Por qué los servidores “simplemente funcionan” más que los desktops?

Más root ports, mejor presupuesto de líneas, diseños de switches más consistentes y firmware que toma ACS y SR-IOV en serio. Además: los proveedores esperan que clientes de virtualización se quejen fuerte.

Conclusión: pasos siguientes que realmente mueven la aguja

Si IOMMU está activado pero tus dispositivos siguen compartiendo grupo, deja de tratarlo como un rompecabezas de parámetros del kernel. Es una investigación de topología PCIe. Haz el trabajo aburrido: mapea el árbol, identifica los puertos aguas arriba, verifica capacidades ACS y cambia el diseño físico o la plataforma hasta que el hardware pueda demostrar aislamiento.

Pasos siguientes:

  1. Ejecuta el comando de inventario de grupos y resalta los co-inquilinos no deseados exactos en tu grupo objetivo.
  2. Usa lspci -tv y lspci -vv para encontrar la cadena de puentes aguas arriba y si ACS existe donde importa.
  3. Prueba un cambio de topología a la vez: mueve la tarjeta a otra ranura, cambia la población de M.2, alterna la bifurcación/ajustes PCIe, actualiza firmware.
  4. Si aún necesitas ACS override, anota el riesgo, qué dispositivos comparten el tejido y cómo se vería una falla—luego decide como un adulto.
  5. Operationaliza: captura tus grupos IOMMU conocidos buenos como prueba de regresión para que una “revisión menor de hardware” no se convierta en tu próximo incidente.
← Anterior
Redes en Docker: la única interpretación errónea de NAT/firewall que expone todo
Siguiente →
Clon vs Imagen vs Respaldo: ¿Cuál Restaura Más Rápido Cuando Ocurre un Desastre?

Deja un comentario