Tengo debajo de los grupos y dispositivos IOMMU.
$ for a in /sys/kernel/iommu_groups/*; do find $a -type l; done | sort --version-sort
/sys/kernel/iommu_groups/0/devices/0000:00:00.0
/sys/kernel/iommu_groups/1/devices/0000:00:02.0
/sys/kernel/iommu_groups/2/devices/0000:00:04.0
/sys/kernel/iommu_groups/3/devices/0000:00:14.0
/sys/kernel/iommu_groups/3/devices/0000:00:14.2
/sys/kernel/iommu_groups/4/devices/0000:00:15.0
/sys/kernel/iommu_groups/4/devices/0000:00:15.1
/sys/kernel/iommu_groups/5/devices/0000:00:16.0
/sys/kernel/iommu_groups/6/devices/0000:00:17.0
/sys/kernel/iommu_groups/7/devices/0000:00:1c.0
/sys/kernel/iommu_groups/7/devices/0000:00:1c.7
/sys/kernel/iommu_groups/7/devices/0000:01:00.0
/sys/kernel/iommu_groups/7/devices/0000:02:00.0
/sys/kernel/iommu_groups/8/devices/0000:00:1f.0
/sys/kernel/iommu_groups/8/devices/0000:00:1f.2
/sys/kernel/iommu_groups/8/devices/0000:00:1f.3
/sys/kernel/iommu_groups/8/devices/0000:00:1f.4
Me gustaría aislar ese dispositivo específico /sys/kernel/iommu_groups/7/devices/0000:01:00.0
en su propio grupo sin otros dispositivos en el mismo grupo.
¿Cómo podemos aislar un solo dispositivo en un grupo IOMMU separado para el paso PCI para la máquina virtual KVM?
Respuesta1
Sé que esta es una vieja pregunta, pero tuve que intentar resolverla recientemente.
La regla general con IOMMU es que el núcleo determinará las asignaciones por usted. Cuando el kernel arranca, buscará qué dispositivos pueden asignarse a un mapa virtual de E/S (IOVA). Si los dispositivos tienen el mismo IOVA entonces terminan en el mismo grupo. Esto se hace para garantizar que cada grupo tenga dispositivos a los que realmente se pueda direccionar y hablar por separado.
Hay un par de soluciones. La primera es que puedes intentar mover la tarjeta a otra posición en la placa base. Si es una tarjeta PCI y no PCIe, entonces probablemente no tenga suerte, ya que todos los puertos PCI probablemente estén asignados al mismo puente PCIe y, por lo tanto, compartirán el mismo IOVA.
Si realmente aún necesita hacerlo, puede tomar todos los dispositivos que están en el mismo grupo y asignarlos todos a vfio-pci y luego puede hacer las asignaciones a donde deben ir los dispositivos.
En mi máquina, por ejemplo, el grupo 13 tiene un montón de dispositivos que incluyen una tarjeta de video adicional (18:00). Aquí está mi salida de ese directorio:
root@rwl01:/sys/kernel/iommu_groups/13/devices# ll
total 0
drwxr-xr-x 2 root root 0 Feb 15 15:43 .
drwxr-xr-x 3 root root 0 Feb 15 15:43 ..
lrwxrwxrwx 1 root root 0 Feb 15 15:43 0000:03:00.0 -> ../../../../devices/pci0000:00/0000:00:01.3/0000:03:00.0
lrwxrwxrwx 1 root root 0 Feb 15 15:43 0000:03:00.1 -> ../../../../devices/pci0000:00/0000:00:01.3/0000:03:00.1
lrwxrwxrwx 1 root root 0 Feb 15 15:43 0000:03:00.2 -> ../../../../devices/pci0000:00/0000:00:01.3/0000:03:00.2
lrwxrwxrwx 1 root root 0 Feb 15 15:43 0000:16:00.0 -> ../../../../devices/pci0000:00/0000:00:01.3/0000:03:00.2/0000:16:00.0
lrwxrwxrwx 1 root root 0 Feb 15 15:43 0000:16:01.0 -> ../../../../devices/pci0000:00/0000:00:01.3/0000:03:00.2/0000:16:01.0
lrwxrwxrwx 1 root root 0 Feb 15 15:43 0000:16:02.0 -> ../../../../devices/pci0000:00/0000:00:01.3/0000:03:00.2/0000:16:02.0
lrwxrwxrwx 1 root root 0 Feb 15 15:43 0000:16:03.0 -> ../../../../devices/pci0000:00/0000:00:01.3/0000:03:00.2/0000:16:03.0
lrwxrwxrwx 1 root root 0 Feb 15 15:43 0000:16:04.0 -> ../../../../devices/pci0000:00/0000:00:01.3/0000:03:00.2/0000:16:04.0
lrwxrwxrwx 1 root root 0 Feb 15 15:43 0000:16:08.0 -> ../../../../devices/pci0000:00/0000:00:01.3/0000:03:00.2/0000:16:08.0
lrwxrwxrwx 1 root root 0 Feb 15 15:43 0000:17:00.0 -> ../../../../devices/pci0000:00/0000:00:01.3/0000:03:00.2/0000:16:00.0/0000:17:00.0
lrwxrwxrwx 1 root root 0 Feb 15 15:43 0000:18:00.0 -> ../../../../devices/pci0000:00/0000:00:01.3/0000:03:00.2/0000:16:01.0/0000:18:00.0
lrwxrwxrwx 1 root root 0 Feb 15 15:43 0000:18:00.1 -> ../../../../devices/pci0000:00/0000:00:01.3/0000:03:00.2/0000:16:01.0/0000:18:00.1
lrwxrwxrwx 1 root root 0 Feb 15 15:43 0000:19:00.0 -> ../../../../devices/pci0000:00/0000:00:01.3/0000:03:00.2/0000:16:02.0/0000:19:00.0
lrwxrwxrwx 1 root root 0 Feb 15 15:43 0000:1a:00.0 -> ../../../../devices/pci0000:00/0000:00:01.3/0000:03:00.2/0000:16:03.0/0000:1a:00.0
lrwxrwxrwx 1 root root 0 Feb 15 15:43 0000:1b:00.0 -> ../../../../devices/pci0000:00/0000:00:01.3/0000:03:00.2/0000:16:04.0/0000:1b:00.0
lrwxrwxrwx 1 root root 0 Feb 15 15:43 0000:1b:00.1 -> ../../../../devices/pci0000:00/0000:00:01.3/0000:03:00.2/0000:16:04.0/0000:1b:00.1
lrwxrwxrwx 1 root root 0 Feb 15 15:43 0000:1c:00.0 -> ../../../../devices/pci0000:00/0000:00:01.3/0000:03:00.2/0000:16:08.0/0000:1c:00.0
Como puede ver, el directorio es un montón de enlaces. Aquí está la cadena sobre cómo se conectan las cosas:
root@rwl01:/sys/kernel/iommu_groups/13/devices# lspci | grep -E '00:01.3|03:00.2|16:01.0'
00:01.3 PCI bridge: Advanced Micro Devices, Inc. [AMD] Device 1453
03:00.2 PCI bridge: Advanced Micro Devices, Inc. [AMD] Device 43b0 (rev 02)
16:01.0 PCI bridge: Advanced Micro Devices, Inc. [AMD] Device 43b4 (rev 02)
Para mí, todos estos dispositivos están en el mismo puente: mi tarjeta de video adicional, el controlador raid, etc. No puedes separarlos fácilmente.
Pero puedes
Será necesario aplicar elhttps://queuecumber.gitlab.io/linux-acs-override/(Parche ACS Override Kernel) Esto le permitirá utilizar parámetros de línea de comando para exponer partes de los grupos que son sus propios grupos. Después de instalar el parche, puede configurar los parámetros de la línea de comandos del kernel que desee:
pcie_acs_override =
[PCIE] Override missing PCIe ACS support for:
downstream
All downstream ports - full ACS capabilties
multifunction
All multifunction devices - multifunction ACS subset
id:nnnn:nnnn
Specfic device - full ACS capabilities
Specified as vid:did (vendor/device ID) in hex
Desde aquí deberías poder hacer que el dispositivo esté en su propio grupo y deberías estar listo para las carreras. Hay problemas con este método:
Aquí hay un par de buenos enlaces:
Respuesta2
Sé que la pregunta original es de 2019, pero por lo que parece, podría ser mucho más fácil con kernels más recientes.
Para cualquiera que tenga algún problema, quería pasar una NIC en una tarjeta Gigabit Ethernet NetXtreme II de 4 puertos Broadcom BCM5709, que estaba conectada a una HP Z600. Ya había activado toda la virtualización, VT-d y similares en el BIOS.
Mi problema fue que si paso a través de una NIC en el puerto 4, el host no podía acceder a nada del Grupo 12, incluida la NIC interna que estaba usando para conectarme.
Esta es una sección útil para brindar algunos conceptos básicos sobre cómo editar la línea de comandos del Kernel. https://pve.proxmox.com/pve-docs/chapter-sysadmin.html#sysboot_edit_kernel_cmdline
Comida
La línea de comando del kernel debe colocarse en la variable GRUB_CMDLINE_LINUX_DEFAULT
del archivo /etc/default/grub
. La ejecución update-grub
agrega su contenido a todas las entradas de Linux en /boot/grub/grub.cfg.
arranque del sistema
La línea de comando del kernel debe colocarse como una línea en /etc/kernel/cmdline
. Para aplicar sus cambios, ejecute proxmox-boot-tool refresh
[no estoy seguro de qué se usaría sin Proxmox], que lo establece como la línea de opción para todos los archivos de configuración en loader/entries/proxmox-*.conf.
Luego, esta página brinda algunos detalles sobre PCI Passthrough, enfocado principalmente en Proxmox, pero el principio debería ser el mismo: https://pve.proxmox.com/wiki/PCI_Passthrough
¡ESTE VIDEO ME AYUDÓ MÁS!y fue realmente útil y minucioso para guiarlo a través del proceso. Es para una implementación específica, pero todo lo que se muestra se puede lograr utilizando la información anterior y siguiente.
https://www.youtube.com/watch?v=qQiMMeVNw-o&ab_channel=SpaceinvaderOne
Finalmente, no recuerdo de dónde lo saqué, pero este es un comando realmente útil para identificar todos los grupos IOMMU para todos los dispositivos (ejecutarlo como root):
for d in $(find /sys/kernel/iommu_groups/ -type l | sort -n -k5 -t/); do n=${d#*/iommu_groups/*}; n=${n%%/*}; printf 'IOMMU Group %s ' "$n"; lspci -nns "${d##*/}"; done;
Para mí, originalmente comencé conGRUB_CMDLINE_LINUX_DEFAULT="quiet"
Habilité la habilitación básica IOMMUGRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on"
Esto me dio:
IOMMU Group 12 00:1c.0 PCI bridge [0604]: Intel Corporation 82801JI (ICH10 Family) PCI Express Root Port 1 [8086:3a40]
IOMMU Group 12 00:1c.5 PCI bridge [0604]: Intel Corporation 82801JI (ICH10 Family) PCI Express Root Port 6 [8086:3a4a]
IOMMU Group 12 01:00.0 Ethernet controller [0200]: Broadcom Inc. and subsidiaries NetXtreme BCM5764M Gigabit Ethernet PCIe [14e4:1684] (rev 10)
IOMMU Group 12 1c:00.0 PCI bridge [0604]: Microsemi / PMC / IDT PES12T3G2 PCI Express Gen2 Switch [111d:8061] (rev 01)
IOMMU Group 12 1d:02.0 PCI bridge [0604]: Microsemi / PMC / IDT PES12T3G2 PCI Express Gen2 Switch [111d:8061] (rev 01)
IOMMU Group 12 1d:04.0 PCI bridge [0604]: Microsemi / PMC / IDT PES12T3G2 PCI Express Gen2 Switch [111d:8061] (rev 01)
IOMMU Group 12 1e:00.0 Ethernet controller [0200]: Broadcom Inc. and subsidiaries NetXtreme II BCM5709 Gigabit Ethernet [14e4:1639] (rev 20)
IOMMU Group 12 1e:00.1 Ethernet controller [0200]: Broadcom Inc. and subsidiaries NetXtreme II BCM5709 Gigabit Ethernet [14e4:1639] (rev 20)
IOMMU Group 12 1f:00.0 Ethernet controller [0200]: Broadcom Inc. and subsidiaries NetXtreme II BCM5709 Gigabit Ethernet [14e4:1639] (rev 20)
IOMMU Group 12 1f:00.1 Ethernet controller [0200]: Broadcom Inc. and subsidiaries NetXtreme II BCM5709 Gigabit Ethernet [14e4:1639] (rev 20)
He eliminado todo excepto el grupo que me interesa, el Grupo 12. Puedes ver los 4 puertos de la NIC, pero también otra NIC, la integrada. Desafortunadamente, si paso a través de una NIC, el host no puede acceder a nada del Grupo 12.
Encontré un mecanismo de trabajo que divide la NIC en dos, usandoGRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on pcie_acs_override=downstream"
esto me dio
IOMMU Group 12 00:1c.0 PCI bridge [0604]: Intel Corporation 82801JI (ICH10 Family) PCI Express Root Port 1 [8086:3a40]
IOMMU Group 13 00:1c.5 PCI bridge [0604]: Intel Corporation 82801JI (ICH10 Family) PCI Express Root Port 6 [8086:3a4a]
IOMMU Group 18 1c:00.0 PCI bridge [0604]: Microsemi / PMC / IDT PES12T3G2 PCI Express Gen2 Switch [111d:8061] (rev 01)
IOMMU Group 19 1d:02.0 PCI bridge [0604]: Microsemi / PMC / IDT PES12T3G2 PCI Express Gen2 Switch [111d:8061] (rev 01)
IOMMU Group 20 1d:04.0 PCI bridge [0604]: Microsemi / PMC / IDT PES12T3G2 PCI Express Gen2 Switch [111d:8061] (rev 01)
IOMMU Group 21 1e:00.0 Ethernet controller [0200]: Broadcom Inc. and subsidiaries NetXtreme II BCM5709 Gigabit Ethernet [14e4:1639] (rev 20)
IOMMU Group 21 1e:00.1 Ethernet controller [0200]: Broadcom Inc. and subsidiaries NetXtreme II BCM5709 Gigabit Ethernet [14e4:1639] (rev 20)
IOMMU Group 22 1f:00.0 Ethernet controller [0200]: Broadcom Inc. and subsidiaries NetXtreme II BCM5709 Gigabit Ethernet [14e4:1639] (rev 20)
IOMMU Group 22 1f:00.1 Ethernet controller [0200]: Broadcom Inc. and subsidiaries NetXtreme II BCM5709 Gigabit Ethernet [14e4:1639] (rev 20)
IOMMU Group 23 01:00.0 Ethernet controller [0200]: Broadcom Inc. and subsidiaries NetXtreme BCM5764M Gigabit Ethernet PCIe [14e4:1684] (rev 10)
Puede ver que la NIC de 4 puertos está dividida en 2 pares y ninguna está en un grupo con la NIC integrada. Sospecho que cada par está en el mismo bus (disculpe la terminología) en la tarjeta, por lo que probablemente sea la división más pequeña que pude obtener (probé otros mecanismos, por ejemplo, aislar uno o más puentes como se describe en el video, pero eran peores que los anteriores).
Espero que esto pueda ser de alguna utilidad para cualquiera que tenga el mismo problema.