{ config, lib, pkgs, ... }: let cfg = config.ptw.virtualisation.gaming; in { options.ptw.virtualisation.gaming = { enable = lib.mkEnableOption "Configure virtualisation for gaming purposes"; }; config = lib.mkIf cfg.enable { environment.etc = { "evdev-proxy/config.toml".source = pkgs.writeText "config.toml" '' log_level = "INFO" [[device]] [device.Simple] name = "EvdevProxyMouse" vendor = 0x1337 model = 0x1337 class = "Mouse" [[device.Simple.selector]] USBIDClass = {vendor=0x046d, model=0xc531, class="Mouse"} [[device.Simple.selector]] USBIDClass = {vendor=0x046d, model=0xc07c, class="Mouse"} [[device]] [device.Simple] name = "EvdevProxyKeyboard" vendor = 0x1337 model = 0x1338 class = "Keyboard" # This is to give a deterministic /dev/input/by-id/ path to # the mapped version of the Tartarus evdev node. # (Useful for qemu) [[device.Simple.selector]] EVDEVClass = {phys="\"input-remapper\""} [[device.Simple.selector]] USBIDClass = {vendor=0x1532, model=0x011a, class="Keyboard"} ''; # "libvirt/hooks/qemu".source = let # vfio-isolate-state = "/tmp/vfio-isolate-state"; # in pkgs.writeScript "qemu" '' # #!${pkgs.stdenv.shell} # guest=$1 # action=$2 # phase=$3 # extra=$4 # echo "called with $1 $2 $3 $4" > /dev/stderr # if [[ "$guest" = "win10-gaming" ]]; then # case "$action" in # prepare) # # Only do this while in preparation # [[ ! "$phase" = "prepare" ]] && exit 0 # GUEST_CORES="C1-3,5-7" # ${pkgs.vfio-isolate}/bin/vfio-isolate \ # -u ${vfio-isolate-state} \ # cpu-governor performance "$GUEST_CORES" \ # cpuset-create --cpus "$GUEST_CORES" /guest.slice \ # cpuset-create --cpus C0,4 /host.slice \ # move-tasks / /host.slice \ # irq-affinity mask "$GUEST_CORES" # ;; # stopped) # # Only run when the VM is fully stopped # [[ ! "$phase" = "end" ]] && exit 0 # ${pkgs.vfio-isolate}/bin/vfio-isolate \ # restore ${vfio-isolate-state} # esac # fi # ''; }; # NOTE: Workaround for libvirt's SYSCONFDIR being set to /var/lib # (See https://github.com/NixOS/nixpkgs/issues/51152#issuecomment-899374407) system.activationScripts.libvirt-hooks.text = '' ln -Tfs /etc/libvirt/hooks /var/lib/libvirt/hooks ''; services.udev.packages = with pkgs; [ evdev-proxy ]; systemd = { services = { libvirtd.path = with pkgs; [ /*vfio-isolate*/ systemd bash ]; }; user.services.evdev-proxy = { description = "Creates virtual device to proxy evdev devices events"; wantedBy = [ "default.target" ]; serviceConfig = { Type = "simple"; ExecStart = "${pkgs.evdev-proxy}/bin/evdev-proxy"; Restart = "always"; }; }; }; }; }