A complete guide to running a Windows 11 VM with GPU passthrough and Looking Glass on an Arch-based Linux system with a Wayland compositor. This setup allows you to run Windows-only software like Fusion 360 in a native-feeling window on your Linux desktop, with near-zero latency and no compression artifacts.
This guide was written from a real setup session, including every issue encountered and how it was resolved. If you're running into problems, there's a good chance the answer is in here.
System Specifications #
| Component | Detail |
|---|---|
| Host OS | CachyOS (Arch-based) with Hyprland (Wayland) |
| Host GPU | NVIDIA GeForce RTX 3080 Ti |
| Guest GPU | NVIDIA GeForce GTX 1080 (passed through to VM) |
| CPU | Intel i9-12900K (16 cores, 24 threads) |
| RAM | 64 GB total, 32 GB allocated to VM |
| QEMU | 6.2+ (JSON-style configuration) |
| libvirt | 7.9+ |
| NVIDIA driver | 590.48.01 |
| Looking Glass | B7 stable release |
| Target resolution | 3440×1440 (ultrawide) |
How Looking Glass Works #
Before diving into configuration, it helps to understand the architecture.
Looking Glass works by sharing GPU framebuffer data between the Windows VM and your Linux host through shared memory, completely bypassing the normal display output path.
The host application runs inside the Windows VM. It uses the Desktop Duplication API (D12 on Windows 10+) to capture frames the GPU is rendering — the same way screen recording works. Instead of encoding those frames into a video stream like RDP or VNC, it writes raw, uncompressed frame data directly into a shared memory region.
That shared memory region is the IVSHMEM device — a virtual PCI device that both the VM and the host can access simultaneously. It's a chunk of RAM that exists at the same physical memory addresses for both sides. The KVMFR kernel module manages this on the Linux side, and the IVSHMEM PCI driver handles it on the Windows side.
The client application runs on your Linux desktop. It maps that same shared memory region and reads the frame data directly. Because there's no encoding, decoding, or network transport involved, the latency is extremely low — essentially the time it takes to copy pixels from GPU memory into shared memory, plus one DMA transfer.
SPICE runs alongside as a separate channel purely for input — keyboard, mouse, clipboard sync, and audio. The actual video frames never touch SPICE.
Part 0: VFIO GPU Passthrough Setup #
This section covers everything needed to get the guest GPU claimed by VFIO and passed through to the VM. If you already have a working passthrough setup, skip to Part 1.
0.1 Enable VT-d in BIOS
This is the number one thing people miss. The kernel parameter intel_iommu=on does nothing if the CPU feature isn't enabled in firmware.
Reboot into BIOS/UEFI and look for one of these settings (varies by motherboard manufacturer):
- VT-d
- Intel Virtualization Technology for Directed I/O
- IOMMU
Enable it, save, and exit. Also confirm VT-x (CPU virtualization) is enabled while you're there.
0.2 Kernel Parameters
CachyOS uses systemd-boot. The correct way to set persistent kernel parameters is through /etc/sdboot-manage.conf, not by editing boot entries directly (those get overwritten on kernel updates).
sudo vim /etc/sdboot-manage.conf
Find the LINUX_OPTIONS line and set:
LINUX_OPTIONS="intel_iommu=on rd.driver.pre=vfio-pci video=efifb:off"
Then regenerate the boot entries:
sudo sdboot-manage gen
Reboot and verify:
cat /proc/cmdline
You should see your parameters in the output.
Troubleshooting: iommu=pt Causes Empty IOMMU Groups
Problem: ls /sys/kernel/iommu_groups/ shows an empty directory despite VT-d being enabled and intel_iommu=on in the kernel parameters.
Cause: iommu=pt (passthrough mode) can prevent IOMMU groups from being populated. The dmesg output will show Default domain type: Passthrough — meaning devices aren't being isolated.
Fix: Remove iommu=pt from your kernel parameters entirely, or change it to iommu=1. Despite being commonly recommended in guides, passthrough mode defeats the purpose of VFIO isolation. The rd.driver.pre=vfio-pci parameter is what actually matters for early VFIO binding.
Troubleshooting: Kernel Parameters Disappear After Updates
Problem: After a system update, cat /proc/cmdline no longer shows your VFIO parameters.
Cause: CachyOS regenerates systemd-boot entries during kernel updates, overwriting manual edits to /boot//entries/*.conf.
Fix: Use /etc/sdboot-manage.conf as described above — this is the CachyOS-specific mechanism for persistent kernel parameters. Never edit boot entries directly; always use LINUX_OPTIONS in the config file and run sudo sdboot-manage gen to apply.
0.3 Identify Your GPUs
lspci -nn | grep -E "VGA|Audio" | grep -i nvidia
Example output for a dual-GPU system:
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA102 [GeForce RTX 3080 Ti] [10de:2208] (rev a1)
01:00.1 Audio device [0403]: NVIDIA Corporation GA102 High Definition Audio Controller [10de:1aef] (rev a1)
08:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP104 [GeForce GTX 1080] [10de:1b80] (rev a1)
08:00.1 Audio device [0403]: NVIDIA Corporation GP104 High Definition Audio Controller [10de:10f0] (rev a1)
Note the device IDs in brackets. In this case, the GTX 1080 (guest GPU) has IDs 10de:1b80 (GPU) and 10de:10f0 (audio).
0.4 Bind the Guest GPU to VFIO
Create /etc/modprobe.d/vfio.conf:
options vfio-pci ids=10de:1b80,10de:10f0
softdep snd_hda_intel pre: vfio-pci
The softdep line ensures VFIO loads before the audio driver, which otherwise races to claim the GPU's audio device first.
Add VFIO modules to the initramfs so they load early enough. Edit /etc/mkinitcpio.conf:
MODULES=(vfio_pci vfio vfio_iommu_type1)
Rebuild the initramfs:
sudo mkinitcpio -P
Reboot, then verify both GPU functions are bound to vfio-pci:
lspci -nnk -s 08:00
Expected output:
08:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP104 [GeForce GTX 1080] [10de:1b80] (rev a1)
Kernel driver in use: vfio-pci
08:00.1 Audio device [0403]: NVIDIA Corporation GP104 High Definition Audio Controller [10de:10f0] (rev a1)
Kernel driver in use: vfio-pci
Troubleshooting: VFIO Not Binding (No Driver Shown)
Problem: After configuring everything, lspci -nnk shows no driver in use for the GPU.
Cause: The VFIO modules aren't in the initramfs, so they don't load early enough.
Fix: Verify the modules are actually present:
sudo lsinitcpio /boot/initramfs-linux-cachyos.img | grep vfio
Note: CachyOS names its initramfs differently (linux-cachyos or linux-cachyos-lts). If the modules aren't listed, re-check /etc/mkinitcpio.conf and rebuild with sudo mkinitcpio -P.
0.5 Create the VM and Add the GPU
Create a Windows 11 VM in virt-manager with Q35 machine type and UEFI firmware (OVMF). Then add the GPU:
- Add Hardware → PCI Host Device → select
0000:08:00.0(GPU) - Add Hardware → PCI Host Device → select
0000:08:00.1(Audio)
0.6 CPU Configuration (Critical)
The CPU mode configuration is surprisingly important for VFIO + shared memory compatibility. Using the wrong mode causes QEMU crashes with vfio_container_region_add errors when shared memory devices are present.
Working configuration:
<cpu mode='host-model' check='none'>
<topology sockets='1' dies='1' cores='18' threads='1'/>
</cpu>
What doesn't work:
host-passthroughwithmigratable='on'— causes memory mapping conflicts between the GPU passthrough and IVSHMEM device, crashing QEMUhost-passthroughwithoutmigratable— may also conflict depending on QEMU version
The host-model mode has libvirt select a compatible CPU model rather than exposing exact CPU features, which avoids the memory region overlap. The migratable attribute must be removed entirely (not set to 'off' — just absent).
Without the topology block, Windows will see an incorrect CPU layout (e.g., 2 sockets instead of 18 cores). The topology line tells Windows exactly how the vCPUs are organized. Note that vCPU allocation is shared, not reserved — your host can still use all 24 cores; the VM just won't use more than 18 at once.
0.7 Bridge Networking
For the VM to be accessible on your LAN (required for SPICE, and useful for general connectivity), set up a network bridge:
sudo nmcli connection add type bridge ifname br0 con-name br0
sudo nmcli connection add type ethernet ifname enp6s0 master br0
sudo nmcli connection up br0
Replace enp6s0 with your actual ethernet interface (check with ip link).
Then configure the VM to use the bridge in its XML:
<interface type='bridge'>
<mac address='52:54:00:xx:xx:xx'/>
<source bridge='br0'/>
<model type='e1000e'/>
</interface>
The VM will get its own IP from your router's DHCP server.
0.8 Install NVIDIA Drivers in the Guest
Once the VM boots with the passed-through GPU, install the NVIDIA drivers manually from nvidia.com. GeForce Experience often fails in VMs due to hardware detection checks, so download the standalone driver instead:
- Go to https://www.nvidia.com/Download/index.aspx
- Select GeForce → 10 Series → GTX 1080 → Windows 11
- Download and install the driver directly
Why Not Moonlight/Sunshine?
Before arriving at Looking Glass, Moonlight/Sunshine was tested as an alternative. The results for this particular use case (CAD work at 3440×1440) were not satisfactory:
- At 165 FPS (native refresh rate), massive compression artifacts appeared — NVENC on the GTX 1080 can't keep up at that frame rate
- At 60 FPS with 150 Mbps bitrate, image quality was acceptable but mouse input felt sluggish — unacceptable for precision CAD work in Fusion 360
- HEVC encoding wasn't available (Moonlight client-side decoding issues on CachyOS)
- Even with optimized settings, the encode/decode pipeline adds perceptible latency compared to raw framebuffer sharing
For gaming or media consumption, Moonlight/Sunshine is excellent. For daily-driver CAD/productivity work where you need pixel-perfect rendering and zero input lag, Looking Glass is the correct tool.
Approaches That Were Tried and Abandoned
GL.iNet Comet Pro (IP KVM): Hardware-based HDMI capture from the GTX 1080. Works for remote access and BIOS-level troubleshooting, but adds its own compression and latency. Useful as a fallback but not a primary display solution for productivity work.
Intel iGPU passthrough (GVT-d): The i9-12900K has a UHD 770 iGPU, but 12th gen Alder Lake does not support GVT-g (mediated/shared GPU). GVT-d requires full passthrough, meaning the host loses the iGPU entirely (must blacklist i915). Combined with known Code 43 errors, missing VBIOS issues, and special OpROM requirements, this was not worth pursuing when the GTX 1080 is vastly more capable for Fusion 360.
Part 1: KVMFR Kernel Module #
The KVMFR module creates a character device (/dev/kvmfr0) that provides a high-performance shared memory interface between host and guest.
1.1 Build and Install via DKMS
Clone the Looking Glass B7 stable release (not git master — the client and host versions must match):
cd ~/source
git clone --branch B7 --single-branch https://github.com/gnif/LookingGlass.git looking-glass-B7
cd looking-glass-B7/module
Install via DKMS so the module rebuilds automatically on kernel updates:
sudo dkms install "."
1.2 Calculate Shared Memory Size
The formula from the Looking Glass docs:
width × height × 4 × 2 = frame bytes
round up to nearest power of 2 in MB
For 3440×1440:
3440 × 1440 × 4 × 2 = 39,628,800 bytes ≈ 37.8 MB
Round up to nearest power of 2 → 64 MB
However, 64 MB can be tight for ultrawide resolutions. We used 128 MB to provide headroom and avoid any frame corruption issues.
1.3 Configure the Module
Create /etc/modprobe.d/kvmfr.conf:
options kvmfr static_size_mb=128
Create /etc/modules-load.d/kvmfr.conf to auto-load at boot:
kvmfr
1.4 Set Up udev Rules
Create /etc/udev/rules.d/99-kvmfr.rules:
SUBSYSTEM=="kvmfr", OWNER="your_username", GROUP="kvm", MODE="0660"
Replace your_username with your actual Linux username.
Reload and trigger:
sudo udevadm control --reload-rules
sudo udevadm trigger
1.5 Load the Module
sudo modprobe kvmfr
Verify it's working:
ls -l /dev/kvmfr0
You should see a character device (permissions start with c) owned by your user:
crw-rw---- 1 your_username kvm 508, 0 Feb 8 15:32 /dev/kvmfr0
Troubleshooting: /dev/kvmfr0 Permissions
Problem: After the module, /dev/kvmfr0 is owned by root with mode 600.
Cause: The udev rule didn't trigger, or the module was reloaded after creating the device (which creates a fresh device node without re-triggering udev).
Fix: Apply permissions manually for the current session, then fix the udev rule for persistence:
sudo chown your_username:kvm /dev/kvmfr0
sudo chmod 660 /dev/kvmfr0
Troubleshooting: /dev/kvmfr0 is a Regular File
Problem: ls -l /dev/kvmfr0 shows a regular file (permissions start with -) instead of a character device (c).
Cause: The VM was started before the KVMFR module was loaded. QEMU creates a regular file as a fallback.
Fix: Stop the VM, remove the file, load the module, then start the VM:
virsh destroy win11
sudo rm /dev/kvmfr0
sudo modprobe kvmfr
virsh start win11
Part 2: libvirt / QEMU Configuration #
2.1 Add QEMU Namespace to Domain XML
The <domain> tag needs the QEMU namespace for the commandline passthrough:
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
This must be done in the same virsh edit session as adding the QEMU commandline block.
2.2 Add KVMFR Shared Memory Device
Add this block at the bottom of your VM XML, just before </domain>:
<qemu:commandline>
<qemu:arg value="-device"/>
<qemu:arg value="{'driver':'ivshmem-plain','id':'shmem0','memdev':'looking-glass'}"/>
<qemu:arg value="-object"/>
<qemu:arg value="{'qom-type':'memory-backend-file','id':'looking-glass','mem-path':'/dev/kvmfr0','size':134217728,'share':true}"/>
</qemu:commandline>
The size is in bytes: 128 MB × 1024 × 1024 = 134,217,728.
Important: This is JSON-style syntax required for QEMU 6.2+ / libvirt 7.9+. Using the older comma-separated syntax on newer versions will cause a "PCI slot not available" error.
2.3 Remove Conflicting shmem Block
If you previously tried the standard shared memory approach, remove any <shmem> block like this:
<!-- REMOVE THIS if present -->
<shmem name='looking-glass'>
<model type='ivshmem-plain'/>
<size unit='M'>128</size>
</shmem>
The QEMU commandline block replaces it. Having both will cause conflicts.
2.4 Disable Memory Ballooning
Change the memballoon device from virtio to none:
<memballoon model="none"/>
The virtio balloon driver causes performance issues with VFIO passthrough.
2.5 Remove USB Tablet Device
Looking Glass is incompatible with absolute pointing devices. Remove the USB tablet:
<!-- REMOVE THIS -->
<input type="tablet" bus="usb">
<address type="usb" bus="0" port="1"/>
</input>
Without removing this, you'll get mouse input issues and the Looking Glass FAQ explicitly calls this out.
2.6 Configure SPICE for Input
SPICE provides keyboard, mouse, and clipboard sync to the VM (video is handled by Looking Glass, not SPICE):
<graphics type="spice" autoport="yes">
<listen type="address" address="127.0.0.1"/>
</graphics>
Install SPICE guest tools inside Windows for clipboard sync and proper integration.
2.7 Configure cgroups for /dev/kvmfr0
Edit /etc/libvirt/qemu.conf and find the cgroup_device_acl block. Uncomment it and add /dev/kvmfr0:
cgroup_device_acl = [
"/dev/null", "/dev/full", "/dev/zero",
"/dev/random", "/dev/urandom",
"/dev/ptmx", "/dev/kvm",
"/dev/kvmfr0"
]
Then restart libvirtd:
sudo systemctl restart libvirtd
Troubleshooting: "Permission denied" on /dev/kvmfr0
Problem: VM fails to start with can't open backing store /dev/kvmfr0 for guest RAM: Permission denied.
Cause: cgroups policy is blocking QEMU from accessing the device, even if file permissions are correct.
Fix: Ensure /dev/kvmfr0 is in the cgroup_device_acl list in /etc/libvirt/qemu.conf and restart libvirtd.
Part 3: Building the Looking Glass Client #
Critical: The client and host must be built from the same release. If you install the B7 host in Windows, you must build the B7 client on Linux. Mixing versions (e.g., a B7 host with a git master client, or vice versa) will cause connection failures or protocol mismatches. Always download the same tagged release for both sides.
3.1 Install Dependencies (Arch/CachyOS)
sudo pacman -S cmake gcc libgl libegl fontconfig spice-protocol make nettle \
pkgconf binutils libxi libxinerama libxss libxcursor libxpresent \
libxkbcommon wayland-protocols ttf-dejavu libsamplerate
3.2 Build the Client
Build from the B7 stable release source (must match the Windows host version):
cd ~/source/looking-glass-B7/client
mkdir build
cd build
cmake ..
make -j$(nproc)
Verify X11 support is enabled (required for XWayland rendering with OpenGL):
grep ENABLE_X11 CMakeCache.txt
3.3 Install
sudo cp looking-glass-client /usr/local/bin/
Part 4: Windows Guest Configuration #
4.1 Install Looking Glass Host
Download the B7 host installer from the Looking Glass releases page and install it in the Windows VM.
The host runs as a Windows service under the SYSTEM account. This is important because it needs to capture the desktop even at the login screen.
Host application location: C:\Program Files\Looking Glass (host)\looking-glass-host.exe
Log file: %ProgramData%\Looking Glass (host)\looking-glass-host.txt
4.2 Install IddSampleDriver (Virtual Display)
If you don't have a physical monitor connected to the passed-through GPU, you need a virtual display driver. IddSampleDriver creates a virtual monitor that the GPU renders to, which Looking Glass then captures.
Download IddSampleDriver from its GitHub repository and install it in the Windows VM. Configure it with your desired resolution (e.g., 3440×1440).
Critical: Do not set the IddSampleDriver display as the primary display if you're still using SPICE or RDP for initial setup. If the GPU can't output to the virtual display before Looking Glass is connected, you may lose access to the VM entirely. Set it as a secondary display first, then make it primary only after confirming Looking Glass captures it.
Troubleshooting: Locked Out After IddSampleDriver Misconfiguration
Problem: Set IddSampleDriver as primary display, can't see the login screen via SPICE or any other method.
Fix: Mount the VM's disk from the Linux host and remove the driver:
virsh destroy win11
sudo modprobe nbd max_part=8
sudo qemu-nbd --connect=/dev/nbd0 /path/to/win11.qcow2
sudo fdisk -l /dev/nbd0 # Identify the Windows NTFS partition (usually p3)
sudo mount -t ntfs-3g -o rw,remove_hiberfile /dev/nbd0p3 /mnt
The remove_hiberfile option is needed because Windows Fast Startup leaves the filesystem dirty. Navigate to the IddSampleDriver installation directory and remove or rename the driver files:
sudo mv /mnt/path/to/IddSampleDriver /mnt/path/to/IddSampleDriver.bak
Unmount and disconnect:
sudo umount /mnt
sudo qemu-nbd --disconnect /dev/nbd0
Start the VM again, and it should fall back to the SPICE display.
Part 5: Running Looking Glass #
5.1 Basic Launch
looking-glass-client
The client will automatically find /dev/kvmfr0 and connect to the shared memory region. SPICE integration provides keyboard/mouse input.
5.2 The Critical Fix: OpenGL Renderer on NVIDIA + Wayland
This is the most important section in this guide. If you're running NVIDIA + Hyprland (or any Wayland compositor), you will almost certainly encounter flickering black rectangles in the Looking Glass output.
Problem: Occasional flickering black boxes/rectangles appearing in the Looking Glass window.
Root cause: The default EGL renderer has a compositing incompatibility with the NVIDIA driver under Wayland. This is not a Looking Glass bug, not a D12 capture issue, and not an IddSampleDriver problem.
Solution: Force the OpenGL renderer instead of EGL.
Create ~/.looking-glass-client.ini:
[app]
renderer=opengl
That's it. The OpenGL renderer completely eliminates the flickering without any performance penalty.
What doesn't fix it (so you don't waste time):
- Disabling D12 damage tracking (
trackDamage=falsein the Windows host config) - Switching to DXGI capture
- Downgrading egl-wayland
- Disabling explicit sync (
__NV_DISABLE_EXPLICIT_SYNC=1) - Enabling double buffering (
egl:doubleBuffer=true) - Disabling DMA (
app:allowDMA=no) - Unsetting
WAYLAND_DISPLAY(this forces XWayland, which works but is unnecessary)
The OpenGL renderer is the clean, correct fix.
5.3 VM Autostart
To have the Windows VM start automatically at boot:
virsh autostart win11
To disable later:
virsh autostart --disable win11
Complete Configuration Reference #
VM XML Key Sections
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
<name>win11</name>
<memory unit='GiB'>32</memory>
<vcpu placement='static'>18</vcpu>
<!-- CPU mode: host-model WITHOUT migratable (critical for VFIO + shmem) -->
<cpu mode='host-model' check='none'>
<topology sockets='1' dies='1' cores='18' threads='1'/>
</cpu>
<!-- GPU Passthrough -->
<hostdev mode='subsystem' type='pci' managed='yes'>
<source>
<address domain='0x0000' bus='0x08' slot='0x00' function='0x0'/>
</source>
</hostdev>
<hostdev mode='subsystem' type='pci' managed='yes'>
<source>
<address domain='0x0000' bus='0x08' slot='0x00' function='0x1'/>
</source>
</hostdev>
<!-- SPICE for input only -->
<graphics type="spice" autoport="yes">
<listen type="address" address="127.0.0.1"/>
</graphics>
<!-- No memory ballooning -->
<memballoon model="none"/>
<!-- NO USB tablet device -->
<!-- KVMFR shared memory -->
<qemu:commandline>
<qemu:arg value="-device"/>
<qemu:arg value="{'driver':'ivshmem-plain','id':'shmem0','memdev':'looking-glass'}"/>
<qemu:arg value="-object"/>
<qemu:arg value="{'qom-type':'memory-backend-file','id':'looking-glass','mem-path':'/dev/kvmfr0','size':134217728,'share':true}"/>
</qemu:commandline>
</domain>
Host Configuration Files
| File | Contents |
|---|---|
/etc/modprobe.d/kvmfr.conf |
options kvmfr static_size_mb=128 |
/etc/modules-load.d/kvmfr.conf |
kvmfr |
/etc/udev/rules.d/99-kvmfr.rules |
SUBSYSTEM=="kvmfr", OWNER="your_username", GROUP="kvm", MODE="0660" |
/etc/libvirt/qemu.conf |
Add /dev/kvmfr0 to cgroup_device_acl |
~/.looking-glass-client.ini |
[app] / renderer=opengl |
Windows Guest Configuration
| Component | Location |
|---|---|
| Looking Glass host | C:\Program Files\Looking Glass (host)\looking-glass-host.exe |
| Host log | %ProgramData%\Looking Glass (host)\looking-glass-host.txt |
| Capture method | D12 (default, fastest for Windows 10+) |
| IddSampleDriver | Virtual display at 3440×1440 |
| SPICE guest tools | Installed for clipboard sync |
Troubleshooting Quick Reference #
| Symptom | Cause | Fix |
|---|---|---|
VM won't start: "Permission denied" on /dev/kvmfr0 |
cgroups blocking access | Add /dev/kvmfr0 to cgroup_device_acl in qemu.conf, restart libvirtd |
/dev/kvmfr0 owned by root |
udev rule not applied | sudo chown user:kvm /dev/kvmfr0 && sudo chmod 660 /dev/kvmfr0; fix udev rule |
/dev/kvmfr0 is regular file, not char device |
VM started before module loaded | Stop VM, rm /dev/kvmfr0, modprobe kvmfr, start VM |
| VM won't start: "PCI slot not available" | Using legacy QEMU syntax on new QEMU | Use JSON-style qemu:commandline syntax |
| Flickering black boxes in LG output | EGL renderer + NVIDIA + Wayland | Set renderer=opengl in ~/.looking-glass-client.ini |
| No display in Looking Glass | Host not running / wrong display captured | Check host log; ensure IddSampleDriver is configured |
| Locked out of VM after display change | IddSampleDriver set as primary with no way to view it | Mount QCOW2 via qemu-nbd, remove driver files |
| Mouse issues in Looking Glass | USB tablet device present | Remove <input type="tablet"> from VM XML |
| No clipboard sync | SPICE tools not installed | Install SPICE guest tools in Windows |
Useful Commands #
lsmod | grep kvmfr
dmesg | grep kvmfr
ls -la /dev/kvmfr0
virsh start win11
virsh destroy win11 # force stop
virsh shutdown win11 # graceful shutdown
virsh autostart win11
sudo modprobe nbd max_part=8
sudo qemu-nbd --connect=/dev/nbd0 /path/to/win11.qcow2
sudo mount -t ntfs-3g -o rw,remove_hiberfile /dev/nbd0p3 /mnt
sudo umount /mnt
sudo qemu-nbd --disconnect /dev/nbd0
looking-glass-client -d