아래 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
동일한 그룹에 다른 장치가 없는 특정 장치를 자체 그룹으로 격리하고 싶습니다 .
KVM 가상 머신에 대한 PCI 패스스루를 위해 단일 장치를 별도의 IOMMU 그룹으로 분리하려면 어떻게 해야 합니까?
답변1
나는 이것이 오래된 질문이라는 것을 알고 있지만 최근에 이것을 알아 내려고 노력해야 했습니다.
IOMMU의 경험 법칙은 커널이 사용자를 위해 매핑을 파악한다는 것입니다. 커널이 부팅되면 IOVA(I/O 가상 맵)에 매핑할 수 있는 장치를 찾습니다. 장치에 동일한 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)
나에게는 이 모든 장치가 동일한 브리지, 추가 비디오 카드, RAID 컨트롤러 등에 있습니다. 이들을 쉽게 분리할 수 없습니다.
하지만 넌 할수있어
다음을 적용해야 합니다.https://queuecumber.gitlab.io/linux-acs-override/(ACS 재정의 커널 패치) 이를 통해 명령줄 매개변수를 사용하여 그룹의 일부를 자체 그룹으로 노출할 수 있습니다. 패치를 설치한 후 원하는 커널 명령줄 매개변수를 구성할 수 있습니다.
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
여기에서 장치를 자체 그룹에 포함할 수 있어야 하며 경주를 시작해야 합니다. 이 방법에는 다음과 같은 문제가 있습니다.
다음은 몇 가지 좋은 링크입니다.
답변2
원래 질문은 2019년의 질문이라는 것을 알고 있지만, 듣기로는 최신 커널을 사용하면 훨씬 쉬울 수 있습니다.
문제가 있는 분들을 위해 HP Z600에 연결된 Broadcom BCM5709 4포트 NetXtreme II 기가비트 이더넷 카드의 NIC를 통과하고 싶었습니다. 나는 이미 BIOS에서 모든 가상화, VT-d 등을 설정했습니다.
내 문제는 4포트에서 하나의 NIC를 통과하면 연결하는 데 사용했던 내부 NIC를 포함하여 그룹 12의 어떤 것도 호스트에 액세스할 수 없다는 것입니다.
이것은 커널 명령줄을 편집하는 방법에 대한 몇 가지 기본 사항을 제공하는 유용한 섹션입니다. https://pve.proxmox.com/pve-docs/chapter-sysadmin.html#sysboot_edit_kernel_cmdline
애벌레
GRUB_CMDLINE_LINUX_DEFAULT
커널 명령줄은 파일의 변수에 배치되어야 합니다 /etc/default/grub
. 실행하면 update-grub
해당 내용이 /boot/grub/grub.cfg의 모든 Linux 항목에 추가됩니다.
시스템 부팅
커널 명령줄은 /etc/kernel/cmdline
. 변경 사항을 적용하려면 proxmox-boot-tool refresh
[Proxmox 없이 무엇을 사용할지 잘 모르겠습니다]를 실행하여 loader/entries/proxmox-*.conf의 모든 구성 파일에 대한 옵션 라인으로 설정합니다.
그런 다음 이 페이지에서는 주로 Proxmox에 초점을 맞춘 PCI 패스스루에 대한 몇 가지 세부 정보를 제공하지만 원칙은 여전히 동일해야 합니다. https://pve.proxmox.com/wiki/PCI_Passthrough
이 영상이 나에게 가장 큰 도움이 되었어요!프로세스를 안내하는 데 정말 유용하고 철저했습니다. 특정 구현을 위한 것이지만 표시된 모든 내용은 위와 아래 정보를 사용하여 수행할 수 있습니다.
https://www.youtube.com/watch?v=qQiMMeVNw-o&ab_channel=SpaceinvaderOne
마지막으로 어디서 얻었는지 기억이 나지 않지만 이것은 모든 장치에 대한 모든 IOMMU 그룹을 식별하는 데 정말 유용한 명령입니다(루트로 실행).
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"
기본 활성화 IOMMU를 활성화했습니다.GRUB_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를 제외한 모든 항목을 제거했습니다. NIC의 4개 포트를 볼 수 있을 뿐만 아니라 또 다른 NIC인 온보드 NIC도 볼 수 있습니다. 불행하게도 하나의 NIC를 통과하면 그룹 12의 어떤 것도 호스트에 액세스할 수 없습니다.
다음을 사용하여 NIC를 두 개로 분할하는 작동 메커니즘을 찾았습니다.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포트 NIC가 2개의 쌍으로 분할되어 있고 둘 다 온보드 NIC가 있는 그룹에 속해 있지 않은 것을 볼 수 있습니다. 나는 각 쌍이 카드에서 서로 동일한 버스(용어는 죄송합니다)에 있다고 생각하므로 이는 아마도 제가 얻을 수 있는 가장 작은 분할일 것입니다(비디오에 설명된 대로 하나 이상의 브리지를 분리하는 등 다른 메커니즘을 시도했지만 위의 것보다 더 나빴습니다).
동일한 문제를 겪고 있는 모든 사람에게 이것이 도움이 되기를 바랍니다.