diff --git a/hosts/focalor/hardware.nix b/hosts/focalor/hardware.nix index b290f2f..126d39c 100755 --- a/hosts/focalor/hardware.nix +++ b/hosts/focalor/hardware.nix @@ -9,8 +9,12 @@ ]; boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "uas" "usbhid" "sd_mod" ]; - boot.initrd.kernelModules = [ ]; + boot.initrd.kernelModules = [ "vfio" "vfio_iommu_type1" "vfio_pci" ]; boot.kernelModules = [ "kvm-amd" ]; + boot.kernelParams = [ + "amd_iommu=on" + "vfio-pci.ids=10de:2484,10de228b,1022:149c,15b7:5045,1dbe:5236,1022:149c" + ]; boot.extraModulePackages = [ ]; fileSystems."/" = diff --git a/hosts/focalor/scripts/vm-win11-hook.sh b/hosts/focalor/scripts/vm-win11-hook.sh new file mode 100755 index 0000000..6c9232e --- /dev/null +++ b/hosts/focalor/scripts/vm-win11-hook.sh @@ -0,0 +1,61 @@ +#!/run/current-system/sw/bin/bash + +echo "qemu-hook: ${1} ${2}" >> /tmp/qemu-hook.log + +set -x + +readonly GUEST_NAME="$1" +readonly HOOK_NAME="$2" +readonly STATE_NAME="$3" + +function start_hook() { + # Stops GUI + systemctl isolate multi-user.target + + # Avoids race condition + sleep 2 + + # Unloads the NVIDIA drivers + modprobe -r nvidia_drm + modprobe -r nvidia_uvm + modprobe -r nvidia_modeset + modprobe -r nvidia + + # Other code you might want to run +} + +function revert_hook() { + virsh nodedev-reattach pci_0000_0a_00_0 + virsh nodedev-reattach pci_0000_0a_00_1 + virsh nodedev-reattach pci_0000_06_00_1 + virsh nodedev-reattach pci_0000_06_00_3 + virsh nodedev-reattach pci_0000_0c_00_3 + + modprobe -r vfio-pci + + # Loads the NVIDIA drivers + modprobe nvidia_modeset + modprobe nvidia_uvm + modprobe nvidia_drm + modprobe nvidia + + modprobe -r xhci_pci + modprobe xhci_pci + + # Starts the UI again + systemctl restart display-manager + systemctl isolate graphical.target +} + +# I am not using the script from Passthrough-Post +# because hooks option saves it to /var/lib/libvirt/hooks/qemu.d. +# It's simpler to just rewrite it for NixOS. +if [[ "$GUEST_NAME" != "win11" ]]; then + exit 0 +fi + +if [[ "$HOOK_NAME" == "prepare" && "$STATE_NAME" == "begin" ]]; then + start_hook +elif [[ "$HOOK_NAME" == "release" && "$STATE_NAME" == "end" ]]; then + revert_hook +fi diff --git a/hosts/focalor/vfio.nix b/hosts/focalor/vfio.nix index eb144df..07cac37 100755 --- a/hosts/focalor/vfio.nix +++ b/hosts/focalor/vfio.nix @@ -17,7 +17,45 @@ }).fd]; }; }; + hooks.qemu = { + win11 = ./scripts/vm-win11-hook.sh; + }; + }; + + systemd.services.libvirtd = { + path = let + env = pkgs.buildEnv { + name = "qemu-hook-env"; + paths = with pkgs; [ + bash + libvirt + kmod + systemd + ripgrep + sd + ]; + }; + in + [ env ]; + + /*preStart = + '' + mkdir -p /var/lib/libvirt/hooks + mkdir -p /var/lib/libvirt/hooks/qemu.d/win10/prepare/begin + mkdir -p /var/lib/libvirt/hooks/qemu.d/win10/release/end + mkdir -p /var/lib/libvirt/vgabios + + ln -sf /home/regent/symlinks/qemu /var/lib/libvirt/hooks/qemu + ln -sf /home/regent/symlinks/kvm.conf /var/lib/libvirt/hooks/kvm.conf + ln -sf /home/regent/symlinks/start.sh /var/lib/libvirt/hooks/qemu.d/win11/prepare/begin/start.sh + ln -sf /home/regent/symlinks/stop.sh /var/lib/libvirt/hooks/qemu.d/win11/release/end/stop.sh + + chmod +x /var/lib/libvirt/hooks/qemu + chmod +x /var/lib/libvirt/hooks/kvm.conf + chmod +x /var/lib/libvirt/hooks/qemu.d/win11/prepare/begin/start.sh + chmod +x /var/lib/libvirt/hooks/qemu.d/win11/release/end/stop.sh + '';*/ }; users.extraUsers.regent.extraGroups = [ "libvirtd" ]; -} \ No newline at end of file +}