將單一裝置隔離到單獨的 IOMMU 群組以實現 PCI 直通?

將單一裝置隔離到單獨的 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 群組中,以實現 KVM 虛擬機器的 PCI 直通?

答案1

我知道這是一個老問題,但我最近不得不嘗試解決這個問題。

IOMMU 的經驗法則是內核將為您找出映射。當核心啟動時,它將尋找哪些裝置可以對應到 I/O 虛擬映射 (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)

對我來說,所有這些設備都在同一個橋上,我的額外顯示卡、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 年開始的,但聽起來,使用更新的核心可能會容易得多。

對於任何有問題的人,我想透過 Broadcom BCM5709 4 連接埠 NetXtreme II 千兆位元乙太網路卡上的 NIC,該卡已插入 HP Z600。我已經在 BIOS 中開啟了所有虛擬化、VT-d 等功能。

我的問題是,如果我透過 4 連接埠上的一個 NIC,主機將無法存取群組 12 中的任何內容,包括我用於連接到它的內部 NIC。


這是一個有用的部分,提供了有關如何編輯內核命令列的一些基礎知識 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 中所有設定檔的選項行。


然後,本頁提供了有關 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)之外的所有內容。不幸的是,如果我透過一個網卡,主機就無法存取第 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 對,並且都不與板載網路卡在一組。我懷疑每一對都在卡上的同一總線上(請原諒術語),所以這可能是我能得到的最小分割(我確實嘗試了其他機制,例如隔離視頻中概述的一個或多個橋,但是他們比上面的更糟)。

希望這對遇到相同問題的人有所幫助。

相關內容