Изолировать одно устройство в отдельную группу IOMMU для прохождения PCI?
У меня ниже группы и устройства 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
Я хотел бы выделить это конкретное устройство, /sys/kernel/iommu_groups/7/devices/0000:01:00.0
в свою группу без других устройств в той же группе.
Как мы можем выделить одно устройство в отдельную группу IOMMU для прохождения PCI для виртуальной машины KVM?
2 ответа
Я знаю, что это старый вопрос, но я должен был попытаться выяснить это недавно.
Эмпирическое правило с IOMMU заключается в том, что ядро определит сопоставления для вас. Когда ядро загружается, оно будет искать, какие устройства могут быть сопоставлены с виртуальной картой ввода / вывода (IOVA). Если устройства имеют одинаковую IOVA, они попадают в одну группу. Это сделано для того, чтобы гарантировать, что в каждой группе есть устройства, к которым можно обращаться и обращаться к ним отдельно.
Есть несколько решений. Во-первых, вы можете попробовать переместить карту в другое место на материнской плате. Если это PCI, а не карта PCIe, то вам, вероятно, не повезло, поскольку все порты PCI, вероятно, сопоставлены одному и тому же мосту PCIe и, следовательно, будут использовать один и тот же IOVA.
Если вам действительно нужно это сделать, вы можете взять все устройства, входящие в одну группу, и назначить их всем для vfio-pci, а затем выполнить назначения для того места, где должны находиться эти устройства.
Например, на моей машине группа 13 имеет несколько устройств, включая дополнительную видеокарту (18:00). Вот мой вывод из этого каталога:
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
Как видите, в каталоге есть куча ссылок. Вот цепочка о том, как все связано:
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)
Для меня все эти устройства находятся на одном мосту, моя дополнительная видеокарта, контроллер рейда и т. Д. Вы не можете легко разделить их.
Но вы можете
Вам нужно будет применить https://queuecumber.gitlab.io/linux-acs-override/ (исправление ядра ACS Override). Это позволит вам использовать параметры командной строки, чтобы выставлять части групп как свои собственные группы. После установки патча вы можете настроить параметры командной строки ядра:
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
Отсюда вы сможете создать устройство в своей группе и отправиться в гонки. Есть проблемы с этим методом:
Вот несколько хороших ссылок:
Я знаю, что исходный вопрос был задан в 2019 году, но, судя по всему, с более свежими ядрами все может быть намного проще.
Для тех, у кого возникнут какие-либо проблемы, я хотел пройти через сетевой адаптер на 4-портовой карте Broadcom BCM5709 NetXtreme II Gigabit Ethernet, которая была подключена к HP Z600. Всю виртуализацию, VT-d и тому подобное я уже включил в биосе.
Моя проблема заключалась в том, что если я пройду через один сетевой адаптер на 4-портовом порту, ничто в группе 12 не будет доступно хосту, включая внутренний сетевой адаптер, который я использовал для подключения к нему.
Это полезный раздел, в котором рассказывается об основах редактирования командной строки ядра https://pve.proxmox.com/pve-docs/chapter-sysadmin.html#sysboot_edit_kernel_cmdline .
личинка
Командную строку ядра необходимо поместить в переменнуюGRUB_CMDLINE_LINUX_DEFAULT
в файле/etc/default/grub
. Бегupdate-grub
добавляет свое содержимое ко всем записям Linux в /boot/grub/grub.cfg.
Systemd-загрузка
Командную строку ядра необходимо разместить одной строкой в/etc/kernel/cmdline
. Чтобы применить изменения, запуститеproxmox-boot-tool refresh
[не уверен, что будет использоваться без Proxmox], что устанавливает его в качестве строки опции для всех файлов конфигурации в loader/entries/proxmox-*.conf.
Затем на этой странице приводятся некоторые подробности о PCI Passthrough, в первую очередь ориентированные на Proxmox, но принцип должен оставаться тем же:https://pve.proxmox.com/wiki/PCI_Passthrough .
ЭТО ВИДЕО ПОМОГЛО МНЕ САМОЕ!и был действительно полезным и тщательным, помогая вам пройти через этот процесс. Это для конкретной реализации, но все показанное можно выполнить, используя приведенную выше и ниже информацию.
https://www.youtube.com/watch?v=qQiMMeVNw-o&ab_channel=SpaceinvaderOne
Наконец, я не могу вспомнить, откуда я ее взял, но это действительно полезная команда для определения всех групп IOMMU для всех устройств (запускается от имени пользователя 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;
Что касается меня, я изначально начал сGRUB_CMDLINE_LINUX_DEFAULT="quiet"
Я включил базовое включение IOMMUGRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on"
Это дало мне:
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)
Я удалил все, кроме интересующей меня группы, группы 12. Вы можете видеть 4 порта сетевой карты, а также еще одну сетевую карту, встроенную. К сожалению, если я пройду через один сетевой адаптер, хосту ничего из группы 12 не будет доступно.
Я нашел рабочий механизм, который разделяет сетевую карту на две части, используяGRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on pcie_acs_override=downstream"
Это дало мне
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)
Вы можете видеть, что 4-портовый сетевой адаптер разделен на 2 пары, и ни одна из них не находится в группе со встроенным сетевым адаптером. Я подозреваю, что каждая пара находится на одной и той же шине (извините за терминологию) на карте, так что это, вероятно, наименьшее разделение, которое я мог получить (я пробовал другие механизмы, например, изолируя один или несколько мостов, как показано в видео, но они были хуже, чем предыдущие).
Надеюсь, это может оказаться полезным для тех, у кого такая же проблема.