vm: add gpu passthrough options
Signed-off-by: Myned <dev@bjork.tech>
This commit is contained in:
parent
67d2373cec
commit
c3a1eb812c
3 changed files with 90 additions and 17 deletions
|
@ -9,6 +9,15 @@
|
|||
width = 3440;
|
||||
height = 1440;
|
||||
refresh = 100;
|
||||
vm.passthrough = {
|
||||
enable = true;
|
||||
driver = "amdgpu";
|
||||
guest = "myndows";
|
||||
id = "1002:73df";
|
||||
init = true;
|
||||
intel = true;
|
||||
node = "pci_0000_03_00_0";
|
||||
};
|
||||
};
|
||||
|
||||
boot = {
|
||||
|
|
|
@ -9,14 +9,17 @@ with lib; let
|
|||
audio = config.home-manager.users.${config.custom.username}.home.file.".local/bin/audio".source;
|
||||
clipse = "${pkgs.clipse}/bin/clipse";
|
||||
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;
|
||||
loupe = "${pkgs.loupe}/bin/loupe";
|
||||
modprobe = "${pkgs.kmod}/bin/modprobe";
|
||||
nautilus = "${pkgs.nautilus}/bin/nautilus";
|
||||
pkill = "${pkgs.procps}/bin/pkill";
|
||||
rm = "${pkgs.coreutils}/bin/rm";
|
||||
sleep = "${pkgs.coreutils}/bin/sleep";
|
||||
sway-audio-idle-inhibit = "${pkgs.sway-audio-idle-inhibit}/bin/sway-audio-idle-inhibit";
|
||||
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";
|
||||
|
||||
cfg = config.custom.desktops.hyprland.settings;
|
||||
|
@ -66,8 +69,7 @@ in {
|
|||
|
||||
# https://wiki.hyprland.org/Configuring/Keywords/#executing
|
||||
exec-once =
|
||||
optionals config.custom.wallpaper ["wallpaper"]
|
||||
++ [
|
||||
[
|
||||
sway-audio-idle-inhibit # Inhibit idle while audio is playing
|
||||
"${audio} --init" # Enforce audio profile state
|
||||
"${rm} ~/.cache/walker/clipboard.gob" # Clear clipboard history
|
||||
|
@ -77,6 +79,13 @@ in {
|
|||
# HACK: Launch hidden GTK windows to reduce startup time
|
||||
"[workspace special:hidden silent] ${loupe}"
|
||||
"[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
|
||||
|
|
|
@ -6,12 +6,24 @@
|
|||
...
|
||||
}:
|
||||
with lib; let
|
||||
virsh = "${config.virtualisation.libvirtd.package}/bin/virsh";
|
||||
|
||||
cfg = config.custom.settings.vm;
|
||||
in {
|
||||
options.custom.settings.vm = {
|
||||
enable = mkOption {default = false;};
|
||||
libvirt = mkOption {default = true;};
|
||||
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 {
|
||||
|
@ -23,12 +35,37 @@ in {
|
|||
onBoot = "ignore";
|
||||
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 = {
|
||||
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
|
||||
ovmf.packages = [
|
||||
(pkgs.OVMF.override {
|
||||
ovmf.packages = with pkgs; [
|
||||
(OVMF.override {
|
||||
secureBoot = true;
|
||||
tpmSupport = true;
|
||||
})
|
||||
|
@ -77,24 +114,42 @@ in {
|
|||
++ lib.optionals cfg.virtualbox ["vboxusers"];
|
||||
|
||||
systemd = mkIf cfg.libvirt {
|
||||
services = {
|
||||
# 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
|
||||
# https://github.com/NixOS/nixpkgs/issues/115996#issuecomment-2224296279
|
||||
# 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
|
||||
"L+ /var/lib/libvirt/images/virtio-win.iso - - - - ${inputs.virtio-win}"
|
||||
];
|
||||
boot = mkIf cfg.passthrough.enable {
|
||||
# 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"];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue