快轉到主要內容

Ubuntu將Nvidia GPU直通給Windows虛擬機 + Looking Glass安裝教學

分類   資訊科技 虛擬機與容器技術
標籤   GPU Passthrough PCI Passthrough Ubuntu QEMU-KVM Windows
🗓️ 民國113年 甲辰年
✍ 切換正體/簡體字
目錄

顯示卡直通(GPU Passthrough) 讓Windows虛擬機能以接近原生效能玩大型3D遊戲。本文Ivon說明如何在Ubuntu安裝Windows虛擬機,並將獨立顯示卡直通給虛擬機。

為什麼要這麼做?Linux的QEMU/KVM的虛擬機的3D性能十分低落,跑不動3D應用程式,為此將顯示卡直通給虛擬機使用。

顯示卡直通(GPU Passthrough)搭配VFIO核心模組,即可讓虛擬機存取宿主機的硬體資源。Proxmox VE系統有採用此技術,現在我們要在一般的Ubuntu桌面系統搞GPU直通。

要做到這點,電腦需要二張顯示卡(一個CPU內顯,一個獨立顯示卡),再準備二台螢幕。

原理是這樣的:將獨顯直通給虛擬機後,宿主機便無法存取獨顯,故需要內顯用於顯示畫面。

我的電腦主機有內顯和獨顯的HDMI連接埠,通常主螢幕是插在Nvidia獨顯的連接埠

而獨顯在直通給虛擬機後,等同與系統隔離,Linux便無法存取Nvidia顯示卡,主螢幕就要改插Intel內顯的連接埠才有畫面,Nvidia獨顯則插上副螢幕。也就是讓Linux畫面輸出到CPU內顯;Windows畫面由獨立顯示卡輸出。

如果你沒有二個螢幕也沒關係!請使用文末提及的「Looking Glass」存取Windows桌面。讓你能夠在使用Linux的時候,透過Looking Glass的視窗與Windows桌面互動。

1. 環境
#

  • 主機板:ASUS K31CD-K
  • CPU:Intel® Core™ i5-7400
  • GPU:Intel® UHD Graphics 630 (內顯)
  • GPU:NVIDIA GTX 1050 Ti(獨顯),已安裝閉源驅動
  • 主螢幕x1
  • 副螢幕x1
  • 宿主機Host OS:Ubuntu 24.04 LTS
  • 虛擬機Guest OS:Windows 11 23H2
  • Linux核心版本:6.5.0
  • QEMU版本:8.2.2
  • Libvirt版本:8.0.0
  • Nvidia閉源驅動版本:550

2. 安裝Windows 11虛擬機
#

參見 Linux安裝Windows 11虛擬機 (QEMU KVM)

安裝後將Windows虛擬機關機。

3. 啟用IOMMU
#

使用VFIO前必須先啟用IOMMU。

  1. 編輯GRUB開機選項:sudo vim /etc/default/grub
sudo vim /etc/default/grub
  1. 針對Intel CPU,在GRUB_CMDLINE_LINUX_DEFAULT後面加入以下內容,啟用IOMMU
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on iommu=pt"
  1. 更新GRUB後重開機。
sudo update-grub
sudo reboot

4. 將Nvidia顯示卡綁定給VFIO
#

VFIO核心模組負責將PCI-E裝置暴露給虛擬機使用。

  1. 編輯udev規則:sudo vim /lib/udev/rules.d/71-nvidia.rules,將所有行數全部加上#註解掉,防止Nvidia程式一直嘗試載入驅動導致開機卡在NVRM: GPU ... is already bound to vfio-pci.的訊息。

  2. 停用服務nvidia-persistenced服務,防止程式一直嘗試載入Nvidia驅動

sudo systemctl disable nvidia-persistenced
  1. 如果直通後再也不需要讓宿主機使用Nvidia顯示卡,可以直接解除安裝Nvidia閉源驅動,改裝回nouveau。
sudo apt purge nvidia-driver-535

sudo apt install xserver-xorg-video-nouveau
  1. 之後要改用Intel內顯開機,不過Intel的顯示驅動不需要裝,通常已經含在Linux的Mesa套件裡面了。

  2. 貼上以下指令,查找獨顯和HDMI裝置的ID

#!/bin/bash
shopt -s nullglob
for g in /sys/kernel/iommu_groups/*; do
    echo "IOMMU Group ${g##*/}:"
    for d in $g/devices/*; do
        echo -e "\t$(lspci -nns ${d##*/})"
    done;
done;
  1. 找到GTX 1050Ti和顯示卡的HDMI音訊裝置,像這裡是Group 2。將後面的二個硬體ID記起來,例如10de:1c8210de:0fb9
IOMMU Group 2:
        01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] [10de:1c82] (rev a1)
        01:00.1 Audio device [0403]: NVIDIA Corporation GP107GL High Definition Audio Controller [10de:0fb9] (rev a1)
  1. 修改Linux的initramfs設定檔:sudo vim /etc/initramfs-tools/modules,設定開機儘早載入VFIO,這也可以防止接著Nvidia顯示卡的副螢幕開機時被意外喚醒。最後面ids=將Nvidia顯示卡綁定給VFIO。
vfio vfio_iommu_type1 vfio_virqfd vfio_pci ids=10de:1c82,10de:0fb9
  1. 編輯:sudo vim /etc/modprobe.d/vfio.conf,設定開機載入VFIO核心模組
options vfio-pci ids=10de:1c82,10de:0fb9

5. 隔離Nvidia GPU
#

接下來的步驟要防止Linux開機的時候搶走Nvidia顯示卡的控制權。這有很多種作法,比如將Nvidia核心模組加入黑名單(blacklist)禁止載入。或者調整核心模組載入順序,確保VFIO可以搶先Nvidia核心模組載入。

  1. 編輯:sudo vim /etc/modprobe.d/nvidia.conf,設定VFIO先於Nvidia驅動載入
softdep nouveau pre: vfio-pci
softdep nvidia pre: vfio-pci
softdep nvidia* pre: vfio-pci
  1. 編輯:sudo vim /etc/modprobe.d/kvm.conf,防止KVM錯誤更正導致Windows虛擬機進入BSOD。
options kvm ignore_msrs=1
  1. 更新initramfs和GRUB,重開機
sudo update-initramfs -u -k all

sudo update-grub

sudo reboot
  1. 重開機一直按著delete,進到UEFI,開啟內顯優先模式。我的是在Advanced → System Agent (SA) Configuration,設定「內顯(IGFX)」優先開機,並開啟「混合螢幕輸出」。

  2. 主螢幕改插到內顯的HDMI孔,副螢幕插到獨顯的HDMI孔(如果沒有二個螢幕就讓Nvidia顯示卡的孔空著)

  3. 重開機進入Linux系統,理論上此時副螢幕應該不會有任何畫面輸出。

  4. 執行sudo lspci -nnk指令,應該會看到Nvidia顯示卡Kernel driver in use:是為vfio-pci

01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] [10de:1c82] (rev a1)
        Subsystem: ASUSTeK Computer Inc. GP107 [GeForce GTX 1050 Ti] [1043:85d6]
        Kernel driver in use: vfio-pci
        Kernel modules: nvidiafb, nouveau
01:00.1 Audio device [0403]: NVIDIA Corporation GP107GL High Definition Audio Controller [10de:0fb9] (rev a1)
        Subsystem: ASUSTeK Computer Inc. GP107GL High Definition Audio Controller [1043:85d6]
        Kernel driver in use: vfio-pci
        Kernel modules: snd_hda_intel

6. 將獨顯加入到虛擬機
#

  1. 開啟Virt Manager,按二下開啟Windows虛擬機,點左上角i編輯硬體

  2. 點選左下角添加硬體 → 新增PCI主機裝置,將獨顯和獨顯音訊HDMI都加進去

  3. 虛擬機開機後,主螢幕會看到Windows畫面,副螢幕會暫時黑畫面。現在虛擬機有二個螢幕了,一個是虛擬機的QXL顯示卡,一個是Nvidia顯示卡

  4. 在虛擬機安裝 GeForce Experience更新Nvidia顯示卡驅動之後,副螢幕應該就會跳出畫面了。

  5. 接著在系統設定 → 顯示器 → 圖形,選取應用程式exe,指定使用Nvidia顯示卡彩現,而非QXL。

程式只要指定使用Nvidia顯示卡渲染,就會吃到GPU加速。儘管如此,程式的視窗在副螢幕上時效能最好。你可以編輯虛擬機硬體,將QXL顯示卡設定為None,讓虛擬機只有一個螢幕。

如果副螢幕有喇叭,則Windows的音效會透過HDMI從副螢幕輸出。

7. 安裝Looking Glass
#

Looking Glass是為只有一個螢幕的用戶準備的,讓你可以在同一個畫面同時操作Linux和Windows虛擬機。

參見 設定Looking Glass

注意Looking Glass Host與Client的版本需一致。Ubuntu 24.04已收錄looking-glass-client套件,不需要手動編譯了。

8. 讓宿主機重新使用直通的GPU
#

不重開機情況下,將虛擬機關機與解除vfio-pci綁定,再載入Nvidia核心模組即可重新讓實體機存取顯示卡。但同樣地,虛擬機需要顯示卡的話就得將其手動綁回去。

參考 GPU直通後讓宿主機重新使用Nvidia GPU

9. 如何解除GPU直通
#

把本文的步驟倒過來做。

具體來說,只要移除綁定vfio-oci相關的參數再更新initramfs就可以了,IOMMU可保留。重開機後再用lspci -nnk檢查GPU的核心模組有無變回nouveau或nvidia。

參考資料
#

相關文章

Ubuntu單GPU直通方法,Nvidia顯示卡直通給Windows 11 QEMU/KVM虛擬機
分類   資訊科技 虛擬機與容器技術
標籤   GPU Passthrough PCI Passthrough Ubuntu QEMU-KVM Libvirt
QEMU/KVM虛擬機Nvidia雙GPU直通,Linux Host對Linux Guest
分類   資訊科技 虛擬機與容器技術
標籤   GPU Passthrough PCI Passthrough QEMU-KVM Nvidia Linux
Linux Looking Glass安裝教學,低延遲顯示Windows QEMU/KVM的遊戲畫面
分類   資訊科技 虛擬機與容器技術
標籤   GPU Passthrough Linux Windows

留言板

此處提供二種留言板。點選按鈕,選擇您覺得方便的留言板。要討論程式碼請用Giscus,匿名討論請用Disqus。

這是Giscus留言板,需要Github帳號才能留言。支援markdown語法,若要上傳圖片請貼Imgur或Postimages。您的留言會在Github Discussions向所有人公開。

這是Disqus留言板,您可能會看到Disqus強制投放的廣告。有時留言可能會被系統判定需審核,導致延遲顯示,請見諒。若要上傳圖片請貼Imgur或Postimages。