1
1
Fork 0

vm: add gpu passthrough options

Signed-off-by: Myned <dev@bjork.tech>
This commit is contained in:
Myned 2024-12-06 19:51:19 -06:00
parent 67d2373cec
commit c3a1eb812c
Signed by: myned
GPG key ID: C7224454F7881A34
3 changed files with 90 additions and 17 deletions

View file

@ -9,6 +9,15 @@
width = 3440; width = 3440;
height = 1440; height = 1440;
refresh = 100; refresh = 100;
vm.passthrough = {
enable = true;
driver = "amdgpu";
guest = "myndows";
id = "1002:73df";
init = true;
intel = true;
node = "pci_0000_03_00_0";
};
}; };
boot = { boot = {

View file

@ -9,14 +9,17 @@ with lib; let
audio = config.home-manager.users.${config.custom.username}.home.file.".local/bin/audio".source; audio = config.home-manager.users.${config.custom.username}.home.file.".local/bin/audio".source;
clipse = "${pkgs.clipse}/bin/clipse"; clipse = "${pkgs.clipse}/bin/clipse";
firefox-esr = "${config.home-manager.users.${config.custom.username}.programs.firefox.finalPackage}/bin/firefox-esr"; firefox-esr = "${config.home-manager.users.${config.custom.username}.programs.firefox.finalPackage}/bin/firefox-esr";
grep = "${pkgs.gnugrep}/bin/grep";
left = config.home-manager.users.${config.custom.username}.home.file.".local/bin/left".source; left = config.home-manager.users.${config.custom.username}.home.file.".local/bin/left".source;
loupe = "${pkgs.loupe}/bin/loupe"; loupe = "${pkgs.loupe}/bin/loupe";
modprobe = "${pkgs.kmod}/bin/modprobe";
nautilus = "${pkgs.nautilus}/bin/nautilus"; nautilus = "${pkgs.nautilus}/bin/nautilus";
pkill = "${pkgs.procps}/bin/pkill"; pkill = "${pkgs.procps}/bin/pkill";
rm = "${pkgs.coreutils}/bin/rm"; rm = "${pkgs.coreutils}/bin/rm";
sleep = "${pkgs.coreutils}/bin/sleep"; sleep = "${pkgs.coreutils}/bin/sleep";
sway-audio-idle-inhibit = "${pkgs.sway-audio-idle-inhibit}/bin/sway-audio-idle-inhibit"; sway-audio-idle-inhibit = "${pkgs.sway-audio-idle-inhibit}/bin/sway-audio-idle-inhibit";
systemctl = "${pkgs.systemd}/bin/systemctl"; systemctl = "${pkgs.systemd}/bin/systemctl";
virsh = "${config.virtualisation.libvirtd.package}/bin/virsh";
waybar = "${config.home-manager.users.${config.custom.username}.programs.waybar.package}/bin/waybar"; waybar = "${config.home-manager.users.${config.custom.username}.programs.waybar.package}/bin/waybar";
cfg = config.custom.desktops.hyprland.settings; cfg = config.custom.desktops.hyprland.settings;
@ -66,8 +69,7 @@ in {
# https://wiki.hyprland.org/Configuring/Keywords/#executing # https://wiki.hyprland.org/Configuring/Keywords/#executing
exec-once = exec-once =
optionals config.custom.wallpaper ["wallpaper"] [
++ [
sway-audio-idle-inhibit # Inhibit idle while audio is playing sway-audio-idle-inhibit # Inhibit idle while audio is playing
"${audio} --init" # Enforce audio profile state "${audio} --init" # Enforce audio profile state
"${rm} ~/.cache/walker/clipboard.gob" # Clear clipboard history "${rm} ~/.cache/walker/clipboard.gob" # Clear clipboard history
@ -77,6 +79,13 @@ in {
# HACK: Launch hidden GTK windows to reduce startup time # HACK: Launch hidden GTK windows to reduce startup time
"[workspace special:hidden silent] ${loupe}" "[workspace special:hidden silent] ${loupe}"
"[workspace special:hidden silent] ${nautilus}" "[workspace special:hidden silent] ${nautilus}"
]
++ optionals config.custom.wallpaper [
"wallpaper"
]
# HACK: Delay driver initialization to work around reset issues
++ optionals config.custom.settings.vm.passthrough.init [
"${virsh} list | ${grep} ${config.custom.settings.vm.passthrough.guest} || sudo ${modprobe} ${config.custom.settings.vm.passthrough.driver}"
]; ];
# https://wiki.hyprland.org/Configuring/Variables/#xwayland # https://wiki.hyprland.org/Configuring/Variables/#xwayland

View file

@ -6,12 +6,24 @@
... ...
}: }:
with lib; let with lib; let
virsh = "${config.virtualisation.libvirtd.package}/bin/virsh";
cfg = config.custom.settings.vm; cfg = config.custom.settings.vm;
in { in {
options.custom.settings.vm = { options.custom.settings.vm = {
enable = mkOption {default = false;}; enable = mkOption {default = false;};
libvirt = mkOption {default = true;}; libvirt = mkOption {default = true;};
virtualbox = mkOption {default = false;}; virtualbox = mkOption {default = false;};
passthrough = {
enable = mkOption {default = false;};
driver = mkOption {default = null;}; #?? lspci -k
guest = mkOption {default = null;}; #?? virsh list --all
id = mkOption {default = null;}; #?? lspci -nn
init = mkOption {default = false;};
intel = mkOption {default = false;};
node = mkOption {default = null;}; #?? virsh nodedev-list
};
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
@ -23,12 +35,37 @@ in {
onBoot = "ignore"; onBoot = "ignore";
onShutdown = "shutdown"; onShutdown = "shutdown";
# https://libvirt.org/hooks.html
hooks.qemu = {
# Attach/detach GPU for passthrough
passthrough = mkIf cfg.passthrough.enable (pkgs.writeShellScript "passthrough" ''
if [[ "$1" == "${cfg.passthrough.guest}" ]]; then
case "$2" in
prepare)
${virsh} nodedev-detach ${cfg.passthrough.node}
;;
release)
${virsh} nodedev-reattach ${cfg.passthrough.node}
;;
*)
exit
;;
esac
fi
'');
};
qemu = { qemu = {
swtpm.enable = true; # TPM emulation swtpm.enable = true; # TPM emulation
# BUG: Windows requires global mountpoint for some applications (\\.\*: instead of *:)
# https://github.com/virtio-win/kvm-guest-drivers-windows/issues/950
# https://virtio-win.github.io/Knowledge-Base/Virtiofs:-Shared-file-system
#// vhostUserPackages = with pkgs; [virtiofsd]; # virtiofs support
# Build OVMF with Windows 11 support # Build OVMF with Windows 11 support
ovmf.packages = [ ovmf.packages = with pkgs; [
(pkgs.OVMF.override { (OVMF.override {
secureBoot = true; secureBoot = true;
tpmSupport = true; tpmSupport = true;
}) })
@ -77,24 +114,42 @@ in {
++ lib.optionals cfg.virtualbox ["vboxusers"]; ++ lib.optionals cfg.virtualbox ["vboxusers"];
systemd = mkIf cfg.libvirt { systemd = mkIf cfg.libvirt {
services = {
# Fix resume messages polluting tty # Fix resume messages polluting tty
services.libvirt-guests.serviceConfig.StandardOutput = "journal"; libvirt-guests.serviceConfig = {
StandardOutput = "journal";
};
};
tmpfiles.settings."10-vm" = {
# HACK: Manually link image to default directory
"/var/lib/libvirt/images/virtio-win.iso" = {
"L+" = {
argument = "${inputs.virtio-win}";
};
};
tmpfiles.rules = let
firmware = pkgs.runCommandLocal "qemu-firmware" {} ''
mkdir $out
cp ${pkgs.qemu}/share/qemu/firmware/*.json $out
substituteInPlace $out/*.json --replace ${pkgs.qemu} /run/current-system/sw
'';
in [
# HACK: Fix libvirt not automatically locating firmware # HACK: Fix libvirt not automatically locating firmware
# https://github.com/NixOS/nixpkgs/issues/115996#issuecomment-2224296279 # https://github.com/NixOS/nixpkgs/issues/115996#issuecomment-2224296279
# https://libvirt.org/formatdomain.html#bios-bootloader # https://libvirt.org/formatdomain.html#bios-bootloader
"L+ /var/lib/qemu/firmware - - - - ${firmware}" "/var/lib/qemu/firmware" = {
"L+" = {
argument = "${pkgs.runCommandLocal "qemu-firmware" {} ''
mkdir $out
cp ${pkgs.qemu}/share/qemu/firmware/*.json $out
substituteInPlace $out/*.json --replace ${pkgs.qemu} /run/current-system/sw
''}";
};
};
};
};
# HACK: Manually link image to default directory boot = mkIf cfg.passthrough.enable {
"L+ /var/lib/libvirt/images/virtio-win.iso - - - - ${inputs.virtio-win}" # https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#Isolating_the_GPU
]; blacklistedKernelModules = mkIf cfg.passthrough.init [cfg.passthrough.driver];
# https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#Enabling_IOMMU
kernelParams = mkIf cfg.passthrough.intel ["intel_iommu=on"];
}; };
}; };
} }