├── etc ├── modprobe.d │ └── vfio.conf ├── modules-load.d │ └── virtio.conf ├── NetworkManager │ └── system-connections │ │ ├── bridge0 slave 1 │ │ └── Host Bridge └── sysctl.d │ └── 99-sysctl.conf ├── synergy.conf ├── vfio.sh ├── Windows8.1.xml └── README.md /etc/modprobe.d/vfio.conf: -------------------------------------------------------------------------------- 1 | options vfio-pci ids=10de:1b81,10de:10f0 2 | -------------------------------------------------------------------------------- /etc/modules-load.d/virtio.conf: -------------------------------------------------------------------------------- 1 | virtio 2 | virtio-ring 3 | virtio-pci 4 | virtio-net 5 | virtio-blk 6 | virtio-balloon 7 | vhost_net 8 | -------------------------------------------------------------------------------- /etc/NetworkManager/system-connections/bridge0 slave 1: -------------------------------------------------------------------------------- 1 | [connection] 2 | id=bridge0 slave 1 3 | uuid=ad76fa5e-5e8f-41b0-8b88-c2511fd273b2 4 | type=ethernet 5 | interface-name=enp0s1234 6 | master=bridge0 7 | permissions= 8 | slave-type=bridge 9 | 10 | [ethernet] 11 | mac-address=01:23:45:67:89:AF 12 | mac-address-blacklist= 13 | -------------------------------------------------------------------------------- /etc/NetworkManager/system-connections/Host Bridge: -------------------------------------------------------------------------------- 1 | [connection] 2 | id=Host Bridge 3 | uuid=0d308e5c-59c5-438a-985b-4a514bfc5451 4 | type=bridge 5 | interface-name=bridge0 6 | permissions= 7 | timestamp=1499897474 8 | 9 | [bridge] 10 | stp=false 11 | 12 | [ipv4] 13 | dns=8.8.8.8;8.8.4.4; 14 | dns-search= 15 | method=auto 16 | 17 | [ipv6] 18 | addr-gen-mode=stable-privacy 19 | dns-search= 20 | ip6-privacy=0 21 | method=auto 22 | -------------------------------------------------------------------------------- /synergy.conf: -------------------------------------------------------------------------------- 1 | section: screens 2 | sigurd: 3 | halfDuplexCapsLock = false 4 | halfDuplexNumLock = false 5 | halfDuplexScrollLock = false 6 | xtestIsXineramaUnaware = false 7 | switchCorners = none 8 | switchCornerSize = 0 9 | WinVM: 10 | halfDuplexCapsLock = false 11 | halfDuplexNumLock = false 12 | halfDuplexScrollLock = false 13 | xtestIsXineramaUnaware = false 14 | switchCorners = none 15 | switchCornerSize = 0 16 | end 17 | 18 | section: aliases 19 | end 20 | 21 | section: links 22 | sigurd: 23 | right = WinVM 24 | WinVM: 25 | left = sigurd 26 | end 27 | 28 | section: options 29 | relativeMouseMoves = false 30 | screenSaverSync = true 31 | win32KeepForeground = false 32 | clipboardSharing = true 33 | switchCorners = none 34 | switchCornerSize = 0 35 | mousebutton(6) = keystroke(WWWBack) 36 | mousebutton(7) = keystroke(WWWForward) 37 | end 38 | 39 | -------------------------------------------------------------------------------- /etc/sysctl.d/99-sysctl.conf: -------------------------------------------------------------------------------- 1 | # Performance tweaks 2 | vm.swappiness=5 3 | vm.dirty_ratio=3 4 | vm.dirty_background_ratio=2 5 | vm.dirty_background_bytes=4194304 6 | vm.dirty_bytes=4194304 7 | vm.vfs_cache_pressure=50 8 | 9 | # TCP/IP stack hardening 10 | net.ipv4.tcp_syncookies=1 11 | net.ipv4.tcp_rfc1337=1 12 | net.ipv4.tcp_timestamps=1 13 | net.ipv4.conf.all.log_martians=1 14 | net.ipv4.icmp_echo_ignore_broadcasts=1 15 | 16 | # BBR Congestion Control Algorithm 17 | net.core.default_qdisc=fq 18 | net.ipv4.tcp_congestion_control=bbr 19 | 20 | # libvirt bridge performance hack 21 | net.bridge.bridge-nf-call-arptables = 0 22 | net.bridge.bridge-nf-call-ip6tables = 0 23 | net.bridge.bridge-nf-call-iptables = 0 24 | 25 | # Increase max file handles for Guard::LiveReload 26 | fs.inotify.max_user_watches=32767 27 | 28 | # Required for Alt-SysRq-REISUB 29 | kernel.sysrq=1 30 | 31 | # Prevent some attacks 32 | kernel.kptr_restrict=1 33 | -------------------------------------------------------------------------------- /vfio.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | vfio_iommu_groups() { 4 | shopt -s nullglob 5 | for d in /sys/kernel/iommu_groups/*/devices/*; do 6 | n=${d#*/iommu_groups/*}; n=${n%%/*} 7 | printf 'IOMMU Group %s ' "$n" 8 | lspci -nns "${d##*/}" 9 | done; 10 | } 11 | 12 | vfio_start_barrier() { 13 | echo "Starting Barrier..." 14 | barrierc --debug WARNING --name sigurd --no-tray --enable-crypto WinVM.lan 15 | } 16 | 17 | vfio_switch_displays() { 18 | echo "Switching outputs..." 19 | xrandr --output HDMI-1 --off 20 | xrandr --output HDMI-2 --mode 1920x1080 --pos 0x0 --primary 21 | xrandr --output HDMI-2 --set "Broadcast RGB" "Full" 22 | } 23 | 24 | vfio_restore_displays() { 25 | echo "Restoring outputs..." 26 | xrandr --output HDMI-1 --mode 2560x1440 --rate 60 --pos 0x0 --primary 27 | xrandr --output HDMI-1 --set "Broadcast RGB" "Full" 28 | xrandr --output HDMI-2 --right-of HDMI-1 --mode 1920x1080 --rate 60 --pos 2560x270 29 | xrandr --output HDMI-2 --set "Broadcast RGB" "Full" 30 | } 31 | 32 | vfio_enable_hugepages() { 33 | echo -n "Compacting memory... " 34 | echo 1 | sudo tee /proc/sys/vm/compact_memory 35 | echo -n "Enabling hugepages... " 36 | echo 10 | sudo tee /proc/sys/vm/nr_hugepages 37 | 38 | echo -n "Allocated: " 39 | sudo cat /proc/sys/vm/nr_hugepages 40 | } 41 | 42 | vfio_disable_hugepages() { 43 | echo -n "Disabling hugepages... " 44 | echo 0 | sudo tee /proc/sys/vm/nr_hugepages 45 | } 46 | 47 | # Force remove the GPU from the system and rescan the PCI bus. 48 | # This basically performs a hardware reset. 49 | vfio_gpu_redetect() { 50 | echo -n "Removing the GPU... " 51 | echo 1 | sudo tee /sys/bus/pci/devices/0000:01:00.0/remove 52 | 53 | echo -n "Removing HDMI Audio... " 54 | echo 1 | sudo tee /sys/bus/pci/devices/0000:01:00.1/remove 55 | 56 | echo -n "Rescanning PCI devices... " 57 | echo 1 | sudo tee /sys/bus/pci/rescan 58 | } 59 | 60 | # Bind both GPU devices to the vfio-pci driver. 61 | vfio_gpu_bind_vfio() { 62 | sudo modprobe vfio-pci 63 | echo "0000:01:00.0" | sudo tee /sys/bus/pci/drivers/vfio-pci/bind 64 | echo "0000:01:00.1" | sudo tee /sys/bus/pci/drivers/vfio-pci/bind 65 | } 66 | 67 | hdd_mount_ro() { 68 | sudo umount /mnt/Seagate2TB 69 | sudo mount /mnt/Seagate2TB -o ro,nosuid,nodev,noexec,relatime,user_id=0,group_id=0,default_permissions,allow_other,blksize=4096,user 70 | } 71 | 72 | hdd_mount_rw() { 73 | sudo umount /mnt/Seagate2TB 74 | sudo mount /mnt/Seagate2TB -o rw,nosuid,nodev,noexec,relatime,user_id=0,group_id=0,default_permissions,allow_other,blksize=4096,user 75 | } 76 | 77 | hdd_assert_ro() { 78 | mountpoint /mnt/Seagate2TB 79 | if [ "$?" -eq "0" ]; then 80 | status=$(mount | grep Seagate2TB | grep rw) 81 | 82 | if [ "$status" = "" ]; then 83 | return 0 84 | else 85 | echo $status 86 | read -p "Remount RO? (Y/N) " choice 87 | case "$choice" in 88 | y|Y ) 89 | hdd_mount_ro 90 | if hdd_assert_ro; then return 0; else return 1; fi 91 | ;; 92 | n|n ) 93 | read -p "You're about to break your file system. Are you sure? Type YES to confirm: " wellfuck 94 | case "$wellfuck" in 95 | YES ) echo "Good luck!"; return 0 ;; 96 | *) return 1 ;; 97 | esac 98 | ;; 99 | * ) 100 | echo "Invalid input, exiting..." 101 | return 1 102 | ;; 103 | esac 104 | fi 105 | fi 106 | } 107 | 108 | vfio_winvm() { 109 | if hdd_assert_ro; then echo "HDD available!"; else echo "HDD unavailable, exiting..."; return 1; fi 110 | vfio_enable_hugepages 111 | 112 | # If no arguments are given, switch displays. 113 | [ $# -eq 0 ] && vfio_switch_displays 114 | 115 | echo "Starting Windows VM..." 116 | sudo virsh start Windows8.1 117 | sleep 1 118 | 119 | vfio_start_barrier 120 | while [[ $(pgrep qemu-system) ]]; do 121 | sleep 5 122 | done 123 | 124 | echo "QEMU no longer running, killing Barrier..." 125 | killall barrierc 126 | 127 | [ $# -eq 0 ] && vfio_restore_displays 128 | } 129 | -------------------------------------------------------------------------------- /Windows8.1.xml: -------------------------------------------------------------------------------- 1 | 2 | Windows8.1 3 | c5f35a6b-8ae6-4b46-ae51-90e7b72ba602 4 | Windows 8.1 5 | 6 | 7 | 8 | 9 | 10 | 16777216 11 | 16777216 12 | 13 | 14 | 15 | 16 | 17 | 18 | 6 19 | 1 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | hvm 35 | /usr/share/ovmf/ovmf_code_x64.bin 36 | /var/lib/libvirt/qemu/nvram/Windows8.1_VARS.fd 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | destroy 74 | restart 75 | destroy 76 | 77 | 78 | 79 | 80 | 81 | /usr/bin/qemu-system-x86_64 82 | 83 | 84 | 85 | 86 | 87 |
88 | 89 | 90 | 91 | 92 | 93 |
94 | 95 | 96 |
97 | 98 | 99 | 100 |
101 | 102 | 103 |
104 | 105 | 106 | 107 | 108 |
109 | 110 | 111 | 112 | 113 |
114 | 115 | 116 | 117 | 118 |
119 | 120 | 121 | 122 | 123 |
124 | 125 | 126 |
127 | 128 | 129 | 130 | 131 | 132 | 133 |
134 | 135 | 136 | 137 |
138 | 139 | 140 | 141 |
142 | 143 | 144 | 145 | 146 | 147 |
148 | 149 | 150 | 151 |
152 | 153 |
154 | 155 | 156 | 157 |
158 | 159 |
160 | 161 | 162 | 163 | 164 | 165 | 166 |
167 | 168 | 169 | 170 | 171 | 172 | 173 |
174 | 175 | 176 | 177 | 178 | 32 179 |
180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **Warning:** I no longer use VFIO. All of these instructions and configs are 2 | up to date as of this writing, plus feel free to ask questions in issues/via 3 | mail if you aren't sure about something, but it'll no longer be updated. 4 | 5 | Instead of VFIO I just use a normal dual boot, since the VM overhead starts 6 | to become a problem in newer games with an older CPU I have, and the primary 7 | reason I've used VFIO (Windows + Linux development box, side by side, with 8 | little to no compromises) is no more. And I mostly play on Linux nowadays :D 9 | 10 | --- 11 | 12 | # VFIO Setup 13 | 14 | Files in this repository are my scripts, notes and "all the helper stuff" for 15 | configuring the GPU passthrough and the guest VM. Essentially, native-level 16 | performance for games in Windows, without dual booting. This was done on Arch 17 | Linux, on other distros your mileage may vary (especially with outdated QEMU). 18 | 19 | - If you'd like to try such a setup yourself, [try this ArchWiki page](https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF). 20 | - My setup is described a bit better on [the VFIO examples page](https://wiki.archlinux.org/index.php?title=PCI_passthrough_via_OVMF/Examples). 21 | 22 | The vfio.sh is sourced in my .bashrc, so that I can just run `vfio_winvm` and 23 | that's it. Passing any extra argument to vfio_winvm skips switching displays. 24 | The VM will fail to start if any attached USB devices are missing - for that, 25 | I use [tinyvirt](https://github.com/DragoonAethis/tinyvirt) to detach those and 26 | then run the VM normally (used to have a separate domain, but I'm too lazy to 27 | maintain them both :P). 28 | 29 | ## IOMMU Groups 30 | 31 | IOMMU Group 0 00:00.0 Host bridge [0600]: Intel Corporation Skylake Host Bridge/DRAM Registers [8086:191f] (rev 07) 32 | IOMMU Group 1 00:01.0 PCI bridge [0604]: Intel Corporation Skylake PCIe Controller (x16) [8086:1901] (rev 07) 33 | IOMMU Group 1 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP104 [GeForce GTX 1070] [10de:1b81] (rev a1) 34 | IOMMU Group 1 01:00.1 Audio device [0403]: NVIDIA Corporation GP104 High Definition Audio Controller [10de:10f0] (rev a1) 35 | IOMMU Group 2 00:02.0 VGA compatible controller [0300]: Intel Corporation HD Graphics 530 [8086:1912] (rev 06) 36 | IOMMU Group 3 00:14.0 USB controller [0c03]: Intel Corporation Sunrise Point-H USB 3.0 xHCI Controller [8086:a12f] (rev 31) 37 | IOMMU Group 4 00:16.0 Communication controller [0780]: Intel Corporation Sunrise Point-H CSME HECI #1 [8086:a13a] (rev 31) 38 | IOMMU Group 5 00:17.0 SATA controller [0106]: Intel Corporation Sunrise Point-H SATA controller [AHCI mode] [8086:a102] (rev 31) 39 | IOMMU Group 6 00:1b.0 PCI bridge [0604]: Intel Corporation Sunrise Point-H PCI Root Port #17 [8086:a167] (rev f1) 40 | IOMMU Group 7 00:1b.2 PCI bridge [0604]: Intel Corporation Sunrise Point-H PCI Root Port #19 [8086:a169] (rev f1) 41 | IOMMU Group 8 00:1b.3 PCI bridge [0604]: Intel Corporation Sunrise Point-H PCI Root Port #20 [8086:a16a] (rev f1) 42 | IOMMU Group 9 00:1c.0 PCI bridge [0604]: Intel Corporation Sunrise Point-H PCI Express Root Port #1 [8086:a110] (rev f1) 43 | IOMMU Group 10 00:1c.4 PCI bridge [0604]: Intel Corporation Sunrise Point-H PCI Express Root Port #5 [8086:a114] (rev f1) 44 | IOMMU Group 11 00:1d.0 PCI bridge [0604]: Intel Corporation Sunrise Point-H PCI Express Root Port #9 [8086:a118] (rev f1) 45 | IOMMU Group 12 00:1f.0 ISA bridge [0601]: Intel Corporation Sunrise Point-H LPC Controller [8086:a145] (rev 31) 46 | IOMMU Group 12 00:1f.2 Memory controller [0580]: Intel Corporation Sunrise Point-H PMC [8086:a121] (rev 31) 47 | IOMMU Group 12 00:1f.3 Audio device [0403]: Intel Corporation Sunrise Point-H HD Audio [8086:a170] (rev 31) 48 | IOMMU Group 12 00:1f.4 SMBus [0c05]: Intel Corporation Sunrise Point-H SMBus [8086:a123] (rev 31) 49 | IOMMU Group 13 00:1f.6 Ethernet controller [0200]: Intel Corporation Ethernet Connection (2) I219-V [8086:15b8] (rev 31) 50 | IOMMU Group 14 05:00.0 PCI bridge [0604]: Intel Corporation DSL6540 Thunderbolt 3 Bridge [Alpine Ridge 4C 2015] [8086:1578] (rev 03) 51 | IOMMU Group 15 06:00.0 PCI bridge [0604]: Intel Corporation DSL6540 Thunderbolt 3 Bridge [Alpine Ridge 4C 2015] [8086:1578] (rev 03) 52 | IOMMU Group 16 06:01.0 PCI bridge [0604]: Intel Corporation DSL6540 Thunderbolt 3 Bridge [Alpine Ridge 4C 2015] [8086:1578] (rev 03) 53 | IOMMU Group 17 06:02.0 PCI bridge [0604]: Intel Corporation DSL6540 Thunderbolt 3 Bridge [Alpine Ridge 4C 2015] [8086:1578] (rev 03) 54 | IOMMU Group 17 09:00.0 USB controller [0c03]: Intel Corporation DSL6540 USB 3.1 Controller [Alpine Ridge] [8086:15b6] (rev 03) 55 | IOMMU Group 18 06:04.0 PCI bridge [0604]: Intel Corporation DSL6540 Thunderbolt 3 Bridge [Alpine Ridge 4C 2015] [8086:1578] (rev 03) 56 | 57 | 58 | ## Configuration 59 | 60 | - There are some system config files in the `/etc` directory in this repo. 61 | - `/etc/modprobe.d/vfio.conf`: vfio-pci module options, basically the device 62 | IDs to rebind - `options vfio-pci ids=10de:1b81,10de:10f0` for the GPU. 63 | - /etc/mkinitcpio.conf: vfio-pci needs to be early-loaded, building the kernel 64 | image with it is required. Without this, GPU may be claimed by nouveau: 65 | `MODULES="vfio vfio_iommu_type1 vfio_pci vfio_virqfd i915"` 66 | - Hugepages are used for VM memory backing - put this in your kernel cmdline: 67 | `hugepagesz=1GB default_hugepagesz=1G transparent_hugepage=never` and this in 68 | your `/etc/fstab`: `hugetlbfs /hugepages hugetlbfs mode=1770,gid=78 0 0`. All 69 | of this will not enable hugepages on boot, but rather allocate them when the 70 | VM starts. Since those pages are now 1GB each, your system might not be able 71 | to enable them all after fragmenting its memory - just reboot and try again. 72 | 73 | After editing modules, this rebuilds the kernel image: `# mkinitcpio -p linux` 74 | 75 | 76 | ## Hugepages 77 | 78 | Until the recent Meltdown/Spectre patches, the VM had some occasional, short 79 | "hiccups" (Decepticon sounds along with the VM hanging for ~0.2s). Occasional, 80 | so I didn't really mind that much - it was irritating, but not enough to fix it 81 | until very recently. After PTI patches, those hiccups started to occur way more 82 | often (every ~10s or so), which made most games unplayable. After some tweaks 83 | with CPU pinning and using hugepages for VM memory, most problems went away for 84 | good - the only problem is that now hugepages are required for the VM to work. 85 | 86 | [This ArchWiki page explains how to set them up.](https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF#Static_huge_pages) 87 | 88 | Now, the article says that only static hugepages are supported and it appears 89 | to be correct - QEMU crashed with transparent hugepages enabled. However, I 90 | play games rather rarely as of late and I'm not up for having 10GBs of RAM in 91 | there consumed just because I might play games like once a week - instead, the 92 | script used to start the VM enables them on demand (`vfio_enable_hugepages`). 93 | To do the same in your setup, skip `hugepages=X` in the kernel parameters. 94 | 95 | There's a big problem with this approach, through: After the system has booted 96 | up, the memory gets fragmented very quickly, so allocating 1GB hugepages gets 97 | problematic - the system will allocate only up to the amount of pages that it 98 | can find space for, and after running a few applications there's virtually no 99 | contiguous, free 1GB blocks of memory to allocate. To fix this, reboot your 100 | computer and run the VM right after your system has started. Once allocated, 101 | you can keep using both the VM and host normally (hugepages aren't getting 102 | deallocated on VM shutdown, since I might want to restart it or something - 103 | `vfio_disable_hugepages` does so, but once you run that, you probably won't be 104 | able to allocate these pages again until reboot). 105 | 106 | 107 | ## Message-Signalled Interrupts 108 | 109 | [This Guru3D thread](http://forums.guru3d.com/showthread.php?t=378044) explains 110 | how to configure and manage MSI for devices under Windows. It allows devices to 111 | perform interrupts with standard PCI messages instead of the interrupt line, 112 | which behaves a bit nicer under QEMU. The linked "MSI utility v2" is okay, but 113 | be careful not to turn on MSI for some devices like the SATA controllers, since 114 | Windows might no longer boot after that (load last known good configuration in 115 | the Boot Manager to get it running again, but DISABLE MSI for those devices). 116 | 117 | Checking whenever a device has MSI enabled: 118 | - Open the Device Manager. 119 | - Menu "View -> Resources by type". Expand "Interrupt request (IRQ)". 120 | - PCI devices with negative IRQ numbers have MSI enabled. 121 | 122 | Also, driver updates tend to disable MSI, so visit that utility periodically. 123 | 124 | 125 | ## PulseAudio Setup (Legacy) 126 | 127 | I've fixed a couple of other things preventing me from running QEMU as my own 128 | user account, so I don't need to do the stuff below anymore (QEMU_PA_SERVER now 129 | points at the local Unix socket). For documentation purposes, my previous setup 130 | is still documented below. This lets you run QEMU as nobody/nogroup and still 131 | have working audio, with minimal extra latency. 132 | 133 | --- 134 | 135 | Finally got PulseAudio to work flawlessly - normally, QEMU needs to be run as 136 | the user owning the running PA server. This breaks a few other things though, 137 | so I tried to find another way to connect to PA. It turns out PA supports TCP 138 | sockets as a standard transport, built-in, just needs to be enabled. Install 139 | and get PulseAudio running, then in `/etc/pulse/default.pa` edit the line: 140 | 141 | #load-module module-native-protocol-tcp 142 | 143 | ...to: 144 | 145 | load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.1.0/24 auth-anonymous=1 146 | 147 | Save that file and restart PulseAudio. 148 | 149 | This allows anybody in your local network (192.168.1.1-254) and on your PC to 150 | connect to the PA daemon without authentication (`auth-anonymous=1`). Normally 151 | PA requires the connecting party to own a shared "cookie", but the `nobody` 152 | user QEMU runs under can't have that - since I trust everyone in my network not 153 | to play disco polo at 3am on my computer while I'm sleeping next to it, it's 154 | fine for now. It'd be nice to find a lightweight auth scheme (shared password 155 | in the PA connection string, or something like that?), though. 156 | 157 | In your domain file, at the very top, replace this: 158 | 159 | 160 | 161 | ...with this: 162 | 163 | 164 | 165 | Then, under the `...` section, put this: 166 | 167 | 168 | 169 | 170 | 171 | 172 | *Et voila!* We have sound. You might want to restart the VM, or make sure PA 173 | actually reloaded the default.pa config file (with `pactl list-modules`), for 174 | everything to start working. 175 | 176 | **As of QEMU 3.0** you also need to make sure your emulated machine is at least 177 | `pc-q35-3.0` or newer (in libvirt's XML files, the line to edit is 178 | `hvm`). Some improvements were 179 | made to the emulated audio card, but they'll only be enabled if you explicitly 180 | ask for the latest machine model. (Latest machine type is `pc-q35-3.1` and is 181 | perfectly fine, too.) 182 | 183 | If your audio still gets a bit Decepticon-ish, you might need a patched QEMU 184 | build - there's a QEMU fork with a new PulseAudio backend that's way less 185 | glitchy, [made by Spheenik](https://github.com/spheenik/qemu/). Arch users can 186 | use [this AUR package](https://aur.archlinux.org/packages/qemu-patched) which 187 | uses those patches on the latest QEMU version. Also see the note on Linux-ck 188 | below, if you're using that. 189 | 190 | 191 | ## Linux-ck Stuttering 192 | 193 | For a long while I've used the [CK patchset](https://ck-hack.blogspot.com/) for 194 | its superb desktop responsiveness under high I/O load. For some reason, recent 195 | versions (since MuQSS introduction?) introduced very nasty stuttering in gaming 196 | VMs that ranges from irritating to deal-breaking. Vanilla kernel doesn't do any 197 | of this, and the I/O scheduler that made responsiveness so good on HDDs (BFQ) 198 | is available as well (it wasn't when I've started to use Linux-ck). 199 | 200 | So, if you're using Linux-ck and experiencing insane stuttering, try vanilla 201 | kernel instead. (Would be nice to test with `linux-clear` one day...) 202 | 203 | 204 | ## Using NVIDIA GPU on the host 205 | 206 | If you're not planning on gaming for a bit, you may want to switch your host to 207 | the NVIDIA GPU temporarily. [nvidia-xrun](https://github.com/Witko/nvidia-xrun) 208 | provides configuration and helper scripts to run X.org on the NVIDIA GPU with a 209 | separate command and separate `.xinitrc` called `.nvidia-xrun`. 210 | 211 | On my system, `.nvidia-xrun` basically contains the same stuff as `.xinitrc`, 212 | so that it starts the same desktop environment, uses same config files, etc. 213 | To run it, you'll need to `sudo rmmod vfio-pci` first, and then `nvidia-xrun` 214 | (it automatically loads the NVIDIA kernel driver and sets up everything you 215 | need, aside from unloading the vfio-pci driver). 216 | --------------------------------------------------------------------------------