- name: Setup GPU passthrough host (Fedora + QEMU/KVM) hosts: localhost become: true vars: host_reserved_cpu: "0-1" gaming_vm_cpus: "2-9" ai_vm_cpus: "10-11" vfio_ids: - 10de:2482 # NVIDIA Corporation GA104 [GeForce RTX 3070 Ti] - 10de:228b # NVIDIA Corporation GA106 High Definition Audio Controller - 10de:2504 # NVIDIA Corporation GA106 [GeForce RTX 3060 Lite Hash Rate] - 10de:228e # NVIDIA Corporation GA106 High Definition Audio Controller - 1b73:1100 # Fresco Logic FL1100 USB 3.0 Host Controller # - 144d:a808 # Samsung Electronics Co Ltd NVMe SSD Controller SM981/PM981/PM983 grub_config_file: "/etc/default/grub" grub_cmdline_args: > rhgb quiet intel_iommu=on iommu=pt isolcpus=1-5,7-11 nohz_full=1-5,7-11 rcu_nocbs=1-5,7-11 i915.modeset=1 i915.enable_gvt=1 i915.enable_fbc=0 initcall_blacklist=simpledrm_platform_driver_init rd.driver.blacklist=nouveau modprobe.blacklist=nouveau snd_hda_codec_hdmi.blacklist=1 rd.driver.pre=vfio-pci audit=off win_partition: "/dev/nvme0n1p1" ai_partition: "/dev/nvme0n1p2" partitions: - { dev: "/dev/nvme0n1p1", label: "win-nvme" } - { dev: "/dev/nvme0n1p2", label: "ai-nvme" } tasks: - name: Install virtualization packages ansible.builtin.dnf: name: - qemu-kvm - libvirt - virt-install - virt-manager - bridge-utils - pciutils state: present - name: Enable and start libvirtd ansible.builtin.systemd: name: libvirtd enabled: true state: started - name: Ensure GRUB_CMDLINE_LINUX is configured for vfio, isolcpus, nohz_full, rcu_nocbs ansible.builtin.lineinfile: path: "{{ grub_config_file }}" regexp: '^GRUB_CMDLINE_LINUX=' line: 'GRUB_CMDLINE_LINUX="{{ grub_cmdline_args | trim }}"' backrefs: true - name: Add VFIO PCI device IDs to modprobe ansible.builtin.copy: dest: /etc/modprobe.d/vfio.conf content: | options vfio-pci ids={{ vfio_ids | join(',') }} install snd_hda_codec_hdmi /bin/false mode: '0644' - name: Blacklist Nouveau and other drivers ansible.builtin.copy: dest: /etc/modprobe.d/ansible-blacklist.conf content: | blacklist noveau blacklist snd_hda_codec_hdmi blacklist i2c_nvidia_gpu blacklist mxm_wmi mode: '0644' - name: Add vfio modules to initramfs config ansible.builtin.copy: dest: /etc/dracut.conf.d/vfio.conf content: | add_drivers+=" vfio vfio_iommu_type1 vfio_pci " mode: '0644' - name: Rebuild initramfs changed_when: false ansible.builtin.command: dracut -f - name: Rebuild GRUB config changed_when: false ansible.builtin.command: grub2-mkconfig -o /boot/grub2/grub.cfg when: ansible_facts['distribution'] == "Fedora" - name: Enable KVM modules at boot ansible.builtin.copy: dest: /etc/modules-load.d/kvm.conf content: | kvmgt mdev vfio vfio-pci vfio_iommu_type1 mode: '0644' - name: Notify user to reboot for changes ansible.builtin.debug: msg: | Reboot your system to apply IOMMU, CPU isolation, and VFIO settings. After reboot, verify using: `dmesg | grep -i vfio` and `lspci -nnk` - name: Ensure partitions are unmounted ansible.posix.mount: path: "/mnt/{{ item.label }}" src: "{{ item.dev }}" state: absent fstype: auto loop: "{{ partitions }}" - name: Set permissions for partition passthrough ansible.builtin.file: path: "{{ item.dev }}" owner: qemu group: kvm mode: '0660' loop: "{{ partitions }}" - name: Create udev rules for persistent access ansible.builtin.copy: dest: /etc/udev/rules.d/99-qemu-nvme.rules content: | KERNEL=="nvme0n1", OWNER="qemu", GROUP="kvm", MODE="0660" KERNEL=="nvme0n1p1", OWNER="qemu", GROUP="kvm", MODE="0660" KERNEL=="nvme0n1p2", OWNER="qemu", GROUP="kvm", MODE="0660" mode: '0644' notify: - Reload udev rules - Trigger udev to apply changes handlers: - name: Reload udev rules changed_when: false ansible.builtin.command: udevadm control --reload-rules - name: Trigger udev to apply changes changed_when: false ansible.builtin.command: udevadm trigger