序言
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 內核重編譯
- 準備編譯主機:推薦 debian,Ubuntu。
- 更新主機源為國內源,為後續下載更新準備。
- 導入 PVE GPG 密鑰:
<code>wget -qO - http://download.proxmox.com/debian/proxmox-ve-release-6.x.gpg | sudo apt-key add -
/<code>
- 添加 Proxmox VE 庫到 /etc/apt/sources.list 文件:
<code>deb http://download.proxmox.com/debian/pve buster pve-no-subscription
/<code>
- 執行更新並安裝需要的文件:
<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
- 下載 PVE 源碼:###需要國外下載,若沒有梯子,請看最後的技巧部分###
<code>Git clone git://git.proxmox.com/git/pve-kernel.git
/<code>
- 修改 \\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>
- 最後開始執行編譯:###需要國外下載,若沒有梯子,請看最後的技巧部分###
<code>cd pev-kernel
make V=s
/<code>
- 如果順利的話那麼會在 pve-kernel 目錄得到 4 個 deb 文件。
- 將以上 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>
閱讀更多 YFDOOR 的文章