准备 GVT-g
把 kvmgt vfio-iommu-type1 vfio-mdev 这仨加到 /etc/mkinitcpio.conf
的 MODULES
数组里去。mkinitcpio -P
重新生成一下 initramfs。
添加内核参数 i915.enable_gvt=1
。比如是 grub 引导就去改 /etc/default/grub
里的 GRUB_CMDLINE_LINUX
变量,然后 grub-mkconfig ...
。
去把 /etc/systemd/system.conf
里的 DefaultLimitMEMLOCK
给改了。比如 DefaultLimitMEMLOCK=65536:1073741824
。
重启。
这个时候应该已经有 /sys/devices/pciXXXX:XX/XXXX:XXXX.X/mdev_supported_types
这个目录了。里边有好几个选项呢。选择一下合适的(查看 description
文件),然后往里边的 create
文件里写一个 UUID 就创建了。
启动 KVM 虚拟机
呃,如果你还没有磁盘镜像就自己 qemu-img 创建一个,然后装机。如果你有别的虚拟机的,也可以用 qemu-img 去转格式。
另外准备一下网络。我早就有个网桥了,所以直接用它了。在 /etc/qemu/bridge.conf
里写一句 allow br0
不然不给用的,毕竟我是普通用户权限而网络接口是要 root 权限操作的,得明确允许一下。
我尽可能地使用了 virtio,据说性能好(VirtualBox 也支持一部分了呢)。如果用已有的虚拟机系统但以前没用过 virtio 的话,记得用 fallback 那个 initramfs 启动,然后进系统之后重新生成一个。
我给分配了四个逻辑 CPU 核,4G 内存。VGA 要关掉,不然两个显卡用起来麻烦。为了避免部分内容显示到别处去(如果关了 VGA 的话就看不到,否则能在默认的那个上看到),要加上 ramfb=on,driver=vfio-pci-nohotplug
选项。
声音当然是要的。添加个 PulseAudio 后端,一张 HDA 声卡。我不懂声卡型号所以找了个顺眼的,能用就好。
合起来是这样子的(那两个省略号,一个是磁盘镜像路径,一个是创建 vGPU 用的 UUID):
#!/bin/bash -e
ulimit -l 1024000
exec qemu-system-x86_64 -enable-kvm \
-name "ArchKDE" \
-cpu host -smp 4 \
-m 4G \
-drive file=/.../ArchLinuxKDE.qcow2,if=virtio \
-netdev bridge,id=eth0,br=br0 \
-device virtio-net,netdev=eth0 \
-device vfio-pci,sysfsdev=/sys/bus/mdev/devices/...,display=on,x-igd-opregion=on,ramfb=on,driver=vfio-pci-nohotplug \
-vga none \
-display gtk,gl=on \
-audiodev pa,id=pa0,server=/run/user/$UID/pulse/native -device intel-hda -device hda-output,audiodev=pa0 \
"$@"
如果你使用 GVT-g 显卡的时候整个系统都卡卡卡的话,去看一下宿主的内核日志,是不是有 vfio_pin_page_external: Task qemu-system-x86 (257364) RLIMIT_MEMLOCK (104857600) exceeded
这样的提示,然后去把 RLIMIT_MEMLOCK 给调大,大到它不再报这个错为止。我最后给了1000M才终于不报错地把 KDE 给跑起来了(默认是64K)。
当然如果你没有 GVT-g 支持的话,去掉那行配置,然后 -vga virtio
也能用。
参考链接