「隨筆」PVE(Proxmox VE) J3455 IOMMU分組及硬件直通探討

序言

PVE 本身是支持 PCI 硬件直通的,可是在一些硬件(例如:華擎 J3455 ITX 主板)卻出現 IOMMU 分組問題,從而導致硬件直通不成功。

關於 PCI 的直通請參閱官方的 wiki:

  • https://pve.proxmox.com/wiki/Pci_passthrough
  • https://pve.proxmox.com/wiki/PCI(e)_Passthrough

PVE PCI 直通設置

簡單來說要實現直通需要通過如下步驟:

第一步:在主機 BIOS 設置中 VT-D 開啟和 Video Options (Embedded Video Primary,Optional Video Secondary)

第二步:開啟 IOMMU 功能 ,修改/etc/default/grub 文件 (The IOMMU has to be activated on the kernel commandline)

打開:

<code>nano /etc/default/grub
/<code>

修改:

<code>GRUB_CMDLINE_LINUX_DEFAULT="quiet"
/<code>

到:

<code>GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on" # INTEL CPU
/<code>
<code>GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on" # AMD CPU
/<code>

然後執行:

<code>update-grub
/<code>

第三步:添加核心模塊 (You have to make sure the following modules are loaded. This can be achieved by adding them to ‘/etc/modules’)

<code>echo "vfio" >> /etc/modules
echo "vfio_iommu_type1" >> /etc/modules
echo "vfio_pci" >> /etc/modules
echo "vfio_virqfd" >> /etc/modules
/<code>

第四步:更新 initramfs 核心後重啟

<code>update-initramfs -u -k all
reboot
/<code>

直通效果驗證

運行:dmesg | grep -e DMAR -e IOMMU 假如沒有回顯,那麼可能哪裡出了問題。若是出現 IOMMU, Directed I/O or Interrupt Remapping is enabled 之類的字樣那麼說明 IOMMU 開啟了。

當你在 PVE 主機執行:

<code>find /sys/kernel/iommu_groups/ -type l
/<code>

回顯:

<code>find /sys/kernel/iommu_groups/ -type l
/sys/kernel/iommu_groups/0/devices/0000:00:00.0
/sys/kernel/iommu_groups/1/devices/0000:01:00.1
/sys/kernel/iommu_groups/2/devices/0000:00:02.0
/sys/kernel/iommu_groups/3/devices/0000:00:16.0
/sys/kernel/iommu_groups/4/devices/0000:00:1a.0
/sys/kernel/iommu_groups/5/devices/0000:00:1b.0
/sys/kernel/iommu_groups/6/devices/0000:00:1c.0
/sys/kernel/iommu_groups/7/devices/0000:00:1c.5
/sys/kernel/iommu_groups/8/devices/0000:00:1c.6
/sys/kernel/iommu_groups/9/devices/0000:00:1c.7
/<code>

但是你也可能看到:

<code>find /sys/kernel/iommu_groups/ -type l
/sys/kernel/iommu_groups/1/devices/0000:00:0f.0
/sys/kernel/iommu_groups/2/devices/0000:00:02.0
/sys/kernel/iommu_groups/3/devices/0000:00:15.0
/sys/kernel/iommu_groups/4/devices/0000:00:12.0
/sys/kernel/iommu_groups/2/devices/0000:00:0e.0
/sys/kernel/iommu_groups/5/devices/0000:03:00.0
/sys/kernel/iommu_groups/5/devices/0000:00:13.2
/sys/kernel/iommu_groups/5/devices/0000:00:13.0
/sys/kernel/iommu_groups/5/devices/0000:04:00.1
/sys/kernel/iommu_groups/5/devices/0000:01:00.0
/sys/kernel/iommu_groups/5/devices/0000:00:13.3
/sys/kernel/iommu_groups/5/devices/0000:00:13.1
/sys/kernel/iommu_groups/5/devices/0000:04:00.0
/sys/kernel/iommu_groups/6/devices/0000:00:00.0
/sys/kernel/iommu_groups/7/devices/0000:00:1f.0
/sys/kernel/iommu_groups/7/devices/0000:00:1f.1
/<code>

可以在第四列看到許多的 device 被分到了一個相同的組內 (5),那麼恭喜你,你中獎了,由於你的 IOMMU 分組沒有區分開,那麼也就意味著沒有完全成功。

官方的 Wiki 對此也有說明,請自行查閱,他給出的一個方法是:

  • 首先加入強制非安全分割:
<code>echo "options vfio_iommu_type1 allow_unsafe_interrupts=1" > /etc/modprobe.d/iommu_unsafe_interrupts.conf
/<code>
  • 再修改/etc/default/grub:
<code>GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on pcie_acs_override=downstream"
/<code>

此時假如你的分組問題解決了,那麼恭喜你,要是發現分組還是有問題,那麼今天我們就要開始大動干戈了。

PVE 內核重編譯

  1. 準備編譯主機:推薦 debian,Ubuntu。
  2. 更新主機源為國內源,為後續下載更新準備。
  3. 導入 PVE GPG 密鑰:
<code>wget -qO - http://download.proxmox.com/debian/proxmox-ve-release-6.x.gpg | sudo apt-key add -
/<code>
  1. 添加 Proxmox VE 庫到 /etc/apt/sources.list 文件:
<code>deb http://download.proxmox.com/debian/pve buster pve-no-subscription
/<code>
  1. 執行更新並安裝需要的文件:
<code>apt-get update 
apt-get upgrade -y
apt-get install git nano screen patch fakeroot build-essential devscripts libncurses5 libncurses5-dev libssl-dev bc flex bison libelf-dev libaudit-dev libgtk2.0-dev libperl-dev asciidoc xmlto gnupg gnupg2 rsync lintian debhelper libdw-dev libnuma-dev libslang2-dev sphinx-common asciidoc-base automake cpio dh-python file gcc kmod libiberty-dev libpve-common-perl libtool perl-modules python-minimal sed tar zlib1g-dev
/<code>

注意:如果沒有導入 PVE 的 GPG 密鑰,可能會導致無法安裝 libpve-common-perl

  1. 下載 PVE 源碼:###需要國外下載,若沒有梯子,請看最後的技巧部分###
<code>Git clone git://git.proxmox.com/git/pve-kernel.git
/<code>
  1. 修改 \\pve-kernel\\patches\\kernel 路徑下的 “0003-pci-Enable-overrides-for-missing-ACS-capabilities-4..patch” 文件:

此處的“106” 改為 “105”,因為代碼行數由 106 變為 105.

<code>--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -193,6 +193,106 @@ static int __init pci_apply_final_quirks(void)
/<code>

再修改:

<code>+\tif (!pci_is_pcie(dev) ||
+\t\tpci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS))
+\t\t\treturn -ENOTTY;
/<code>

改成:

<code>+\tif (!pci_is_pcie(dev))\t\t
+\t\t\treturn -ENOTTY;
/<code>
  1. 最後開始執行編譯:###需要國外下載,若沒有梯子,請看最後的技巧部分###
<code>cd pev-kernel
make V=s
/<code>
  1. 如果順利的話那麼會在 pve-kernel 目錄得到 4 個 deb 文件。
  2. 將以上 4 個 deb 文件傳到 pve 的 root 目錄下,執行安裝,安裝後重啟即可。(請自行備份,以防萬一)
<code>dpkg -i *.deb
reboot
/<code>

技巧:

PVE 官方的源碼在國外,直接下載速度很慢,而且編譯過程會下載很多的 submodule,我們可以先將相關的源碼拉到國內的“碼雲”上,再下載速度會快許多。我已經把所有需要的庫全部拉到了碼雲上,供大家參考:

<code>[email protected]:yfdoor/pve-kernel.git
[email protected]:yfdoor/pve-mirror_ubuntu-eoan-kernel.git
[email protected]:yfdoor/pve-zfsonlinux.git
[email protected]:yfdoor/pve-mirror_zfs.git
[email protected]:yfdoor/pve-zfs-images.git
/<code>

PVE 的各個項目間通過 Git submodule 關聯,他們之間的關係為:

  • 一級目錄 pve-kernel:submodules 文件夾 關聯 mirror_ubuntu-eoan-kernelzfsonlinux
  • 二級目錄 zfsonlinux:upstream 文件夾關聯 mirror_zfs
  • 三級目錄 mirror_zfs:scripts/zfs-images 文件夾關聯 zfs-images

每個項目下的 .gitmodules 文件來定義 submodule 的鏈接,用法請自己百度,常用的命令:

<code>Git clone
Git pull
Git submodule init
Git submodule update

/<code>


分享到:


相關文章: