Using Linux for Work but Still Tied to Windows Software?
Developers and DevOps engineers often choose Linux for its powerful terminal and native Docker environment. The headache begins when you need to edit 4K videos in Adobe Premiere, test DirectX applications, or jump into a few matches of Valorant or Apex Legends. Dual-booting solves this, but rebooting your machine constantly throughout the workday is both annoying and breaks your focus.
Standard virtual machines (VirtualBox, VMware) rely on virtualized graphics, making 3D rendering sluggish and choppy. GPU Passthrough (VFIO) provides a definitive solution. This technique passes an entire dedicated PCIe graphics card directly to a KVM/QEMU virtual machine. The real-world results are remarkable: 3DMark Time Spy benchmark scores inside the VM hit around 12,100 points compared to 12,450 points natively (retaining over 97% of native performance) without ever rebooting Fedora.
Understanding IOMMU and VFIO
Understanding the underlying mechanics helps you troubleshoot quickly when encountering black screens or tangled IOMMU groups:
- IOMMU (Intel VT-d / AMD-Vi): A motherboard hardware feature that allows virtual machines to directly access system RAM and PCIe devices without host kernel intervention.
- IOMMU Groups: Hardware isolation boundaries defined by your BIOS. For stable passthrough, the dedicated GPU and its accompanying audio controller must reside entirely in their own isolated group—separate from your NVMe SSDs or network cards.
- VFIO Driver (
vfio-pci): A kernel driver acting as a placeholder. It prevents host graphics drivers (nvidia,nouveau,amdgpu) from binding to the dedicated card at boot, reserving the device exclusively for QEMU.
Minimum Hardware Requirements: You need two GPUs. The most common setup is an integrated GPU (Intel UHD/Iris or AMD Radeon) for Fedora display output, paired with a dedicated PCIe card (Nvidia/AMD) passed through to Windows.
Step-by-Step Implementation on Fedora
Fedora ships with modern kernels and continuously updated VFIO patches, making the setup process relatively smooth. Here is the complete step-by-step workflow.
Step 1: Enable Hardware Virtualization and Load Kernel Parameters
Boot into your BIOS/UEFI, locate, and enable Intel VT-d or AMD IOMMU (SVM / AMD-Vi).
Boot back into Fedora, open Terminal, and add kernel parameters using grubby:
# Intel CPUs:
sudo grubby --update-kernel=ALL --args="intel_iommu=on iommu=pt"
# AMD CPUs:
sudo grubby --update-kernel=ALL --args="amd_iommu=on iommu=pt"
Reboot your system. Run the following command to verify that IOMMU is enabled:
dmesg | grep -E -i "(iommu|dmar)"
If the terminal returns DMAR: IOMMU enabled or AMD-Vi: Initialized IOMMU, your system is ready.
Step 2: Identify Hardware IDs and Verify IOMMU Groups
Run the following bash script to list your IOMMU groups:
for d in /sys/kernel/iommu_groups/*/devices/*; do
n=${d#*/iommu_groups/*}; n=${n%%/*}
printf 'IOMMU Group %s ' "$n"
lspci -nns "${d##*/}"
done | grep -i -E "vga|3d|audio"
Sample output from our test machine:
IOMMU Group 14 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA106 [GeForce RTX 3060] [10de:2503] (rev a1)
IOMMU Group 14 01:00.1 Audio device [0403]: NVIDIA Corporation GA106 High Definition Audio Controller [10de:228e] (rev a1)
Note down the two hardware IDs in brackets at the end of each line: 10de:2503 (VGA) and 10de:228e (the on-card audio controller).
Step 3: Bind the GPU to the vfio-pci Driver at Boot
Declare the extracted hardware IDs in modprobe configuration:
sudo bash -c 'cat <<EOF > /etc/modprobe.d/vfio.conf
options vfio-pci ids=10de:2503,10de:228e
EOF'
Instruct Dracut to load VFIO drivers early in the initramfs stage:
sudo bash -c 'cat <<EOF > /etc/dracut.conf.d/vfio.conf
force_drivers+=" vfio vfio_iommu_type1 vfio_pci "
EOF'
Regenerate the initramfs images and reboot:
sudo dracut --regenerate-all --force
sudo reboot
Verify whether the vfio-pci driver has taken control of the dedicated card:
lspci -k -s 01:00.0
If you see Kernel driver in use: vfio-pci, the GPU is now fully isolated from Fedora.
Step 4: Configure the Windows Virtual Machine in Virt-Manager
Install the complete KVM/QEMU virtualization stack:
sudo dnf install -y qemu-kvm libvirt virt-manager virt-install edk2-ovmf
sudo systemctl enable --now libvirtd
sudo usermod -aG libvirt $(whoami)
Open Virtual Machine Manager (virt-manager), create a Windows 10/11 VM, and configure these essential settings:
- Overview: Set Chipset to
Q35and Firmware toUEFI x86_64: .../OVMF_CODE.secboot.fd. - CPU: Set the model to
host-passthroughto pass all AVX2/SSE4 instruction sets to the VM. Configure a proper CPU topology (e.g., allocate 6 cores and 12 threads to the guest on an 8-core, 16-thread host). - Add Hardware: Click PCI Host Device and add both the VGA device (01:00.0) and its corresponding Audio device (01:00.1).
- Remove Virtual Display: Delete Display Spice, Video QXL/Virtio, and Channel spice. The physical GPU will output video directly to your monitor.
Connect an HDMI or DisplayPort cable from the dedicated GPU to a separate monitor (or switch the input source on your existing monitor). Start the VM and install the Nvidia/AMD drivers directly in Windows.
Conclusion
The most challenging part of GPU Passthrough is isolating IOMMU groups and ensuring the kernel loads the correct driver at boot. Once configured properly, you get an optimal dual-environment workflow: stable coding in Linux alongside uncompromised native performance for graphics work and gaming on Windows.

