You may know that I have a custom Secure Boot set-up on my PC. And, as it turns out, Windows doesn't support this whatsoever. If you try and sign their bootloader with your own key, it will refuse to boot. And yet I want to play some VR games, which on linux still kinda sucks for standalone headsets.

In this post I just want to share my qemu scripts that I use to run a VM to play those games. Some anti-cheat games, like VRChat, refuse to work in a VM, so I had to set some additional flags to hide the VM.
Explaining every step, sadly, is way too hard, and I don't remember half of it already.

I recommend reading the vrchat article on virtual machines. It explains how to generate smbios flags for your VM from your actual hardware. Specifically, this generate_smbios.sh script on gist let's you generate them automatically.

So, here is the script that I use to launch the VM. Since I only have one AMD GPU, I have to detach it from the host and pass to the VM. After VM shuts down, I don't reclaim it and reboot the host. You can reclaim it and continue using the host machine without rebooting, if you wish.

#!/bin/bash
# Unmount all network and local mounts:
umount /run/media/ilya/*

echo "Dropping caches to free up the RAM"
sync
echo 3 > /proc/sys/vm/drop_caches

# Set-up HugePages for VM memory
mkdir -p /tmp/hugepages/
mount -t hugetlbfs hugetlbfs /tmp/hugepages/
echo 32 > /proc/sys/vm/nr_hugepages

# Unbind and override the GPU drivers:
echo vfio-pci > /sys/bus/pci/devices/0000\:03\:00.0/driver_override
echo vfio-pci > /sys/bus/pci/devices/0000\:03\:00.1/driver_override
echo 0000:03:00.0 > /sys/bus/pci/devices/0000\:03\:00.0/driver/unbind
echo 0000:03:00.1 > /sys/bus/pci/devices/0000\:03\:00.1/driver/unbind

# Since I don't have any other GPUs, might as well remove the module:
rmmod amdgpu

echo "Detached from amdgpu"
sleep 1
modprobe vfio-pci

# Claim GPU with vfio:
echo 1002 73ef > /sys/bus/pci/drivers/vfio-pci/new_id
echo 1002 ab28 > /sys/bus/pci/drivers/vfio-pci/new_id
echo "Attached to VFIO

# Software TPM:
mkdir -p /tmp/emulated_tpm
swtpm socket --tpmstate dir=/home/ilya/Documents/tpm2 --ctrl type=unixio,path=/tmp/emulated_tpm/swtpm-sock --log level=20 --tpm2 -d
sleep 1

# For looking glass
#touch /dev/shm/looking-glass
#chmod 777 /dev/shm/looking-glass

echo "Starting Qemu"
qemu-system-x86_64 \
    -nodefaults \
    -global driver=cfi.pflash01,property=secure,value=on \
    -drive if=pflash,format=raw,unit=0,file="/usr/local/share/edk2/x64/OVMF_CODE.secboot.4m.fd",readonly=on \
    -drive if=pflash,format=raw,unit=1,file="/usr/local/share/edk2/x64/OVMF_VARS.4m.fd" \
    -enable-kvm \
    -cpu host,topoext,kvm=off,hv_relaxed,hv_reset,hv_runtime,hv_stimer,hv_synic,hv_time,hv_vapic,hv_vpindex,hv-frequencies,hv-avic,hv-vendor-id=76CA8702435C,host-cache-info=on,apic=on,migratable=off,invtsc=on,hv_spinlocks=0x1fff,-hypervisor \
    -m 32G -mem-path /tmp/hugepages \
    -name "BlankVM" \
    # Place the SMBIOS flags you got from generate_smbios.sh here
    -smp 12,sockets=1,cores=6,threads=2 \
    -monitor stdio \
    -nographic \
    -vga none \
    -machine type=q35,accel=kvm \
    -device pcie-root-port,multifunction=on,id=pcie.1,bus=pcie.0,chassis=1,slot=1,port=1 \
    -device vfio-pci,host=03:00.0,addr=0.0,bus=pcie.1,id=gpu,multifunction=on,x-vga=on \
    -device vfio-pci,host=03:00.1,addr=0.1,bus=pcie.1,id=audiogp \
    -device ich9-intel-hda \
    -nic,model=virtio -net user \
    -drive driver=raw,file="/dev/disk/by-id/ata-
URMOM",cache=unsafe,discard=unmap,if=virtio \
    -object input-linux,id=kbd1,evdev=/dev/input/by-id/usb-
URMOM-event-kbd,grab_all=on,repeat=on \
    -object input-linux,id=mouse1,evdev=/dev/input/by-id/usb-URMOM-event-mouse \
    -chardev socket,id=chrtpm,path=/tmp/emulated_tpm/swtpm-sock \
    -tpmdev emulator,id=tpm0,chardev=chrtpm -device tpm-tis,tpmdev=tpm0 \
    $@

#    -drive file=/home/ilya/Downloads/virtio-win-0.1.266.iso,index=3,media=cdrom \
#    -cdrom /home/ilya/Downloads/Win11_24H2_English_x64.iso \

# For looking glass:
#    -device ivshmem-plain,memdev=ivshmem,bus=pcie.0 \
#    -object memory-backend-file,id=ivshmem,share=on,mem-path=/dev/shm/looking-glass,size=32M

echo "Qemu stopped"
sleep 0.5
killall swtpm
sync
# echo > /sys/bus/pci/devices/0000\:03\:00.0/driver_override
# echo > /sys/bus/pci/devices/0000\:03\:00.1/driver_override
# sleep 1
# modprobe amdgpu
systemctl reboot

 I had lots of trouble with OVMF Secure Boot. For some reason it just refused to even boot into firmware settings. I don't remember how I solved it, since it was fixed by random poking at different things. In any case, here is a FAT32 drive image with Microsoft Secure Boot keys, so you can attach it and enroll them, if needed.


0 Comments latest

No comments.