參考文獻(xiàn):
- Ubuntu配置GPU直傳kvm虛擬機(jī) - CodeAntenna
- KVM虛擬機(jī)GPU直通,step by step - 機(jī)械意志 (mechanical-consciousness.com)
- lspci的輸出簡(jiǎn)單分析 - 成蹊0xc000 - 博客園 (cnblogs.com)
- PCI passthrough via OVMF - Arch Linux 中文維基 (archlinuxcn.org)
- Win10/11 如何開啟 第二屏幕/副屏/虛擬顯示器,讓平板成為副屏 - 知乎 (zhihu.com)
首先聲明,本文的背景是在兩張同型號(hào)的3090ti中選擇一張進(jìn)行直通,在整個(gè)直通過程中,上面的參考文獻(xiàn)給與了我很大的幫助,本篇內(nèi)容是我基于他們描述完整操作后的記錄,其中不乏對(duì)原文的直接摘抄,但也結(jié)合了我個(gè)人的機(jī)器情況進(jìn)行了重新梳理,并進(jìn)行了多次可行性驗(yàn)證,因?yàn)槊總€(gè)人的機(jī)器情況可能都大不相同,希望我的記錄能給和我相同配置的同學(xué)一些幫助。如果有不懂的命令,建議大家查一下GPT,可能理解起來會(huì)快很多。
直通步驟:
1. 確定是否支持虛擬化:
確定本機(jī)是否支持VT-P虛擬化,一般需要主板BIOS開啟VT-P。如果不能進(jìn)BIOS確認(rèn),也可以在終端里確認(rèn)。
檢查CPU是否支持虛擬化,運(yùn)行如下命令:
$ egrep -c '(svm|vm)' /proc/cpuinfo
如果顯示為0,則不支持虛擬化。
系統(tǒng)配置:Ubuntu22.04.1 LTS,GPU 3090 Ti*2,CPU i7 13700K,主板 華碩Z790-P
2. 在宿主機(jī)系統(tǒng)中啟用iommu組:
打開/etc/default/grub,找到GRUB_CMDLINE_LINUX_DE FAULT,修改為下面內(nèi)容:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on"
接著我們需要更新grub:
$ sudo update-grub -u
然后重啟電腦,重啟完后我們需要檢查iommu有沒有被正確啟用:
$ dmesg | grep -i iommu
如果你在輸出中看到很多pci xxxx:xx:xx.x: Adding to iommu group xx
,那么恭喜你,第一步完成了。
系統(tǒng)中的所有設(shè)備只能按照iommu group為單位分配給宿主機(jī)或者虛擬機(jī)。因此如果你看到兩個(gè)不相關(guān)的設(shè)備在一個(gè)group里,那也沒招,你只能給這倆設(shè)備一起丟虛擬機(jī)里去。
很可惜的是,Linux系統(tǒng)并不支持預(yù)留iommu group。
iommu group是硬件實(shí)現(xiàn)上的分組。在Linux的實(shí)現(xiàn)中,只認(rèn)得各個(gè)在總線上的硬件,并挨個(gè)挨個(gè)的啟動(dòng)起來。
我們要做的就是阻止Linux內(nèi)核在啟動(dòng)時(shí)初始化某些組里的硬件。
3. 尋找我們需要預(yù)留的iommu組:
首先確認(rèn)我們顯卡所在的PCIE總線和產(chǎn)品型號(hào):
$ lspci -nnv | grep -i nvidia
我的電腦上輸出如下:
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:2203] (rev a1) (prog-if 00 [VGA controller])
Kernel driver in use: nvidia
Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia
01:00.1 Audio device [0403]: NVIDIA Corporation GA102 High Definition Audio Controller [10de:1aef] (rev a1)
05:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:2203] (rev a1) (prog-if 00 [VGA controller])
Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia
05:00.1 Audio device [0403]: NVIDIA Corporation GA102 High Definition Audio Controller [10de:1aef] (rev a1)
可以看到輸出分成兩部分,編號(hào)加設(shè)備描述。01:00.0
和01:00.1
是編號(hào)通過冒號(hào) “:” 又分成了三部分,第一個(gè)部分是PCIe的 domain ID,第二個(gè)部分是 bus ID,第三個(gè)部分是 device id.function id。PCI設(shè)備的組織形式是一個(gè)樹形,這表示一個(gè)domain可以包含多個(gè)bus,一個(gè)bus又包含了多個(gè)device,一個(gè)device又包含多個(gè)function。
0300
是一個(gè)用來區(qū)分不同設(shè)備的編號(hào),網(wǎng)絡(luò)設(shè)備、存儲(chǔ)設(shè)備、多媒體設(shè)備、顯卡都有自己的編號(hào)。
10de:2203
這是一個(gè)廠商特有的編號(hào),10de是 Nvidia的編號(hào)(Vendor ID),Nvidia所有的設(shè)備都是使用這一編號(hào),2203 表示這是一個(gè)3090Ti顯卡。
以上參考:lspci的輸出簡(jiǎn)單分析 - 成蹊0xc000 - 博客園 (cnblogs.com),可以在這個(gè)博客里繼續(xù)查找自己的顯卡信息。
接下來我們需要找出我們的設(shè)備所在的iommu group:
$ sudo dmesg | grep iommu | grep 01:00.0
輸出如下:
[ 0.536462] pci 0000:01:00.0: Adding to iommu group 17
$ sudo dmesg | grep iommu | grep 05:00.0
[ 0.536491] pci 0000:05:00.0: Adding to iommu group 20
確認(rèn)iommu group中的所有設(shè)備:
$ sudo dmesg | grep "iommu group 17"
輸出如下:
[ 0.536462] pci 0000:01:00.0: Adding to iommu group 17
[ 0.536467] pci 0000:01:00.1: Adding to iommu group 17
4. 屏蔽顯卡
4.1 型號(hào)屏蔽法:
如果只有一張顯卡,或者兩張顯卡的ID不同,可以直接用pci-stub或者vfio-pci的方法來屏蔽即可,修改/etc/default/grub
:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on pci-stub.ids=10de:2203,10de:1aef"
或者
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on vfio-pci.ids=10de:2203,10de:1aef"
更新內(nèi)核,并重啟:
$ sudo update-grub -u
如果屏蔽成功,內(nèi)核驅(qū)動(dòng)就會(huì)顯示如下:
$ lspci -nnv | grep -E "(^\S|Kernel driver in use)" | grep 01:00 -A 1
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:2203] (rev a1) (prog-if 00 [VGA controller])
Kernel driver in use: vfio-pci
01:00.1 Audio device [0403]: NVIDIA Corporation GA102 High Definition Audio Controller [10de:1aef] (rev a1)
Kernel driver in use: vfio-pci
否則下面還是驅(qū)動(dòng)被nvidia接管的狀態(tài)(其實(shí)nvidia-smi就能看了):
$ lspci -nnv | grep -E "(^\S|Kernel driver in use)" | grep 01:00 -A 1
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:2203] (rev a1) (prog-if 00 [VGA controller])
Kernel driver in use: nvidia
01:00.1 Audio device [0403]: NVIDIA Corporation GA102 High Definition Audio Controller [10de:1aef] (rev a1)
Kernel driver in use: snd_hda_intel
4.2 腳本屏蔽法
當(dāng)然如果兩張顯卡都是同一個(gè)型號(hào),是不能用上面的方法屏蔽的。
這個(gè)時(shí)候我們要為顯卡指定驅(qū)動(dòng):
$ sudo vim /etc/initramfs-tools/scripts/init-top/vfio.sh
腳本內(nèi)容為:
#!/bin/sh
echo "vfio-pci" > /sys/bus/pci/devices/0000:01:00.0/driver_override
echo "vfio-pci" > /sys/bus/pci/devices/0000:01:00.1/driver_override
#echo "0000:01:00.0" > /sys/bus/pci/drivers/vfio-pci/bind # 這里我沒有加這個(gè)綁定,有人加了這兩句,但我注釋了,因?yàn)楸镜卣也坏竭@個(gè)文件夾
#echo "0000:01:00.1" > /sys/bus/pci/drivers/vfio-pci/bind # 需要modprobe -i vfio-pci之后才有這個(gè)文件夾,但不加仍然可用
exit 0
給腳本增加權(quán)限,否則無法執(zhí)行:
$ sudo chmod 744 /etc/initramfs-tools/scripts/init-top/vfio.sh
完成后刷新initramfs,這個(gè)命令會(huì)執(zhí)行上面的腳本:
$ sudo update-initramfs -u -k all
輸出下面的結(jié)果,重啟就可以正常屏蔽了。
update-initramfs: Generating /boot/initrd.img-6.2.0-31-generic
update-initramfs: Generating /boot/initrd.img-6.2.0-26-generic
重啟配置成功后按照上一節(jié)的命令就能看到顯卡的驅(qū)動(dòng)被vfio-pci接管了,nvidia-smi也能發(fā)現(xiàn)顯卡已經(jīng)無法識(shí)別了。
如果想恢復(fù)顯卡的掛載,就把腳本中的兩行echo...
注釋掉,并刷新initramfs
,重啟機(jī)器即可。
4.3 開機(jī)腳本屏蔽法
有些地方用下面的方法成功了,但我試了沒有效果,我把方法留在這里供大家嘗試:
$ sudo vim /usr/bin/vfio-pci-override.sh
腳本的內(nèi)容:
#!/bin/sh
if [ ! -z "$(ls -A /sys/class/iommu)" ]; then
echo "vfio-pci" > /sys/bus/pci/devices/0000:01:00.0/driver_override
echo "vfio-pci" > /sys/bus/pci/devices/0000:01:00.1/driver_override
fi
modprobe -i vfio-pci
再給腳本增加運(yùn)行權(quán)限,否則啟動(dòng)時(shí)是不能運(yùn)行的:
$ sudo chmod 744 /usr/bin/vfio-pci-override.sh
最后在/etc/modprobe.d/vfio.conf
內(nèi)指定我們的腳本路徑。
$ sudo vim /etc/modprobe.d/vfio.conf
install vfio-pci /usr/bin/vfio-pci-override.sh
Arch Linux的官方中文文檔也有詳細(xì)的解釋,但實(shí)際操作和Ubuntu有差異,放在這里作為一個(gè)參考資料。PCI passthrough via OVMF - Arch Linux 中文維基 (archlinuxcn.org)。
因?yàn)橛昧?modprobe,所以 vfio 也能正常工作了,上面說的bind文件也能找到了。
$ lsmod | grep vfio
輸出如下:
vfio_pci 16384 0
vfio_pci_core 94208 1 vfio_pci
vfio_iommu_type1 49152 0
vfio 61440 3 vfio_pci_core,vfio_iommu_type1,vfio_pci
iommufd 73728 1 vfio
irqbypass 16384 2 vfio_pci_core,kvm
5. 安裝KVM虛擬機(jī)并配置顯卡:
至此顯卡已經(jīng)被成功虛擬化,接下來就是加載到KVM之中,KVM的安裝很簡(jiǎn)單,GUI界面的安裝網(wǎng)上有很多資料,這里留下安裝命令。
$ sudo apt-get install qemu-kvm libvirt-clients libvirt-daemon-system bridge-utils virt-manager ovmf
啟用libvirt服務(wù)和開機(jī)自啟
sudo systemctl start libvirtd.service
sudo systemctl enable libvirtd.service
如果你裝完上面的命令后不想再重啟更新用戶組之類的,可以直接sudo virt-manager
。
創(chuàng)建Win10鏡像,這里就不贅述了,操作很簡(jiǎn)單,找好ISO鏡像,安裝即可,這里備注幾個(gè)重要的點(diǎn)。
首先,如果這里沒有自動(dòng)識(shí)別ISO中的系統(tǒng)可以輸入后自己手動(dòng)選擇一下,比如這里選擇win10就可以了。
其次,創(chuàng)建成功后再把顯卡的PCIE添加進(jìn)來,注意Nividia的聲卡也要加進(jìn)來。
進(jìn)入系統(tǒng)后安裝Nvidia官方的驅(qū)動(dòng)就可以在設(shè)備管理器里找到顯卡了,但還需要繼續(xù)配置才能使用顯卡接管顯示輸出。
6. 高清顯示與Parsec遠(yuǎn)程
parsec和其他軟件都是需要啟動(dòng)顯卡才能高清輸出的,所以這里還要?jiǎng)?chuàng)建一個(gè)虛擬高分辨率顯示器,創(chuàng)建步驟很簡(jiǎn)單,參考這個(gè)博客即可,Win10/11 如何開啟 第二屏幕/副屏/虛擬顯示器,讓平板成為副屏 - 知乎 (zhihu.com)。
安裝里面的腳本,在CMD里執(zhí)行下面的命令:
deviceinstaller64 install usbmmidd.inf usbmmidd
deviceinstaller64 enableidd 1 # 創(chuàng)建屏幕
deviceinstaller64 enableidd 0 # 用來關(guān)閉屏幕
完成后就能在windows的設(shè)立里看到第二個(gè)屏幕可用了,再把第二塊屏的分辨率調(diào)到3840x2160(16:9)的4k,并設(shè)置為主屏。
最后打開parsec之類的軟件就能夠正常高清輸出了,當(dāng)然parsec需要網(wǎng)絡(luò)能夠滿足p2p的環(huán)境,如果連接不了報(bào)錯(cuò),可以在B站搜索相關(guān)錯(cuò)誤代碼,確認(rèn)自己的情況,我這里嘗試了同一個(gè)路由內(nèi)虛擬機(jī)默認(rèn)的網(wǎng)絡(luò)配置是可以連接的,但設(shè)備在不同路由下面的時(shí)候會(huì)跨網(wǎng)段,虛擬機(jī)就不能建立p2p連接了(例如宿主機(jī)在172.19.1.10,虛擬機(jī)在宿主機(jī)中但沒有相關(guān)172.19的網(wǎng)段,測(cè)試用的筆記本在172.20.1.20),可能的思路是需要修改虛擬機(jī)的網(wǎng)卡讓其轉(zhuǎn)到172.19網(wǎng)段下面再嘗試。文章來源:http://www.zghlxwxcb.cn/news/detail-780921.html
ToDesk里也會(huì)顯示當(dāng)前是否為p2p的連接,可以利用ToDesk來輔助檢測(cè)網(wǎng)絡(luò)環(huán)境。文章來源地址http://www.zghlxwxcb.cn/news/detail-780921.html
到了這里,關(guān)于【完整詳細(xì)教程】Ubuntu22.04 雙顯卡 3090Ti*2 KVM虛擬機(jī)多顯卡直通與Parsec高清遠(yuǎn)程的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!