Tutorial: Linux Virtual Gaming Machine

Questions about virtualization software
Forum rules
Before you post read how to get help. Topics in this forum are automatically closed 6 months after creation.
Locked
powerhouse
Level 6
Level 6
Posts: 1144
Joined: Thu May 03, 2012 3:54 am
Location: Israel
Contact:

Tutorial: Linux Virtual Gaming Machine

Post by powerhouse »

I've already written tutorials on "how to make dual-boot obsolete...", showing how to run Windows as a VM on Linux without any noticeable performance penalties. In the following tutorial I like to share the steps needed to install a Linux VM with VGA passthrough on a Linux host.

You may ask: What's the point of that?

My short answer: It's the best thing since sliced bread. (I wish I had thought about it before.)

The full answer can be found here: https://heiko-sieger.info/linux-virtual-gaming-machine/

Here is an overview of my configuration:

Host: Linux Mint 19
Host GPU: Nvidia Quadro 2000
VMs:
1. Windows 10 Pro VM running on kvm with VGA passthrough
2. Linux Mint 19 VM running on kvm with VGA passthrough
VM GPU: Nvidia GTX 970 (passed through to either of the above VMs)

My Linux host uses a low-power graphics card (a CPU internal GPU would suffice). This is perfectly fine for everyday tasks.

I run Windows or the "Linux gaming VM" only when needed, one at a time. My Linux VM is also used for experimenting with new software, or different desktop settings. Backing up and restoring the VM can be done in minutes, depending on the storage media and image size.

This setup is ideal for gamers who use both Windows and Linux based games.

Installing a Linux Mint 19 (Ubuntu 18.04) VM with VGA Passthrough

Note: My original tutorial (and the one I will be updating if necessary) is here: https://heiko-sieger.info/installing-a- ... ssthrough/

Introduction

Installing a Linux Mint 19 VM (or Ubuntu 18.04) with VGA passthrough is surprisingly straightforward. This tutorial follows the Running Windows 10 on Linux using KVM with VGA Passthrough almost step-by-step. I will therefore focus on what's different from the above tutorial.

While booting the Linux Mint 19 life installation media (ISO) as a VM was easy, the installation of Linux Mint invariably ended with the following error:
The 'grub-efi-amd64-signed' package failed to install target/
The following tutorial will describe the steps to overcome this problem (bug?).

Preliminary steps

As always: Backup your system! I mean everything - the host, the VMs, etc. One small error and your valuable data is lost.

If you already installed a Windows 10 VM with VGA passthrough, you can skip to the next step, "Edit the Linux VM start script".

1. If you have not yet prepared your PC for VGA passthrough, follow the Running Windows 10 on Linux using KVM with VGA Passthrough tutorial chapters 4.1 to 4.6.
2. Download the life Linux ISO of the distribution you wish to install, for example from https://linuxmint.com/download.php or https://www.ubuntu.com/download/desktop.

Edit the Linux VM start script

Copy the start script from chapter 4.10 and save it as "linuxvm.sh". If you already have a working Windows 10 VM start script, copy that script!

Make the file executable:

Code: Select all

sudo chmod +x linuxvm.sh
Now edit the script in your favorite editor. Change the name of the VM at the top of the script, for example:

Code: Select all

vmname="lm19vm"
Just underneath the VM name definition is a "if...else...fi" statement. Make sure it reads as follows:

Code: Select all

if ps -ef | grep qemu-system-x86_64 | grep -q multifunction=on; then
echo "A passthrough VM is already running." &
exit 1

else
(Explanation: The above statement checks if we are accidentally trying to run a second VGA passthrough VM. The ps -ef command shows the running processes and their command line. grep qemu-system-x86_64 filters out the qemu command, but also the ps -ef | grep qemu... command we just issued. To filter out the latter, grep -q multifunction=on searches through the qemu command to detect if it contains "multifunction=on", which is a good indicator for VGA passthrough.

If your script does NOT contain the "multifunction=on" option, replace it by the PCI bus ID of the graphics card, e.g. "02:00.0".)

Underneath the qemu-system-x86_64 command, look for the following lines:

Code: Select all

-drive id=disk0,if=virtio,cache=none,format=raw,file=/media/user/win.img \
-drive file=/home/user/ISOs/win10.iso,index=1,media=cdrom \
-drive file=/home/user/Downloads/virtio-win-0.1.140.iso,index=2,media=cdrom \
and change them to:

Code: Select all

-drive id=disk0,if=virtio,cache=none,format=raw,file=/media/user/linux.img \
-drive file=/home/user/ISOs/linux.iso,index=1,media=cdrom \
Important: Replace the paths and filenames with yours.

Note that we don't need the virtio-win-0.1.140.iso driver disk for Linux.

As an example, here is my complete qemu... command:

Code: Select all

qemu-system-x86_64 \
-name $vmname,process=$vmname \
-machine type=q35,accel=kvm \
-cpu host,kvm=off \
-smp 4,sockets=1,cores=2,threads=2 \
-m 8G \
-balloon none \
-rtc clock=host,base=localtime \
-vga none \
-nographic \
-serial none \
-parallel none \
-soundhw hda \
-usb -usb-host,vendorid=045e,productid=076c \
-usb-host,vendorid=045e,productid=0750 \
-device vfio-pci,host=02:00.0,multifunction=on \
-device vfio-pci,host=02:00.1 \
-drive if=pflash,format=raw,readonly,file=/usr/share/OVMF/OVMF_CODE.fd \
-drive if=pflash,format=raw,file=/tmp/my_vars.fd \
-boot order=dc \
-drive id=disk0,if=virtio,cache=none,format=raw,file=/media/user/linux.img \
-drive file=/home/user/ISOs/linux.iso,index=1,media=cdrom \
-netdev type=tap,id=net0,ifname=vmtap0,vhost=on \
-device virtio-net-pci,netdev=net0,mac=00:16:3e:00:01:01
Important: Replace the PCI IDs/slots of the devices (mouse, keyboard, GPU) you pass to the guest with the PCI IDs you discovered in chapter 4.3:

Code: Select all

-usb -usb-host,vendorid=045e,productid=076c \
-usb-host,vendorid=045e,productid=0750 \
-device vfio-pci,host=02:00.0,multifunction=on \
-device vfio-pci,host=02:00.1 \
Check the script file to see that the file names and paths are correct, as well as the PCI devices.

Install the Linux VM

After you have verified the VM start script, run the script as follows from a terminal:

Code: Select all

sudo ./linux.sh
If all goes well, you will see a brief Tianocore screen and the life Linux media will boot.

Once you see the desktop, open Firefox and see if networking works.

If you got a network connection, proceed to run the installer.

Inside the installer (ubiquity in the case of Linux Mint and Ubuntu) skip the installation of 3rd party drivers.

At the "Installation type" screen, select the default option ("Erase disk and install Linux Mint" in the case of Linux Mint 19). This will install Linux onto the virtual file system linux.img we created with fallocate.

The installation will then proceed and end with the following error message:
The 'grub-efi-amd64-signed' package failed to install into target/
When you click OK, it will tell you that grub didn't install and that the system cannot be booted.

This problem has been reported here, together with a solution that only required some minor modifications. These are the steps to work around this bug/error:

1. Open a terminal and enter:

Code: Select all

sudo -i
2. Mount the installed file system into /mnt:

Code: Select all

mount /dev/vda2 /mnt
mount /dev/vda1 /mnt/boot/efi
for i in /dev /dev/pts /proc /sys; do sudo mount -B $i /mnt$i; done
where /dev/vda2 is the root partition and /dev/vda1 the EFI partition.

3. Load the efivars module:

Code: Select all

modprobe efivars
4. Reinstall grub-install:

Code: Select all

apt-get install --reinstall grub-efi-amd64-signed
grub-install --no-nvram --root-directory=/mnt
5. Change root to /mnt and run update-grub:

Code: Select all

chroot /mnt
update-grub
6. Once update-grub ran successfully (check the terminal output), you can exit the chroot:

Code: Select all

exit
7. Quit the Linux VM.

8. Edit the start script and change the following line to read:

Code: Select all

-boot order=c \
Save the file.

9. Boot the Linux VM:

Code: Select all

sudo ./linux.sh
If all goes well, your newly installed Linux VM will boot. You can then update the packages and install drivers, for instance the proprietary Nvidia graphics driver (if your passed-through GPU is Nvidia).

Please let me know if this tutorial has worked for you (or not).
Last edited by LockBot on Wed Dec 28, 2022 7:16 am, edited 1 time in total.
Reason: Topic automatically closed 6 months after creation. New replies are no longer allowed.
Subjects of interest: Linux, vfio passthrough virtualization, photography
See my blog on virtualization, including tutorials: https://www.heiko-sieger.info/category/ ... alization/
Locked

Return to “Virtual Machines”