{"id":13622719,"url":"https://github.com/lennard0711/vfio","last_synced_at":"2025-04-15T09:33:37.436Z","repository":{"id":217078230,"uuid":"353850438","full_name":"lennard0711/vfio","owner":"lennard0711","description":"This is the config for my VFIO gaming VM","archived":false,"fork":false,"pushed_at":"2022-05-25T15:29:53.000Z","size":35,"stargazers_count":31,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-08-01T21:54:52.918Z","etag":null,"topics":["kvm","vfio","vfio-setup","virtual-machine","virtualization"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"eupl-1.2","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lennard0711.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-01T23:20:48.000Z","updated_at":"2024-05-26T05:14:45.000Z","dependencies_parsed_at":null,"dependency_job_id":"e1f20a9f-e08d-4ab3-905e-e65b3afa5be0","html_url":"https://github.com/lennard0711/vfio","commit_stats":null,"previous_names":["lennard0711/vfio"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lennard0711%2Fvfio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lennard0711%2Fvfio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lennard0711%2Fvfio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lennard0711%2Fvfio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lennard0711","download_url":"https://codeload.github.com/lennard0711/vfio/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223668327,"owners_count":17182913,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kvm","vfio","vfio-setup","virtual-machine","virtualization"],"created_at":"2024-08-01T21:01:23.293Z","updated_at":"2024-11-08T10:30:52.561Z","avatar_url":"https://github.com/lennard0711.png","language":"Shell","funding_links":[],"categories":["Shell"],"sub_categories":[],"readme":"# VFIO\nIn this repo you can find everything about my VFIO setup. I mainly use it for gaming on a Windows VM while using a Arch Linux host system.\n\nI mostly used the Arch Wiki to setup everything, especially this page: [PCI passthrough via OVMF](https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF)\n\n## TODOs\n- [x] Create QEMU hooks to disable host screen 1 after booting the VM\n- [x] Isolate pinned CPUs\n- [ ] Pass through USB controller for hotplugging support in the VM\n- [ ] Document mainboard settings\n\n## Hardware\n\nType | Device | Info\n------------ | ------------- | -------------\nMainboard | ASRock X570 Pro4\nCPU | AMD Ryzen 7 3700x | 8C/16T\nGPU | AMD XFX Radeon RX 580 GTS Core Aktiv | VFIO\nGPU | MSI GeForce GT 1030 Aero ITX | Host\nRAM | 16GB G.Skill Aegis DDR4-3200\nRAM | 16GB G.Skill Aegis DDR4-3200\nSSD | 500 GB Crucial P1 NVMe | /dev/nvme0n1\nSSD | 500 GB Crucial MX500 SATA | /dev/sdb\nHDD | 1000 GB Seagate BarraCuda ST1000DM010 | /dev/sda\nHDD | 1000 GB Seagate BarraCuda ST1000DM010 | /dev/sdc\n\n## Mainboard Settings\ntba\n\n## Installation\n\n### Arch Linux\n#### Packages\n* `libvirt`\n* `qemu`\n* `edk2-ovmf`\n* `ebtables`\n* `dnsmasq`\n* `bridge-utils`\n* `openbsd-netcat`\n* `virt-manager`\n\nInstall all packages via pacman:\n\n`sudo pacman -S libvirt qemu edk2-ovmf ebtables dnsmasq bridge-utils openbsd-netcat virt-manager`\n\nEnable \u0026 start the libvirt service:\n\n`sudo systemctl enable --now libvirtd.service`\n\n#### User Group\nAdd yourself to the `libvirt` group to get passwordless access to the QEMU system socket.\n\n## Partition Setup\nAll devices are luks2 encrypted.\n\nAll hard drives have at least one lvm volume which is passed through to the VM.\n\n`/dev/sda` is used as a HDD to store all games on.\n\n`/dev/sdb` is used as the SSD to run the OS and most programs.\n\n`/dev/sdc` is used to store my other VMs.\n```\nsda                            8:0    0 931,5G  0 disk  \n└─win10-hdd                  254:5    0 931,5G  0 crypt \n  └─win10--hdd-games         254:6    0 931,5G  0 lvm   \nsdb                            8:16   0 465,8G  0 disk  \n└─win10-ssd                  254:3    0 465,7G  0 crypt \n  └─win10--ssd-root          254:4    0 465,7G  0 lvm   \nsdc                            8:32   0 931,5G  0 disk  \n└─sdc1                         8:33   0 931,5G  0 part  \n  └─libvirt                  254:7    0 931,5G  0 crypt \n    ├─libvirt-gentoo         254:8    0    50G  0 lvm   \n    ├─libvirt-fedora         254:9    0   100G  0 lvm   \n    ├─libvirt-ubuntu         254:10   0   100G  0 lvm   \n    ├─libvirt-rhel           254:11   0   100G  0 lvm   \n    └─libvirt-RDPWindows     254:12   0    80G  0 lvm   \nnvme0n1                      259:0    0 465,8G  0 disk  \n├─nvme0n1p1                  259:1    0   512M  0 part  /boot\n└─nvme0n1p2                  259:2    0 465,3G  0 part  \n  └─cryptroot                254:0    0 465,2G  0 crypt \n    ├─arch-swap              254:1    0    32G  0 lvm   [SWAP]\n    └─arch-root              254:2    0 433,2G  0 lvm   /\n```\n\n## VM config\n\n### Hypervisor Details\n\nType | Info \n------------ | -------------\nHypervisor | KVM\nArchitecture | x86_64\nEmulator | /usr/bin/qemu-system-x86_64\nChipset | i440FX\nFirmware | UEFI x86_64: /usr/share/edk2-ovmf/x64/OVMF_CODE.fd\n\n\n### CPU\n#### Cores\nUse 1 Socket with 6 cores and 2 threads = 12 threads\n\nTo use the nested virtualisation feature on Windows with an AMD Chipset, you'll need to use the Windows insider builds!\n\nI don't use it for my Windows VM but for others (RHEL), that's why I have it enabled in the `/etc/modprode.d/kvm.conf` config.\n\nSo unless you want to play Valorant which needs Hyper-V enabled and working nested virtualisation in order to work, you can skip the `/etc/modprode.d/kvm.conf` part.\n\n`/etc/libvirt/qemu/win10.xml`\n```xml\n\u003ccpu mode=\"host-passthrough\" check=\"none\" migratable=\"on\"\u003e\n  \u003ctopology sockets=\"1\" dies=\"1\" cores=\"6\" threads=\"2\"/\u003e\n  \u003cfeature policy=\"require\" name=\"topoext\"/\u003e\n\u003c/cpu\u003e\n```\n\n`/etc/modprobe.d/kvm.conf`\n```\noptions kvm_amd nested=1\noptions kvm ignore_msrs=1\n```\n#### CPU pinning\nThis pins specific CPUs to my VM, but it won't hinder other processes to use them. \n\n`/etc/libvirt/qemu/win10.xml`\n```xml\n\u003cvcpu placement=\"static\"\u003e12\u003c/vcpu\u003e\n\u003ccputune\u003e\n  \u003cvcpupin vcpu=\"0\" cpuset=\"2\"/\u003e\n  \u003cvcpupin vcpu=\"1\" cpuset=\"10\"/\u003e\n  \u003cvcpupin vcpu=\"2\" cpuset=\"3\"/\u003e\n  \u003cvcpupin vcpu=\"3\" cpuset=\"11\"/\u003e\n  \u003cvcpupin vcpu=\"4\" cpuset=\"4\"/\u003e\n  \u003cvcpupin vcpu=\"5\" cpuset=\"12\"/\u003e\n  \u003cvcpupin vcpu=\"6\" cpuset=\"5\"/\u003e\n  \u003cvcpupin vcpu=\"7\" cpuset=\"13\"/\u003e\n  \u003cvcpupin vcpu=\"8\" cpuset=\"6\"/\u003e\n  \u003cvcpupin vcpu=\"9\" cpuset=\"14\"/\u003e\n  \u003cvcpupin vcpu=\"10\" cpuset=\"7\"/\u003e\n  \u003cvcpupin vcpu=\"11\" cpuset=\"15\"/\u003e\n  \u003cemulatorpin cpuset=\"0,8\"/\u003e\n\u003c/cputune\u003e\n```\n#### CPU isolation\nThis isolates the pinned CPUs to hinder processes from the host to use them\n```bash\nsystemctl set-property --runtime -- user.slice AllowedCPUs=0,1,8,9\nsystemctl set-property --runtime -- system.slice AllowedCPUs=0,1,8,9\nsystemctl set-property --runtime -- init.scope AllowedCPUs=0,1,8,9\n```\nThis frees all CPUs to let the host use all CPUs again\n```bash\nsystemctl set-property --runtime -- user.slice AllowedCPUs=0-15\nsystemctl set-property --runtime -- system.slice AllowedCPUs=0-15\nsystemctl set-property --runtime -- init.scope AllowedCPUs=0-15\n```\nI use these commands in my QEMU hook script [here](https://github.com/lennard0711/vfio/blob/main/etc/libvirt/hooks/qemu.d/win10.sh)\n\n### Disks\n#### Boot Disk / SSD\n`/etc/libvirt/qemu/win10.xml`\n```xml\n\u003cdisk type=\"block\" device=\"disk\"\u003e\n  \u003cdriver name=\"qemu\" type=\"raw\" cache=\"none\" io=\"native\"/\u003e\n  \u003csource dev=\"/dev/win10-ssd/root\"/\u003e\n  \u003ctarget dev=\"vda\" bus=\"virtio\"/\u003e\n  \u003cboot order=\"1\"/\u003e\n  \u003caddress type=\"pci\" domain=\"0x0000\" bus=\"0x00\" slot=\"0x07\" function=\"0x0\"/\u003e\n\u003c/disk\u003e\n```\n\n#### HDD\n`/etc/libvirt/qemu/win10.xml`\n```xml\n\u003cdisk type=\"block\" device=\"disk\"\u003e\n  \u003cdriver name=\"qemu\" type=\"raw\" cache=\"none\" io=\"native\"/\u003e\n  \u003csource dev=\"/dev/win10-hdd/games\"/\u003e\n  \u003ctarget dev=\"vdb\" bus=\"virtio\"/\u003e\n  \u003caddress type=\"pci\" domain=\"0x0000\" bus=\"0x00\" slot=\"0x08\" function=\"0x0\"/\u003e\n\u003c/disk\u003e\n```\n\n### Audio\nI pass my audio directly to my pulseaudio server (provided by pipewire).\n\n`/etc/libvirt/qemu.conf`\n```\nuser = \"lennard0711\"\n```\n\n`/etc/libvirt/qemu/win10.xml`\n```xml\n\u003caudio id='1' type='pulseaudio' serverName='/run/user/1000/pulse/native'/\u003e\n```\n\n### Automatic monitor switching\nAll my monitors are set to autodetect signals.\n\nMy Linux GPU is connected via DVI to my gaming monitor so i just deactivate it via xrandr.\n\nTo get my dual screen setup back, I just enable the DVI output again and set the HDMI output as primary display.\n\nWith this QEMU hook script it switches my monitors automatically when i start/stop my VM\n\n`/etc/libvirt/hooks/qemu.d/win10.sh`\n```bash\n#!/bin/bash\nif [[ $1 == \"win10\" ]]; then\n  if [[ $2 == \"started\" ]]; then\n    # CPU isolation\n    systemctl set-property --runtime -- user.slice AllowedCPUs=0,1,8,9\n    systemctl set-property --runtime -- system.slice AllowedCPUs=0,1,8,9\n    systemctl set-property --runtime -- init.scope AllowedCPUs=0,1,8,9\n    # Disable DVI-D-0\n    su -l lennard0711 -c \"DISPLAY=:0 xrandr --output DVI-D-0 --off\"\n  fi\n  if [[ $2 == \"stopped\" ]]; then\n    # Free all CPUs\n    systemctl set-property --runtime -- user.slice AllowedCPUs=0-15\n    systemctl set-property --runtime -- system.slice AllowedCPUs=0-15\n    systemctl set-property --runtime -- init.scope AllowedCPUs=0-15\n    # Enable DVI-D-0\n    su -l lennard0711 -c \"DISPLAY=:0 xrandr --output DVI-D-0 --auto --left-of HDMI-0\"\n    su -l lennard0711 -c \"DISPLAY=:0 xrandr --output HDMI-0 --primary\"\n  fi\nfi\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flennard0711%2Fvfio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flennard0711%2Fvfio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flennard0711%2Fvfio/lists"}