按我返回上一篇文章

(本文最後更新時間:2024年8月11日)

VFIO虛擬機及Looking Glass設定 Link to heading

本文假設你的電腦已經安裝最新版本的Fedora(現時是40)。

我用的是KDE版本,但本教學應同時適用於GNOME版本(即Workstation )。注意不要安裝不可變(Immutable)版本(Fedora稱之為Atomic Desktop ),例如SilverblueKinoite

強烈建議以下內容配合Arch Wiki上的教學一並閱讀,可以相互參照。

我的設定可能和Arch Wiki上的有出入,因為我另外參考了VFIO Discord內的Linux高手們較新的建議。我推薦加入這群組,因為群組內的wiki-and-psa頻道有必讀的虛擬機優化教學,此外也能請教群內Linux高手。

Intel用家注意

Intel平台上IOMMU需要以下步驟才能啟動:

  1. 執行sudo nano /etc/sysconfig/grub,並於GRUB_CMDLINE_LINUX引號內的最後添加intel_iommu=on,然後儲存
  2. 執行sudo grub2-mkconfig -o /etc/grub2-efi.cfg,然後重啟電腦
  3. 重啟後執行這節第4步檢查IOMMU組的腳本,如看到硬件的IOMMU組則成功

綁定vfio-pci/pci-stub驅動程式 Link to heading

vfio-pci 是一個VFIO專用驅動程式。綁定vfio-pci 的硬件不會使用正常的驅動程式(比如顯示卡的官方驅動),因此宿主機不會使用這些硬件。這樣能保證VFIO虛擬機傳入硬件的穩定性。

在執行以下步驟前,先確保你兩張顯示卡都已連接電腦螢幕。綁定了vfio-pci 的顯示卡不會顯示宿主機的畫面。如果沒接駁第二張顯示卡,你就只會看到黑屏。(CPU內顯須用主機板後方面板上的HDMI/DP插口)

  1. 執行這節第4步檢查IOMMU組的腳本,記下你想傳入虛擬機的設備ID(應是xxxx:xxxx格式,例如我的3060 Ti的ID是10de:2489
  2. 執行sudo nano /etc/sysconfig/grub,並於GRUB_CMDLINE_LINUX引號內的最後添加vfio_pci.ids=abcd:efgh,1234:5678(請自行代入設備ID),然後儲存
  3. 執行sudo nano /etc/dracut.conf.d/vfio.conf,貼上以下內容後儲存:
add_drivers+=" vfio vfio_iommu_type1 vfio_pci vfio_pci_core " 
force_drivers+=" vfio_pci "
  1. 執行sudo grub2-mkconfig -o /etc/grub2-efi.cfgsudo dracut -fv,然後重啟電腦
  2. 重啟後輸入lspci -nnk,應看到想傳入虛擬機的設備有Kernel driver in use: vfio-pci

有些硬件不能用以上方法綁定vfio-pci ,例如USB控制器和SATA控制器。因為這兩種硬件的驅動程式(USB是xhci_hcd 、SATA是ahci )綁定優先度更高,vfio-pci 來不及綁定硬件。

這時候可以轉用pci-stub :它是vfio-pci 的前身,功能和vfio-pci 相近,但綁定優先度比xhci_hcdahci 更高。它的缺點是沒有vfio-pci 的一些功能(例如vfio-pci 可以把你的硬件設置成耗電較低的休眠狀態)。

  1. 執行sudo nano /etc/sysconfig/grub,並於GRUB_CMDLINE_LINUX引號內的最後添加pci-stub.ids=abcd:efgh,1234:5678(請自行代入設備ID),然後儲存
  2. 執行sudo grub2-mkconfig -o /etc/grub2-efi.cfg,然後重啟電腦
  3. 重啟後輸入lspci -nnk,應看到想傳入虛擬機的設備有:Kernel driver in use: pci-stub

不過也不一定要綁定pci-stub :我自己就有一個USB控制器照常使用xhci_hcdVFIO虛擬機啟動時Linux會自動把xhci_hcd 換成vfio-pci ,虛擬機關機後又會換回xhci_hcd ,這樣做我沒遇到甚麼問題。

注意:我不知道SATA控制器(或其他vfio-pci 綁定不了的硬件)不綁定pci-stub 的話會不會有問題,這個要留給你自己研究了。

我的GRUB_CMDLINE_LINUX是這樣的:

GRUB_CMDLINE_LINUX="rhgb quiet vfio_pci.ids=10de:2489,10de:228b pci-stub.ids=1b21:3241"

創建VFIO虛擬機 Link to heading

  1. 執行sudo dnf install -y @virtualization
  2. 下載Windows 10 ISO檔此處下載Latest virtio-win ISO,並將它們移至/var/lib/libvirt/images(提示:sudo mv *.iso /var/lib/libvirt/images
  3. 啟動virt-manager
  4. 啟用設定:Edit => Preferences => Enable XML editing
  5. 創建新的虛擬機(左上角按鍵)
  6. 選擇安裝媒介
    • 如你想安裝Windows:
      1. 第一頁選擇Local install media (ISO image or CDROM)
      2. 第二頁選擇Windows 10 ISO檔作安裝ISO
    • 如你想使用已安裝Windows的儲存裝置,第一頁則選擇Manual install
  7. Choose the operation system you are installing中選Microsoft Windows 10
  8. 第三頁設定CPU及RAM
  9. 第四頁取消勾選Enable storage for this virtual machine
  10. 最後一頁勾選Customize configuration before install,然後按Finish
這時應出現這個介面

這時應出現這個介面

設定VFIO虛擬機 Link to heading

我的VFIO虛擬機的XML(參考用,不可直接複制貼上)

  1. Overview頁,ChipsetQ35FirmwareUEFI

  2. CPU頁,Topology下勾選Manually set CPU Topology

    • Sockets設定為1
    • Cores設定為你想傳入的CPU核數
    • Threads設定為你CPU單核的線程數(如你的CPU支持SMT/Hyper-threading,此處應填2
  3. 按左下角Add Hardware,並加入以下內容:

    • 加入PCI Host Device:加入所有你想傳入虛擬機的硬件(例如虛擬機卡
    • 加入NetworkDevice model選擇virtio。加入後將原本使用e1000e的虛擬網卡刪除
    • 加入StorageDevice typeCDROM Device,再按Manage...並選擇上一部分第二步下載的virtio-win之ISO檔
    • 加入Windows存儲
      • 如果你選擇用虛擬硬碟:
        1. 加入Storage:設定虛擬硬碟容量,然後Bus Type選擇SCSI
        2. 加入ControllerType選擇SCSIModelVirtIO SCSI
      • 如果你想將Windows安裝於儲存裝置上,加入PCI Host Device並選擇這儲存裝置的控制器
  4. 最後返回Overview頁,然後按XML,進入下部分

CPU Pinning Link to heading

此部分請配合Arch Wiki上的條目一并閱讀。

CPU Pinning可使虛擬機的CPU工作全部放在你指定的CPU線程上。沒有CPU Pinning的時候,Linux會把虛擬機的CPU工作隨意分配在不同CPU線程上,這可能導致虛擬機CPU性能較差或出現延遲。

開啟終端程式(如Konsole),輸入lspcu -e,應看到類似以下內容:

❯ lscpu -e
CPU NODE SOCKET CORE L1d:L1i:L2:L3 ONLINE    MAXMHZ    MINMHZ       MHZ
  0    0      0    0 0:0:0:0          yes 4950.1948 2200.0000 3600.0920
  1    0      0    1 1:1:1:0          yes 4950.1948 2200.0000 2197.2310
  2    0      0    2 2:2:2:0          yes 4950.1948 2200.0000 4884.6382
  3    0      0    3 3:3:3:0          yes 4950.1948 2200.0000 3823.2080
  4    0      0    4 4:4:4:0          yes 4950.1948 2200.0000 2200.0210
  5    0      0    5 5:5:5:0          yes 4950.1948 2200.0000 2194.9751
  6    0      0    6 8:8:8:1          yes 4950.1948 2200.0000 3487.3359
  7    0      0    7 9:9:9:1          yes 4950.1948 2200.0000 3814.7109
  8    0      0    8 10:10:10:1       yes 4950.1948 2200.0000 2646.6521
  9    0      0    9 11:11:11:1       yes 4950.1948 2200.0000 3786.4270
 10    0      0   10 12:12:12:1       yes 4950.1948 2200.0000 2725.9070
 11    0      0   11 13:13:13:1       yes 4950.1948 2200.0000 4775.0581
 12    0      0    0 0:0:0:0          yes 4950.1948 2200.0000 2615.2581
 13    0      0    1 1:1:1:0          yes 4950.1948 2200.0000 3854.8860
 14    0      0    2 2:2:2:0          yes 4950.1948 2200.0000 2200.0000
 15    0      0    3 3:3:3:0          yes 4950.1948 2200.0000 2637.1350
 16    0      0    4 4:4:4:0          yes 4950.1948 2200.0000 2198.7981
 17    0      0    5 5:5:5:0          yes 4950.1948 2200.0000 3593.8911
 18    0      0    6 8:8:8:1          yes 4950.1948 2200.0000 2200.0000
 19    0      0    7 9:9:9:1          yes 4950.1948 2200.0000 3347.8350
 20    0      0    8 10:10:10:1       yes 4950.1948 2200.0000 2200.0000
 21    0      0    9 11:11:11:1       yes 4950.1948 2200.0000 3814.2129
 22    0      0   10 12:12:12:1       yes 4950.1948 2200.0000 2199.4971
 23    0      0   11 13:13:13:1       yes 4950.1948 2200.0000 4768.5542

CPU一欄其實是線程(Thread),CORE一欄是這線程實際所屬的CPU核。我們要將屬同一個CORE的全部CPU做Pinning,以保證最高效能。

此外,L1d:L1i:L2:L3一欄最後的數字(即L3快取)也值得注意:Arch Wiki建議PinL3組別相同的CPU。如果你和我一樣有兩個或以上的L3組別,我建議先Pin同一組別的全部CPU,性能不夠的話再去Pin其他組別的CPU

<vcpu>項下方添加<cputune>內容。下方是我的設定(我Pin了20個CPU):

<cputune>
    <vcpupin vcpu="0" cpuset="6" />
    <vcpupin vcpu="1" cpuset="18" />
    <vcpupin vcpu="2" cpuset="7" />
    <vcpupin vcpu="3" cpuset="19" />
    <vcpupin vcpu="4" cpuset="8" />
    <vcpupin vcpu="5" cpuset="20" />
    <vcpupin vcpu="6" cpuset="9" />
    <vcpupin vcpu="7" cpuset="21" />
    <vcpupin vcpu="8" cpuset="10" />
    <vcpupin vcpu="9" cpuset="22" />
    <vcpupin vcpu="10" cpuset="11" />
    <vcpupin vcpu="11" cpuset="23" />
    <vcpupin vcpu="12" cpuset="2" />
    <vcpupin vcpu="13" cpuset="14" />
    <vcpupin vcpu="14" cpuset="3" />
    <vcpupin vcpu="15" cpuset="15" />
    <vcpupin vcpu="16" cpuset="4" />
    <vcpupin vcpu="17" cpuset="16" />
    <vcpupin vcpu="18" cpuset="5" />
    <vcpupin vcpu="19" cpuset="17" />
    <emulatorpin cpuset="0-1,12-13" />
</cputune>

上方<vcpupin>內的vcpu是虛擬機的CPU次序,由0開始,按次序遞增即可。cpuset則對應你lspcu -e列出的CPU一欄的數字(即線程),同CORE的全部CPU最好連續在一起。

<emulatorpin>則是將宿主機處理虛擬工作的CPU工作放在指定的CPU內。我建議將全部未Pin的CPU都加進這項的cpuset內。

注意<vcpupin>要避免Pin第0個CORECPU

CPU Pinning不是把指定CPU線程限制只能由虛擬機使用:它只是把虛擬機的CPU工作全部指派給你指定的CPU線程去做,宿主機仍能使用這些Pin了的CPU線程。

(有方法把CPU線程完全獨立出來供虛擬機使用,可看看Arch Wiki的說明)

Intel 大小核 CPU 用家注意

我自己沒用過大小核結構的Intel CPU,不過我看過網上的討論,很多都建議只用(除CORE 0外的)P-core做vcpupin,E-core則只做emulatorpiniothreadpin

如果vcpupin混合了P-core和E-core的話可能會產生問題,具體請自己研究。

IOThread Link to heading

注意
這部分只適用於虛擬硬碟用家。如你選擇直接安裝Windows於儲存裝置上,請跳過本節
此部分請配合Arch Wiki上的條目一并閱讀。

設定IOThread可提高虛擬硬碟的讀寫性能:

  1. 在介面左方按Controller VirtIO SCSI,在<controller>內加<driver>,添加後應如此:

    <controller type="scsi" model="virtio-scsi">
        <!--注:queues的值請設為虛擬機總線程數-->
        <driver iothread='1' queues='20'/>
    </controller>
    
  2. 返回Overview頁,在<vcpu>下方添加<iothreads>1</iothreads>

  3. <cputune>內的<emulatorpin>下添加<iothreadpin>

    <iothreadpin iothread="1" cpuset="0-1,12-13" />
    

    (請自己代入cpuset的值,其應和<emulatorpin>cpuset的值一樣)

其他雜項優化 Link to heading
  • 如果你用AMD的CPU,請在<cpu>項內加<feature policy='require' name='topoext'/><cache mode='passthrough'/>。添加後應如此:
<cpu mode="host-passthrough">
    <topology sockets="1" cores="10" threads="2"/>
    <feature policy="require" name="topoext"/>
    <cache mode="passthrough"/>
</cpu>
    <hyperv mode='custom'>
        <relaxed state='on'/>
        <vapic state='on'/>
        <spinlocks state='on' retries='8191'/>
        <vpindex state='on'/>
        <runtime state='on'/>
        <synic state='on'/>
        <stimer state="on"/>
        <vendor_id state='on' value='randomid'/>
        <frequencies state='on'/>
        <tlbflush state='on'/>
        <ipi state='on'/>
    </hyperv>
    <kvm>
        <hidden state="on"/>
    </kvm>
  • <clock>項替換做以下內容:
<clock offset="localtime">
    <timer name="rtc" tickpolicy="catchup"/>
    <timer name="pit" tickpolicy="delay"/>
    <timer name="hpet" present="no"/>
    <timer name="hypervclock" present="yes"/>
</clock>

安裝Windows Link to heading

按左上方Begin Installation,然後照常安裝Windows。

如果你選擇用虛擬硬碟,Windows因為沒驅動程式,所以不能將它辨認出來:

這時按Load driver,再於出現的驅動程式中選擇w10一項即可:

要有virtio-win作為CDROM,Windows才能找到驅動程式

要有virtio-win作為CDROM,Windows才能找到驅動程式

因為Windows沒有virtio虛擬網卡的驅動,所以整個安裝過程都是離線進行。

安裝Windows後,開啟檔案總管(File Explorer)並開啟virtio-win的CDROM,然後執行CDROM內的virtio-win-gt-x64.msi。安裝成功後應可連接至網絡。

最後將VFIO虛擬機關機,然後開啟虛擬機設定介面:

  1. 將兩個CDROM刪除
  2. 開啟XML並尋找<memballoon>一項,將type設定為none

到此VFIO虛擬機安裝已完成。如果你不打算安裝Looking Glass,可直接跳過下一部分

VFIO應該還有其他設定要做(例如設定evdev),請自己做功課,在此不作說明。

Looking Glass設定 Link to heading

本部分請配合Looking Glass官方安裝文檔(B7-rc1)一并閱讀。

官方文檔簡潔易明(至少比VFIO的教學更容易理解),所以我只提供較簡要的教學。一切以官方教學為準。

  1. 官方教學之Install Libvirt

  2. 安裝編譯依賴

    sudo dnf install -y \
        cmake gcc gcc-c++ libglvnd-devel fontconfig-devel spice-protocol make nettle-devel \
        pkgconf-pkg-config binutils-devel libXi-devel libXinerama-devel libXcursor-devel \
        libXpresent-devel libxkbcommon-x11-devel wayland-devel wayland-protocols-devel \
        libXScrnSaver-devel libXrandr-devel dejavu-sans-mono-fonts \
        libdecor-devel pipewire-devel libsamplerate-devel git
    
  3. 官方教學之Building:

    • 找一個空白文件夾,入內開啟終端程式並用Git下載Looking Glass源代碼(下稱LG文件夾 ):

      git clone --recurse-submodules https://github.com/gnif/LookingGlass.git
      
    • LG文件夾 內的client文件夾內創建build文件夾並入內開啟終端程式

    • 執行以下指令:

      cmake -DENABLE_WAYLAND=1 -DENABLE_X11=0 -DENABLE_PULSEAUDIO=0 -DENABLE_PIPEWIRE=1 ../
      make
      sudo make install
      
注意

如果你的宿主機卡 是NVIDIA,而又選擇用官方閉源的驅動程式的話,可能用不了KVMFR module。

可以試試照常執行下方步驟。但如果行不通,請改用IVSHMEM with standard shared memory

用這方法的話,請跳過下方步驟,並根據官方教學自行安裝。(這方法應比安裝KVMFR簡單一點)

(用開源的驅動程式的話應可用KVMFR module)

  1. 官方教學之IVSHMEM with the KVMFR module

    • 安裝編譯依賴

      sudo dnf install -y dkms kernel-devel kernel-headers
      
    • LG文件夾 內的module文件夾內開啟終端程式

    • 執行sudo dkms install "."以安裝

    • 執行sudo nano /etc/modprobe.d/kvmfr.conf並輸入以下內容,然後儲存:

      options kvmfr static_size_mb=32
      

      (將32改成第一步計算出的數字)

    • 執行sudo nano /etc/modules-load.d/kvmfr.conf並輸入以下內容,然後儲存:

      # KVMFR Looking Glass module
      kvmfr
      
    • 執行sudo nano /etc/udev/rules.d/99-kvmfr.rules並輸入以下內容,然後儲存:

      SUBSYSTEM=="kvmfr", OWNER="user", GROUP="kvm", MODE="0660"
      

      (將user改成你的Linux用戶名;可執行whoami指令以查看)

    • 修改虛擬機XML:

      1. 將最上方的<domain>改成:

        <domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
        

        (修改後先別儲存)

      2. 於XML最後(即</domain>前)添加以下內容:

        <qemu:commandline>
            <qemu:arg value='-device'/>
            <qemu:arg value='{"driver":"ivshmem-plain","id":"shmem0","memdev":"looking-glass"}'/>
            <qemu:arg value='-object'/>
            <qemu:arg value='{"qom-type":"memory-backend-file","id":"looking-glass","mem-path":"/dev/kvmfr0","size":33554432,"share":true}'/>
        </qemu:commandline>
        

        (將33554432改成第一步計算出的數字,再乘以1024的二次方)

    • 執行sudo nano /etc/libvirt/qemu.conf

      1. 找出cgroup_device_acl項(nano內按CTRL+W可搜索關鍵字)

      2. 將整個部分取消註解,並於最後添加/dev/kvmfr0,然後儲存。應得出以下:

        cgroup_device_acl = [
            "/dev/null", "/dev/full", "/dev/zero",
            "/dev/random", "/dev/urandom",
            "/dev/ptmx", "/dev/kvm",
            "/dev/userfaultfd",
            "/dev/kvmfr0"
        ]
        
  2. SELinux容許QEMU使用kvmfr0

    • 創造一個空白文件夾,入內並創造kvmfr.te檔案,修改內容如下:

      module kvmfr 1.0;
      
      require {
          type svirt_t;
          type device_t;
          class chr_file { map open read write };
      }
      
      #============= svirt_t ==============
      allow svirt_t device_t:chr_file { map open read write };
      
    • 於文件夾開啟終端程式,執行以下指令:

      checkmodule -M -m -o kvmfr.mod kvmfr.te
      semodule_package -o kvmfr.pp -m kvmfr.mod
      sudo semodule -i kvmfr.pp
      
    • 重啟電腦

  3. 啟動VFIO虛擬機:

    • 如果virt-manager 顯示虛擬機黑屏,請先把螢幕輸出轉至虛擬機卡 插螢幕的插口,再繼續操作
    • 此處下載Bleeding EdgeWindows Host Binary 並安裝
    • 此處下載spice-guest-tools 並安裝(安裝後虛擬機和宿主機可共享剪貼簿)
    • 確保Looking Glass服務正在運行:
      1. 於虛擬機內按WIN+R,輸入services.msc並執行
      2. 找出Looking Glass (host)
      3. 如其未開始運行,選擇它,然後滑鼠右鍵功能表按啟動
  4. 於宿主機上開啟終端程式:

    • 執行nano $HOME/.looking-glass-client.ini並輸入以下內容,然後儲存:

      [app]
      shmFile=/dev/kvmfr0
      
      ; 禁止Windows使用你的麥克風;或可設做`allow`並容許Windows使用你的麥克風
      ; 如不設這項,每次Windows要用麥克風的時候,Looking Glass都會彈出對話框問你是否同意使用
      [audio]
      micDefault=deny
      

      (可於此處查看所有設定項)

    • 執行looking-glass-client,如能看到虛擬機畫面及操作它,則大功告成

Looking glass 客戶端使用教學

在Looking Glass窗口內按住Escape key(預設是ScrollLock鍵)可看到快捷鍵一覽。例如:

  1. ScrollLock:切換Capture modeCapture mode 下滑鼠及鍵盤會被鎖定在Looking Glass內
  2. ScrollLock+F:切換全螢幕模式
  3. ScrollLock+D:開啟或關閉FPS展示器

可以在.looking-glass-client.ini設定Escape key ,例如:

; 設鍵盤右邊的alt鍵為Escape key
[input]
escapeKey=KEY_RIGHTALT

執行looking-glass-client input:escapeKey=help以查看可設做Escape key 的所有鍵。

Looking Glass客戶端官方使用教學

  1. (可選) Looking Glass OBS插件

    Looking Glass有個OBS插件可讓你將整個虛擬機的畫面投射到OBS上。

    安裝很簡單(官方OBS插件安裝教學):

    1. 安裝OBS;例如安裝Flatpak版

      flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
      flatpak install -y flathub com.obsproject.Studio
      
    2. 安裝編譯依賴:sudo dnf install obs-studio-devel

    3. LG文件夾 內的obs文件夾內創建build文件夾並入內開啟終端程式

    4. 執行以下指令:

      cmake -DUSER_INSTALL=1 ../
      make
      
    5. 安裝插件:

      • Flatpak版OBS:執行以下指令

        FLATPAK_OBS_PLUGIN_DIR="$HOME/.var/app/com.obsproject.Studio/config/obs-studio/plugins/looking-glass-obs/bin/64bit"
        mkdir -p "$FLATPAK_OBS_PLUGIN_DIR"
        cp liblooking-glass-obs.so "$FLATPAK_OBS_PLUGIN_DIR"
        
      • Fedora版OBS:執行make install

    6. 啟動OBS,於Sources加入Looking Glass Client

      • SHM File/dev/kvmfr0
      • 勾選Use DMABUF import (requires kvmfr device)
效果圖

效果圖

雜項 Link to heading

繞過虛擬機偵測 Link to heading

在虛擬機XML中的<os>項內添加<smbios mode="host" />項,可以繞過部分遊戲的虛擬機偵測(例如Elden RingVRChat)。

因為我不怎玩線上遊戲,所以沒有深入研究過反制虛擬機偵測方法。如果只是偶爾玩玩,可以另外買個SSD,並把VFIO虛擬機直接安裝在上面,想玩線上遊戲時再Dual boot即可。

如選擇Dual boot,建議先添加上方<smbios>項,然後將虛擬機的UUID值修改成主機板的UUID值,否則Dual boot後可能要重新認證Windows:

  1. 執行sudo dmidecode -s system-uuid並記錄所得的UUID值
  2. 找一個空白文件夾,入內開啟終端程式
  3. 執行sudo virsh dumpxml vfio-win10 > vfio.xml
  4. 開啟vfio.xml,將<uuid>的值改成第一步獲得的UUID值
  5. 執行以下指令:
sudo virsh undefine --keep-nvram vfio-win10
sudo virsh define vfio.xml

(將第3及第5步的vfio-win10改成你VFIO虛擬機的名稱)

經網絡連接虛擬機 Link to heading

正常情況下虛擬機會在虛擬網絡內。虛擬機可經網絡連接外界,但宿主機及宿主機網絡上其他電腦卻不能經網絡連接虛擬機。

如果想經網絡連接虛擬機的話,有兩個方法:

橋接網絡 (Network Bridge)

注意:此方法要求宿主機以有線乙太網絡連接上網。如果你只能用WiFi,請轉用端口轉發方法(原因

  1. 開啟終端程式並執行nmcli con,記下你有線乙太網絡的名稱(例如eth0enp1s0等)
  2. 執行以下指令:
nmcli con add type bridge autoconnect yes con-name br0 ifname br0 stp no
# 以DHCP方式連接br0
# 如有需要,可改成`ipv4.method manual`並手動設定(請自行Google設定方法)
nmcli con modify br0 ipv4.method auto
# 將下兩行的eth0改成你的有線乙太網絡的名稱
nmcli con del eth0
nmcli con add type bridge-slave autoconnect yes con-name eth0 ifname eth0 master br0
  1. 重啟電腦
  2. 開啟VFIO虛擬機設定介面並選擇虛擬機的虛擬網卡
  3. Network sourceBridge device...Device namebr0

最後啟動VFIO虛擬機並查找它的IP,應看到IP是在宿主機的同一子網路內。

端口轉發 (Port Forwarding)
  1. 找一個空白文件夾,入內開啟終端程式
  2. 執行git clone https://github.com/saschpe/libvirt-hook-qemu.git
  3. 開啟hooks.json並將第59行的逗號刪除(如有)
  4. 根據說明自行修改hooks.json。可於hooks.schema.json查看hooks.json的格式
  5. 執行sudo make install
  6. 於Linux設定中開啟網絡設定,並選擇正在使用的網絡連接
  7. General configuration中之Firewall zone選擇FedoraWorkstation,以容許網絡上其他電腦連接宿主機的1025至65535端口

安裝後,可透過宿主機的指定端口去連接虛擬機的指定端口。

更新Looking Glass Link to heading

如果Looking Glass使用正常,那麼不需要特意去更新它。

但遇到問題時,可試試更新Looking Glass,步驟如下:

  1. LG文件夾 內開啟終端程式

  2. 更新源代碼:

    git pull --recurse-submodules
    
  3. 進入client內的build文件夾,執行以下指令:

    cmake -DENABLE_WAYLAND=1 -DENABLE_X11=0 -DENABLE_PULSEAUDIO=0 -DENABLE_PIPEWIRE=1 ../
    make
    sudo make install
    
  4. 如使用KVMFR,進入module文件夾:

    • 執行dkms status並記下顯示的kvmfr/<版本數字>
    • 執行sudo dkms remove kvmfr/<版本數字> --all
    • 再次執行dkms status
    • 如仍有kvmfr 項,執行sudo rm -rf /var/lib/dkms/kvmfr
    • 執行sudo dkms install "."
  5. 啟動VFIO虛擬機,於此處下載Bleeding EdgeWindows Host Binary 並安裝

  6. 如安裝了OBS插件,進入obs內的build文件夾,執行以下指令:

    cmake -DUSER_INSTALL=1 ../
    make
    
    # 以下二選一以安裝OBS插件
    # Flatpak版OBS:
    FLATPAK_OBS_PLUGIN_DIR="$HOME/.var/app/com.obsproject.Studio/config/obs-studio/plugins/looking-glass-obs/bin/64bit"
    mkdir -p "$FLATPAK_OBS_PLUGIN_DIR"
    cp liblooking-glass-obs.so "$FLATPAK_OBS_PLUGIN_DIR"
    
    # Fedora版OBS:
    make install
    

降低虛擬機卡耗電 Link to heading

VFIO Discord的大神發現虛擬機卡 單靠vfio-pci 的內建休眠功能不能真正達致低耗電,需要綁定官方驅動程式才能做到低耗電。

你可以選擇常時啟動VFIO虛擬機以綁定官方驅動程式,但這樣做可能會佔用很多資源(例如佔用大量RAM)。

另一個做法是創造一個低資源虛擬機並傳入虛擬機卡 ,並於VFIO虛擬機關機時啟動它。我的做法:

  1. 下載Debian安裝檔並將其移至/var/lib/libvirt/images

  2. 開啟終端程式並執行sudo systemctl enable libvirtd

  3. 創造Debian虛擬機:

    • 提供極少資源(我只提供單核/兩線程和512MB RAM)
    • 傳入VFIO虛擬機使用的虛擬機卡
    • Boot Options勾選Start virtual machine on host boot up
    • 不安裝任何桌面環境
  4. 安裝後,在啟動時的Grub畫面中按UEFI Firmware Settings,然後將Device Manager=>Secure Boot Configuration=>Attempt Secure Boot取消掉,然後按幾次ESC返回首頁,再按Reset

  5. 在這虛擬機上安裝虛擬機卡 的官方驅動程式(Debian安裝NVIDIA驅動教學),然後重啟虛擬機

  6. 執行nvidia-smi,如看到顯示卡資訊則成功

這樣做不但可以降低耗電,你還可以在這虛擬機內做顯示卡相關的工作(例如跑AI)。

缺點是麻煩:你想玩遊戲時要將它關機(否則不能啟動VFIO虛擬機),VFIO虛擬機關機後又要手動啟動它。

因此,我特意寫了一個程式將這步驟自動化。安裝教學如下:

  1. 找一個空白文件夾,入內開啟終端程式

  2. 執行sudo dnf install libvirt-devel make gcc

  3. 執行git clone https://github.com/regunakyle/vfio-vm-rotation-service.git

  4. 開啟vfio-vm-rotation.service並於[Service]下方加入以下內容:

    # 請於下方代入虛擬機名稱
    Environment="VFIO_VM_NAME=VFIO虛擬機名"
    Environment="IDLE_VM_NAME=低資源虛擬機名"
    
  5. 執行sudo make install

安裝後,你只需將低資源虛擬機關機,VFIO虛擬機就會自動啟動,反之亦然。

VFIO Discord內有進一步降低耗電的教學,請自行研究,在此不作說明。

結語 Link to heading

以上就是VFIOLooking Glass的安裝教學。希望能幫助對VFIO有興趣的朋友。

最後附上我重裝Linux時特意去跑的3DMark分數:

實機Windows下的3DMark跑分

實機Windows下的3DMark跑分


Looking Glass B7-rc1下的跑分(比實機少兩核/四線程):可看到顯示卡性能損耗比B6少

Looking Glass B7-rc1下的跑分(比實機少兩核/四線程):可看到顯示卡性能損耗比B6少