├── 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 |
--------------------------------------------------------------------------------