QEMU-gpu pass through-Windows Client 环境搭建
ysh One

ref PCI passthrough via OVMF - ArchWiki — 通过 OVMF 的 PCI 直通 - ArchWiki (archlinux.org)

ref 2 Windows VM with GPU Passthrough, Part 1: Creating a basic Windows VM | Quantum (quantum5.ca)

方式-利用virt-manager

实现结果:微星MSI主板, Ubuntu20.04 desktop 上利用 qemu启动直通NVIDIA 4060ti的windows10 home 版本
ref Windows VM with GPU Passthrough, Part 1: Creating a basic Windows VM | Quantum (quantum5.ca)

环境准备

预先检查

请确保主板支持iommu

系统

选择ubuntu 20.04 desktop,内核版本默认,听说6+的内核版本会

Since kernel 6.0, framebuffer output will freeze after loading VFIO modules and until GPU drivers are loaded.
要用6+的版本先看看这条
Stuck on “::Running early hooks [udev]”, and GRUB question(s)… / Newbie Corner / Arch Linux Forums

需要准备的软件包

libvirt
virt-manager
qemu-system-x86
ovmf
前三者apt-get 就可以,我的环境中qemu使用的最新的8.1.2版本,需要单独配置,ovmf要额外配置。

需要下载的其余文件

  1. windows 10 iso
    1. 我用的链接是
      https://dl.ccm2.net/ccmcms-download/enccm/Windows-10-ISO-22H2-en.iso
  2. virtio-win iso
    1. linux是自带virtio的驱动的,但windows不支持,需要额外下载
    2. 链接是
      https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso

可跳过-部分软件的安装

qemu

如果是用apt安装的,可跳过此步骤(但apt用的是版本6 -2023/11/21至少是6)

qemu需要的软件包安装-总

由于Ubuntu 20.04用的nasm版本不够,需要自己编译安装

1
2
sudo apt install qemu libvirt-dev virt-manager make gcc uuid-dev g++ nasm iasl python autoconf  -y

qemu需要的软件包配置-python3
1
2
3
# python3 needed to be the default python in system
sudo rm /usr/bin/python
sudo ln -s /usr/bin/python3 /usr/bin/python
qemu需要的软件包配置-nasm

nasm 版本>=2.16

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# nasm 依赖版本>=2.71的autoconf
wget ftp://ftp.gnu.org/gnu/autoconf/autoconf-2.71.tar.gz
tar -zxvf autoconf-2.71.tar.gz
cd autoconf-2.71
./configure
make
sudo make install

wget https://www.nasm.us/pub/nasm/releasebuilds/2.16/nasm-2.16.tar.bz2
tar -jxvf nasm-2.16.tar.bz2

cd nasm-2.16
./autogen.sh
./configure
sudo make install
qemu自身安装
1
2
3
4
5
6
wget https://download.qemu.org/qemu-8.1.2.tar.xz
tar xvf ./qemu-8.1.2.tar.xz
cd qemu-8.1.2
./configure --target-list=x86_64-softmmu --enable-kvm
make -j $(nproc)
make install
部分问题排除

internal error: Failed to start QEMU binary /usr/local/bin/qemu-system-x86_64 for probing: libvirt: error : cannot execute binary /usr/local/bin/qemu-system-x86_64: Permission denied

这应该是qemu 8版本的问题,其他版本都可执行

暂时关闭apparmor(推荐)

1
sudo systemctl stop apparmor

去掉apparmor(并不推荐)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 sudo systemctl stop apparmor
sudo systemctl disable apparmor
sudo apt-get remove --purge apparmor
sudo reboot
sudo systemctl status apparmor


#### OVMF

git clone --recursive https://github.com/tianocore/edk2.git
cd edk2
make -C BaseTools
vim ./Conf/target.txt
# 改下三行
ACTIVE_PLATFORM  = OvmfPkg/OvmfPkgX64.dsc
TARGET_ARCH      = X64
TOOL_CHAIN_TAG   = GCC5
source ./edksetup.sh

build
# 成功就能看到这个文件 edk2/Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd

虚拟机配置

New Virtual Machine

  1. 启动virt-manager
  2. File->New Virtual Machine
    |300
  3. 继续,选择下载的windows10.iso
  4. 配置分配的CPU、内存
  5. 命名虚拟机,在这一步要勾选Customize configuration before install 选项框
    |300
  6. Finish

Customized Configuration

  1. 上面点击finish后应进入如下界面
    |300
  2. 在Overview中,把Firmware改成 UEFI x86_64: …/OVMF_CODE_4M.ms.fd,用于Win11的secureboot,win10用它也不会有什么大问题。
  3. 把SataDisk1 页 的 disk bus 改成 virtio
  4. 把Nic 页的device model改成virtio
  5. 点击 Add Hardware,选择storage,然后选select custom storage,然后选manage,然后 brouse local ,选择之前下好的virtio_win.iso,之后用于安装virtio相关的驱动,把它的device typeSATA改成 CDROM
  6. 删除一些过时的设备
    USBredirector/channel spice
    USB Redirector 1
    USB Redirector 2
  7. 把Display spice页内的选项改成vnc
  8. 调换boot options
    vritio_win.iso 的CDROM > windows10.iso 的CDROM > virtio磁盘
  9. 万事俱备,左上角begin installation

Windows 10 installation

和平常的windows10安装一样,只有一点
到where do you want to install Windows 时,不会有任何disk被发现,需要手动安装virtio驱动
|300

左下角load driver,然后选win10的驱动就可以了。之后返回上面页面,等一会儿就可以看到disk

启动后

启动后,打开windows的设备管理器,然后更新一些设备的驱动
|300
Ethernet Controller. PCI Device , PCI SImple Communications Controller , Microsoft Basic Display Adapter
直接右键,update drive,然后选择E盘(里面是virtio驱动),它会自己找的。

gpu隔离

ref Windows VM with GPU Passthrough, Part 2: Passing through PCIe Devices | Quantum (quantum5.ca)

1. enable iommu

test code ,没输出就是没enable

1
2
3
4
5
6
7
8
#!/bin/bash
shopt -s nullglob
for g in $(find /sys/kernel/iommu_groups/* -maxdepth 0 -type d | sort -V); do
echo "IOMMU Group ${g##*/}:"
for d in $g/devices/*; do
echo -e "\t$(lspci -nns ${d##*/})"
done;
done;

更新 /etc/default/grub

1
2
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on"

1
sudo update-grub

2. 隔离GPU

2.1 vfio-pci 绑定

本机情况

|500
之后需要将vfio-pci和10de:280310de:22bd绑定
修改/etc/modprobe.d/vfio.conf

1
2
3
4
5
6
sudo vim /etc/default/grub
# inside
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on iommu=pt vfio-pci.ids=10de:2803,10de:22bd"
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on iommu=pt vfio-pci.ids=8086:56a1,8086:4f90"

sudo update-grub

2.2 bios时缓冲帧去除

/etc/default/grub
启动默认配置改成这样

1
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on iommu=pt vfio-pci.ids=10de:2803,10de:22bd video=vesafb:off video=efifb:off"

2.3 initramfs 包括vfio-pci

修改 /etc/initramfs-tools/modules

1
2
3
4
5
# VFIO
vfio_pci
vfio
vfio_iommu_type1
vfio_virqfd

使用initramfs-tools时

需要让vfio驱动首先绑定gpu设备
修改 /etc/modprobe.d/vfio.conf,如果没有要新建一个

1
2
3
4
5
# Make vfio-pci a pre-dependency of the usual video modules
softdep amdgpu pre: vfio-pci
softdep radeon pre: vfio-pci
softdep nouveau pre: vfio-pci
softdep snd_intel_hda pre: vfio-pci

更新 initramfs

1
sudo update-initramfs -u

将设备添加到虚拟机里

启动virt-manager
点击AddHardware
选PCI Host Device ,然后选择NVIDIA 4060ti

启动设备

通过virt-manager 启动设备。
此时能看到GPU

方式-通过qemu命令行 -不推荐

建议直接跳转 方式2 - 通过vitual manager
环境

  1. 主机和系统信息
    1
    uname -a

    Linux nmhn-MS-7D48 5.15.0-88-generic #98~20.04.1-Ubuntu SMP Mon Oct 9 16:43:45 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

step 1. enable iommu
test code ,没输出就是没enable

1
2
3
4
5
6
7
8
#!/bin/bash
shopt -s nullglob
for g in $(find /sys/kernel/iommu_groups/* -maxdepth 0 -type d | sort -V); do
echo "IOMMU Group ${g##*/}:"
for d in $g/devices/*; do
echo -e "\t$(lspci -nns ${d##*/})"
done;
done;

更新 /etc/default/grub

1
2
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on"

1
sudo update-grub

step 2. 隔离GPU
2.1 vfio-pci 绑定
本机情况

|500
之后需要将vfio-pci和10de:280310de:22bd绑定
修改/etc/modprobe.d/vfio.conf

1
2
3
4
sudo vim /etc/default/grub
# inside
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on iommu=pt vfio-pci.ids=10de:2803,10de:22bd"
sudo update-grub
1
lspci -nnk -d 10de:2803

成功报告
|500

设置基于OVMF的guest虚拟机

安装

pre
ref 如何在Linux中安装nasm最新版本_linux nasm-CSDN博客

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# python3 needed to be the default python in system
sudo rm /usr/bin/python
sudo ln -s /usr/bin/python3 /usr/bin/python
sudo apt install qemu libvirt-dev virt-manager make gcc uuid-dev g++ nasm iasl python autoconf autohead -y
# ubuntu 20 nasm的版本较低,需要nasm 版本>=2.16
# nasm 依赖版本>=2.71的autoconf
wget ftp://ftp.gnu.org/gnu/autoconf/autoconf-2.71.tar.gz
tar -zxvf autoconf-2.71.tar.gz
cd autoconf-2.71
./configure
make && make install

wget https://www.nasm.us/pub/nasm/releasebuilds/2.16/nasm-2.16.tar.bz2
tar -jxvf nasm-2.16.tar.bz2

cd nasm-2.16
./autogen.sh
./configure
make install

edk2-ovmf

1
2
3
4
5
6
7
8
9
10
11
12
13
git clone --recursive https://github.com/tianocore/edk2.git
cd edk2
make -C BaseTools
vim ./Conf/target.txt
# 改下三行
ACTIVE_PLATFORM  = OvmfPkg/OvmfPkgX64.dsc
TARGET_ARCH      = X64
TOOL_CHAIN_TAG   = GCC5
source ./edksetup.sh

build
# 成功就能看到这个文件 edk2/Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd

|500
download qemu

1
2
3
./configure --target-list=x86_64-softmmu --enable-kvm 
make -j $(nproc)
make install

download windows 10.iso

create qcow2 disk
setup.sh

1
2
3
qemu-system-x86_64 --enable-kvm -smp 4 -m 4G -hda win10_disk.qcow2 -cdrom Windows-10-ISO-22H2-en.iso \
-bios ./OVMF.fd \
-vnc :0

start.sh

1
2
3
4
5
6
qemu-system-x86_64 --enable-kvm -smp 8 -m 8G -hda win10_disk.qcow2 -vnc :0 \
-device vfio-pci,host=0000:01:00.0 \
-device vfio-pci,host=0000:01:00.1 \
-drive if=pflash,format=raw,readonly=on,file=/home/nmhn/gpu-pass/repo/edk2/Build/OvmfX64/DEBUG_GCC5/FV/OVMF_CODE.fd \
-drive if=pflash,format=raw,file=/home/nmhn/gpu-pass/img/OVMF_VARS.fd

报错

1
2
kernel: vfio-pci 0000:01:00.0: BAR 1: can t reserve [mem 0x90000000-0x9fffffff 64bit pref]
qemu-system-x86_64: vfio_region_write(0000:01:00.0:region1+0x19abbb, 0x0,1) failed: Device or resource busy

解决方案:
ref解决显卡直通 kernel: vfio-pci BAR 1: can’t reserve 问题 | JackieWu
/etc/default/grub
启动默认配置里加这两个

1
video=vesafb:off video=efifb:off

问题

internal error: Failed to start QEMU binary /usr/local/bin/qemu-system-x86_64 for probing: libvirt: error : cannot execute binary /usr/local/bin/qemu-system-x86_64: Permission denied

这应该是qemu 8版本的问题,其他版本都可执行

暂时关闭apparmor(推荐)

1
sudo systemctl stop apparmor

去掉apparmor(并不推荐)

1
2
3
4
5
 sudo systemctl stop apparmor
sudo systemctl disable apparmor
sudo apt-get remove --purge apparmor
sudo reboot
sudo systemctl status apparmor

|500

测试

geekbench5

ubuntu:

  1. 下载geekbench 5
1
wget https://cdn.geekbench.com/Geekbench-5.3.1-Linux.tar.gz
  1. 解压
1
2
tar xf Geekbench-5.3.1-Linux.tar.gz
cd Geekbench-5.3.1-Linux/
  1. 运行
    1
    ./geekbench5
    运行完可以看到一个url,打开就能看到结果

windows:

下载
https://geekbench-5.en.uptodown.com/android/download
双击运行即可

Powered by Hexo & Theme Keep