Hi,
i'm using vga passthrough in arch-linux (host) for windows (guest).
My Specs:
i7 5820k
MSI x99S sli plus
Host gpu: evga gtx 960
guest gpu: sapphire r9 290x vapor
It works great for over a year now. So i thought i should write a setup script for when i have to set up from scratch.
It is by no means perfect or can be used in all cases.
It also assumes that the gpus in the pcie lanes will end up in different iommu groups,
that the gpu to be isolated is alone in its group,
that you're using grub as bootloader,
that the arch install is kinda fresh,
and that the two gpus are one nvidia and one amd.
What it does is set up a folder in home directory where all the VM stuff will be put.
After asking some questions it configures grub and some other files and puts/creates the necessary
qemu-scripts in this folder. The generated "qemu_setup.sh" needs basically only be used once to install windows.
For a daily use the script sets it up that one only need to start the newly created "windows" "program" with one click for example.
Besides the assumptions from above the script might also work on an arch installation that is already in use.
I'm planing to install opensuse, fedora maybe ubuntu and try to get the passthrough working and adapt the script for those options too.
TL;DR
Long story short, here is a script that sets up vga passthrough in arch. Maybe someone other than me has use for it
Use at your own risk:
#!/bin/bash
echo "Please run this script in your home folder!"
printf "\n"
echo "Choose the brand of the GPU that will be isolated for the guest "
echo "1: AMD 2:Nvidia"
read vgaChoice
if [ $vgaChoice -eq 1 ]
then
var_vgaBrand=amd
elif [ $vgaChoice -eq 2 ]
then
var_vgaBrand=nvidia
else
echo "start over"
exit
fi
var_user=$(whoami)
echo "Download the file with the pattern:"
echo "edk2.git-ovmf-*.noarch.rpm"
echo "from the following link:"
echo "https://www.kraxel.org/repos/jenkins/edk2/"
echo "Save it in your home folder and then press enter to continue"
read
edk2file=$(find edk2*ovmf*)
echo "Enter the folder name you want to store all the virtual machine stuff in, it will be created in your home folder:"
read var_foldername
printf "\n"
mkdir $var_foldername
echo "Give the virtual harddrive a name:"
read var_hddname
printf "\n"
echo "Enter the size you want the virtual HDD to have (e.g. 15G):"
read var_hddsize
printf "\n"
echo "Download Windows-ISO and put it in the folder you specified above. \n Enter the full name (excluding extension) of the ISO:"
read var_isoName
printf "\n"
echo "Enter the size of the memory you want to allocate to the guest in Megabyte:"
read var_memory
printf "\n"
echo "Enter the Number of cores (hyperthreading included) that will be allocated to guest:"
read var_threads
printf "\n"
echo "Enter the Number of physical cores you want to allocate to the guest:"
read var_cores
printf "\n"
var_pciID1=$(lspci -nn | grep -i "vga compatible"| grep -i $var_vgaBrand | awk '{print $NF}')
var_pciID1=${var_pciID1:1:9}
var_pciNR1=$(lspci -nn | grep -i "vga compatible"| grep -i $var_vgaBrand | awk '{print $1}')
var_pciID2=$(lspci -nn | grep -i "audio device"| grep -i $var_vgaBrand | awk '{print $NF}')
var_pciID2=${var_pciID2:1:9}
var_pciNR2=$(lspci -nn | grep -i "audio device"| grep -i $var_vgaBrand | awk '{print $1}')
cd /home/$var_user
sudo pacman -Syyuu
sudo sed -i "/#Server = file:\/\/\/home\/custompkgs/a[multilib]\nInclude = \/etc\/pacman.d\/mirrorlist \n\n[archlinuxfr] \nSigLevel = Optional \nServer = http:\/\/repo.archlinux.fr\/\$arch" "/etc/pacman.conf"
sudo pacman -Syyuu
sudo pacman -S --noconfirm wget qemu ovmf libvirt rpmextract
sudo sed -i "s/GRUB_CMDLINE_LINUX=\"\"/GRUB_CMDLINE_LINUX=\"intel_iommu=on vfio-pci.ids=$var_pciID1,$var_pciID2\"/" "/etc/default/grub"
sudo sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="quiet"/#GRUB_CMDLINE_LINUX_DEFAULT="quiet"/' /etc/default/grub
sudo sed -i 's/GRUB_TIMEOUT=5/GRUB_TIMEOUT=0.5/' /etc/default/grub
sudo sed -i 's/MODULES=""/MODULES="vfio vfio-pci vfio_iommu_type1 vfio_virqfd"/' /etc/mkinitcpio.conf
sudo touch /etc/udev/rules.d/10-qemu-hw-users.rules
sudo sh -c "echo abc1 >> /etc/udev/rules.d/10-qemu-hw-users.rules"
sudo sh -c "echo abc2 >> /etc/udev/rules.d/10-qemu-hw-users.rules"
sudo sh -c "echo abc3 >> /etc/udev/rules.d/10-qemu-hw-users.rules"
sudo sed -i "s/abc1/SUBSYSTEM==\"vfio\", OWNER=\"$var_user\"/" "/etc/udev/rules.d/10-qemu-hw-users.rules"
sudo sed -i "s/abc2/SUBSYSTEM==\"usb\", OWNER=\"$var_user\"/" "/etc/udev/rules.d/10-qemu-hw-users.rules"
sudo sed -i "s/abc3/SUBSYSTEM==\"sda1\", OWNER=\"$var_user\"/" "/etc/udev/rules.d/10-qemu-hw-users.rules"
sudo sed -i "/#user = \"root\"/auser = \"$var_user\"" "/etc/libvirt/qemu.conf"
sudo sed -i 's/#nvram = \[/nvram = \[/' /etc/libvirt/qemu.conf
sudo sed -i '/nvram = \[/a"\/usr\/share\/edk2.git\/ovmf-x64\/OVMF_CODE-pure-efi.fd:\/usr\/share\/edk2.git\/ovmf-x64\/OVMF_VARS-pure-efi.fd", \n\]' /etc/libvirt/qemu.conf
sudo sed -i 's/#cgroup_device_acl = \[/cgroup_device_acl = \[/' /etc/libvirt/qemu.conf
sudo sed -i '/cgroup_device_acl = \[/a "\/dev\/null", "\/dev\/full", "\/dev\/zero", \n "\/dev\/random", "\/dev\/urandom", \n "\/dev\/ptmx", "\/dev\/kvm", "\/dev\/kqemu", \n "\/dev\/rtc","\/dev\/hpet", "\/dev\/vfio\/vfio", \n "\/dev\/vfio\/32" \n\]' /etc/libvirt/qemu.conf
sudo mkinitcpio -p linux
sudo grub-mkconfig -o /boot/grub/grub.cfg
mkdir -p /tmp/efi
mv $edk2file /tmp/efi/$edk2file
cd /tmp/efi/
rpmextract.sh $edk2file
rm $edk2file
sudo cp -R . /
cd ~/
cd $var_foldername
wget https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/virtio-win.iso
qemu-img create -f qcow2 $var_hddname.qcow2 $var_hddsize
echo "cp /usr/share/edk2.git/ovmf-x64/OVMF_VARS-pure-efi.fd /tmp/my_vars.fd" >> qemu_setup.sh
echo "qemu-system-x86_64 \\" >> qemu_setup.sh
echo " -enable-kvm \\" >> qemu_setup.sh
echo " -m $var_memory \\" >> qemu_setup.sh
echo " -cpu host,kvm=off,check \\" >> qemu_setup.sh
echo " -smp $var_threads,sockets=1,cores=$var_cores,threads=2 \\" >> qemu_setup.sh
echo " -device vfio-pci,host=$var_pciNR1,multifunction=on \\" >> qemu_setup.sh
echo " -device vfio-pci,host=$var_pciNR2 \\" >> qemu_setup.sh
echo " -drive if=pflash,format=raw,readonly,file=/usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd \\" >> qemu_setup.sh
echo " -drive if=pflash,format=raw,file=/tmp/my_vars.fd \\" >> qemu_setup.sh
echo " -device virtio-scsi-pci,id=scsi \\" >> qemu_setup.sh
echo " -drive if=virtio,id=drive0,file=/home/$var_user/$var_foldername/$var_hddname.qcow2,format=qcow2,format=qcow2,cache=none,aio=native \\" >> qemu_setup.sh
echo " -boot order=d \\" >> qemu_setup.sh
echo " -device ide-cd,drive=drive-cd-disk1,id=cd-disk1,unit=0,bus=ide.0 \\" >> qemu_setup.sh
echo " -drive file=/home/$var_user/$var_foldername/$var_isoName.iso,if=none,id=drive-cd-disk1,media=cdrom \\" >> qemu_setup.sh
echo " -device ide-cd,drive=drive-cd-disk2,id=cd-disk2,unit=0,bus=ide.1 \\" >> qemu_setup.sh
echo " -drive file=/home/oli/VirtualMachine/virtio-win.iso,if=none,id=drive-cd-disk2,media=cdrom" >> qemu_setup.sh
echo "cp /usr/share/edk2.git/ovmf-x64/OVMF_VARS-pure-efi.fd /tmp/my_vars.fd" >> qemu_run.sh
echo "qemu-system-x86_64 \\" >> qemu_run.sh
echo " -enable-kvm \\" >> qemu_run.sh
echo " -m $var_memory \\" >> qemu_run.sh
echo " -cpu host,kvm=off,check \\" >> qemu_run.sh
echo " -smp $var_threads,sockets=1,cores=$var_cores,threads=2 \\" >> qemu_run.sh
echo " -device vfio-pci,host=$var_pciNR1,multifunction=on \\" >> qemu_run.sh
echo " -device vfio-pci,host=$var_pciNR2 \\" >> qemu_run.sh
echo " -drive if=pflash,format=raw,readonly,file=/usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd \\" >> qemu_run.sh
echo " -drive if=pflash,format=raw,file=/tmp/my_vars.fd \\" >> qemu_run.sh
echo " -device virtio-scsi-pci,id=scsi \\" >> qemu_run.sh
echo " -drive if=virtio,id=drive0,file=/home/$var_user/$var_foldername/$var_hddname.qcow2,format=qcow2,format=qcow2,cache=none,aio=native \\" >> qemu_run.sh
echo " -device ide-cd,drive=drive-cd-disk1,id=cd-disk1,unit=0,bus=ide.0 \\" >> qemu_run.sh
echo " -drive file=/home/oli/VirtualMachine/virtio-win.iso,if=none,id=drive-cd-disk1,media=cdrom" >> qemu_run.sh
chmod +x qemu_run.sh
chmod +x qemu_setup.sh
wget https://cdn2.iconfinder.com/data/icons/metro-uinvert-dock/256/OS_Windows_8.png
mv OS_Windows_8.png IconWindows.png
sudo touch /usr/share/applications/Windows.desktop
sudo sh -c "echo [Desktop Entry] >> /usr/share/applications/Windows.desktop"
sudo sh -c "echo Name=Windows >> /usr/share/applications/Windows.desktop"
sudo sh -c "echo Comment=Virtual Machine for Gaming with Windows >> /usr/share/applications/Windows.desktop"
sudo sh -c "echo abc123 >> /usr/share/applications/Windows.desktop"
sudo sed -i "s/abc123/Exec=\/home\/$var_user\/$var_foldername\/qemu_run.sh %U/" "/usr/share/applications/Windows.desktop"
sudo sh -c "echo abc123 >> /usr/share/applications/Windows.desktop"
sudo sed -i "s/abc123/Icon=\/home\/$var_user\/$var_foldername\/IconWindows.png/" "/usr/share/applications/Windows.desktop"
sudo sh -c "echo Terminal=false >> /usr/share/applications/Windows.desktop"
sudo sh -c "echo Type=Application >> /usr/share/applications/Windows.desktop"
sudo sh -c "echo Categories=Virtual-Machine\; >> /usr/share/applications/Windows.desktop"
cd ~/
echo "After you hit enter the system will reboot"
read
sudo reboot