Here is a solution to be able to play video games from a Linux environment with 95% native performance.

erminologies

First of all, there are a few terminologies to know:

  • KVM (Kernel-based Virtual Machine) is the Linux kernel module that interacts with the virtualization features of the processor. It is a Type I hypervisor for Linux.
  • QEMU is the KVM-based virtualization software that emulates virtual processors and peripherals and starts and shuts down virtual machines.
  • virt-manager is the graphical interface that allows you to create, configure, and run virtual machines.
  • libvirt is the library that allows virt-manager to interact with the virtualization capabilities provided by QEMU.
  • virtio is a programming interface that handles all communication between the hypervisor and the kernel.
  • OVMF (Open Virtual Machine Firmware) is a project to allow UEFI support to virtual machines.
  • vfio Virtual Function I / O
  • IOMMU Input-output memory management unit

Prerequisite

  • Have two Graphics Cards or 1 Apu and a Graphics Card
  • Your motherboard must support IOMMU technology
  • Your CPU must support hardware virtualization
  • Your graphics card must support UEFI
  • Have 2 video inputs on the screen (1 for linux (host) and 1 for the virtual machine (Guest)

Installation

The installation I propose here is specifically intended for Arch Linux or a distribution based on it like Antergos . This procedure will aim to install a Qemu / KVM + VFIO / IOMMU GPU Passthrough environment in order to be able to play games from Linux on a Windows virtual machine .

Activate IOMMU

# /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on"

Copy

grub-mkconfig -o /boot/grub/grub.cfg
dmesg|grep -e DMAR -e IOMMU # Vérifier l'activation de IOMMU

Copy

Install libvirt, qemu, virt-manager and OVMF

pacman -S dnsmasq ebtables dmidecode # libvirt dependencies
pacman -S qemu ovmf virt-manager
pacman -S libvirt
usermod -aG libvirt username
systemctl enable libvirtd

Copy

Configure qemu

mv /etc/libvirt/qemu.conf /etc/libvirt/qemu.conf.orig
cat <<EOT >> /etc/libvirt/qemu.conf
user = "root"
group = "root"
clear_emulator_capabilities = 0
cgroup_device_acl = [
    "/dev/null", "/dev/full", "/dev/zero",
    "/dev/random", "/dev/urandom",
    "/dev/ptmx", "/dev/kvm", "/dev/kqemu",
    "/dev/rtc","/dev/hpet", "/dev/vfio/vfio",
    "/dev/vfio/1"
]
nvram = [
  "/usr/share/ovmf/x64/OVMF_CODE.fd:/usr/share/ovmf/x64/OVMF_VARS.fd"
]
EOT

Copy

Install vfio

lspci -nn|grep -iP "NVIDIA|Radeon" # $VFIOID
echo options vfio-pci ids=$VFIOID > /etc/modprobe.d/vfio.conf

MODULES="vfio vfio_iommu_type1 vfio_pci vfio_virqfd" # /etc/mkinitcpio.conf
mkinitcpio -p linux

lspci -k | grep -i vfio-pci # Check vfio

Copy

Install virtio

pacaur -S virtio-win
echo -e 'virtio\virtio_blk\virtio_pci\virtio_net' | sudo tee /etc/modules-load.d/virtio.conf
lsmod | grep virtio # Check virtio modules

Copy

Virtual machine configuration

Once the environment is ready, we must create and configure our virtual machine with it virt-manager. Rather than putting a hundred screenshots here is a video which gives step by step the configuration of our virtual machine.

Configuring a Windows virtual machine with virt-manager

Network configuration

To configure a network connection on your virtual machine:

  1. Edit -> Connection Details -> Virtual Networks -> Add Network

  2. Create “br0” virtual network with “Forwarding to physical network” option and Physical device wlp59s0

  3. virsh edit <VM_name> and add:

Copy

My configuration

If you have followed all the steps, you should have your virtual machine ready to use to play your favorite games.

For my part, I have a Laptop, which implies a particular configuration . At the moment, I can only run my VM with a VNC server, I have not managed to make my HDMI output functional on a screen :(.

This is what my setup looks like:

sudo /usr/sbin/qemu-system-x86_64 \
-cpu host,kvm=off \
-enable-kvm \
-m 4096 \
-smp cores=4,threads=2 \
-device vfio-pci,host=01:00.0 \
-drive if=pflash,format=raw,readonly,file=/usr/share/ovmf/x64/OVMF_CODE.fd \
-drive if=pflash,format=raw,file=/usr/share/ovmf/x64/OVMF_VARS.fd \
-drive file=/var/lib/libvirt/images/win10.qcow2,format=qcow2,if=none,id=disk0,cache=writeback \
-device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x8,drive=disk0,id=virtio-disk0,bootindex=1 \
-netdev type=tap,script=no,downscript=no,id=net0,ifname=tap2 \
-device virtio-net-pci,netdev=net0,disable-legacy=on,iommu_platform=true,romfile= \
-boot menu=on

Copy

Do not hesitate to ask your questions in the comments;)

Good week !