# Pastebin 71Rhty9A { lib, config, pkgs, ... }: let gtx1050ti-rom' = builtins.fetchurl { url = "https://www.techpowerup.com/vgabios/194754/EVGA.GTX1050Ti.4096.170714.rom"; sha256 = "1qhhn3zvaghlynmh4iy0pdv4vgc447cn870m3q1vmpgr5xgf1lzp"; }; nvidia_vbios_vfio_patcher = builtins.fetchurl { url = https://raw.githubusercontent.com/Matoking/NVIDIA-vBIOS-VFIO-Patcher/2cbf953f4e61e766201a62bfc542cb6b23d336b8/nvidia_vbios_vfio_patcher.py; sha256 = "1wk1xpvzvr67kz8xgmlw37hs90dzv1crjsm6j244pdc0qw4qd9hx"; }; gtx1050ti-rom = pkgs.runCommand "gtx1050ti-rom" { nativeBuildInputs = [pkgs.python]; } '' echo "I agree to be careful" | python ${nvidia_vbios_vfio_patcher} -i ${gtx1050ti-rom'} -o $out ''; devices = [ { device = "10de 1c82"; slot = "42:00.0"; driver = "nvidia"; romfile = gtx1050ti-rom; } # GPU { device = "10de 0fb9"; slot = "42:00.1"; driver = "snd_hda_intel"; } # GPU audio controller ]; usbDevices = [ { vendorid = "0x05ac"; productid = "0x024f"; } # Keyboard { vendorid = "0x062a"; productid = "0x4102"; } # Mouse { vendorid = "0x046d"; productid = "0x0825"; } # webcam { vendorid = "0x0c76"; productid = "0x161b"; } # mic ]; qemuDevices = let f = { slot, romfile ? null, ... }: "-device " + lib.concatStringsSep "," ( [ "vfio-pci" "host=${slot}" ] ++ lib.optional (romfile != null) "romfile=${romfile}" ); pciArgs = lib.concatMapStringsSep " " f devices; usbArgs = lib.concatMapStringsSep " " ({ vendorid, productid }: "-usb -device usb-host,vendorid=${vendorid},productid=${productid}") usbDevices; in pciArgs + " " + usbArgs; efivars = "/var/lib/mentor-guest/efivars"; disk = "pyromancer/mentor/disk"; inherit (pkgs) OVMF qemu; cores = 8; threads = 1; sockets = 1; in { boot.kernelModules = ["vfio-pci"]; boot.kernelParams = [ "amd_iommu=on" "amd_iommu=pt" "iommu=pt" "kvm.ignore_msrs=1" "kvm.report_ignored_msrs=0" ]; systemd.services.mentor-guest = { restartIfChanged = false; unitConfig.Conflicts = "display-manager.service"; serviceConfig.Type = "simple"; after = ["display-manager.service"]; preStart = '' set +e set -xuo pipefail echo 0 > /sys/class/vtconsole/vtcon0/bind echo 0 > /sys/class/vtconsole/vtcon1/bind echo efi-framebuffer.0 > /sys/bus/platform/drivers/efi-framebuffer/unbind ${lib.concatMapStringsSep "\n" ({ slot, driver, ... }: '' echo -n "0000:${slot}" > /sys/bus/pci/drivers/${driver}/unbind '') devices} ${lib.concatMapStringsSep "\n" ({ device, ... }: '' echo -n "${device}" > /sys/bus/pci/drivers/vfio-pci/new_id '') devices} /run/booted-system/sw/bin/zfs destroy ${disk}@pre-boot /run/booted-system/sw/bin/zfs snapshot ${disk}@pre-boot if ! [ -f "${efivars}" ]; then mkdir -p $(dirname ${efivars}) cp --no-preserve=all ${OVMF.fd}/FV/OVMF_VARS.fd "${efivars}" fi ''; serviceConfig.ExecStart = '' ${qemu}/bin/qemu-system-x86_64 \ -cpu host,kvm=off,hv_time,hv_relaxed,hv_vapic,hv_spinlocks=0x1fff,hv_vendor_id=Nvidia43FIX \ -smp cpus=${toString (cores * threads * sockets)},cores=${toString cores},threads=${toString threads},sockets=${toString sockets} \ -enable-kvm \ -m 16G \ -nodefaults \ -nic user \ -drive if=pflash,format=raw,readonly,file=${OVMF.fd}/FV/OVMF_CODE.fd \ -drive if=pflash,format=raw,file="${efivars}" \ -smbios type=2 \ -vga none \ -nographic \ -serial none \ -monitor telnet:127.0.0.1:55555,server,nowait \ -device nec-usb-xhci \ ${qemuDevices} \ -device ich9-intel-hda -device hda-duplex \ -device ide-drive,bus=ide.1,drive=mentor_disk \ -drive id=mentor_disk,cache=unsafe,if=none,file="/dev/zvol/${disk}",format=raw,discard=unmap,detect-zeroes=unmap ''; serviceConfig.ExecStop = "${pkgs.bash}/bin/bash -c 'echo systemd_powerdown | telnet 127.0.0.1 55555; while echo | telnet 127.0.0.1 55555; do sleep 1; done'"; postStop = '' set +e set -xuo pipefail /run/booted-system/sw/bin/zfs destroy ${disk}@post-shutdown /run/booted-system/sw/bin/zfs snapshot ${disk}@post-shutdown ${lib.concatMapStringsSep "\n" ({ slot, driver, ... }: '' echo -n "0000:${slot}" > /sys/bus/pci/drivers/vfio-pci/unbind '') devices} ${lib.concatMapStringsSep "\n" ({ device, ... }: '' echo -n "${device}" > /sys/bus/pci/drivers/vfio-pci/remove_id '') devices} ${lib.concatMapStringsSep "\n" ({ slot, driver, ... }: '' echo -n "0000:${slot}" > /sys/bus/pci/drivers/${driver}/bind '') devices} echo 1 > /sys/class/vtconsole/vtcon0/bind echo 1 > /sys/class/vtconsole/vtcon1/bind echo efi-framebuffer.0 > /sys/bus/platform/drivers/efi-framebuffer/bind ${config.systemd.package}/bin/systemctl start display-manager.service --no-block ''; }; }