dotfiles
My PC Dotfiles & Websitegit clone https://github.com/maydayv7/dotfiles
commit 8f340eb7ea31945b702ac0534773d2aad9550fd0 parent 74fd36ebbea16b40a06597435a84fb594b88ff90 Author: maydayv7 <maydayv7@gmail.com> Date: Sun, 4 Oct 2026 16:30:17 +0530 fix: Windows VM
Diffstat:
| M | flake.lock | | | 20 | ++++++++++---------- |
| M | flake.nix | | | 2 | +- |
| M | modules/apps/codex.nix | | | 2 | +- |
| M | modules/desktop/_wm/files.nix | | | 12 | +++++++++++- |
| M | modules/desktop/hyprland/_features/shell.nix | | | 21 | +++++++++++++-------- |
| M | modules/hosts/valkyrie/_asus/default.nix | | | 8 | +++++--- |
| M | modules/hosts/valkyrie/_vm/default.nix | | | 53 | ++++++++++++++++++++++++++++++++++++++++++++++------- |
| M | modules/hosts/valkyrie/_vm/windows.xml | | | 8 | ++++++-- |
| M | modules/hosts/valkyrie/default.nix | | | 26 | ++++++++++++++------------ |
| M | modules/shell/shell.nix | | | 1 | + |
| M | site/content/blog/nixos/win11vm.md | | | 27 | +++++++++++++++++++++++---- |
11 files changed, 131 insertions(+), 49 deletions(-)
diff --git a/flake.lock b/flake.lock @@ -274,11 +274,11 @@ ] }, "locked": { - "lastModified": 1788450739, - "narHash": "sha256-glZLQlzIn1fXH6PazR2iUmTo7kzzyYSshrWhLS9TqCU=", + "lastModified": 1790898470, + "narHash": "sha256-zTwuwezD0w3hpga6a6P8emidzAZFyWqlNeRBlpWOOl8=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "31729ca8cbdb4fa927b34e5f4353e6a83f39e993", + "rev": "024633cd702b10285db5cb19b40ad48d2399ba60", "type": "github" }, "original": { @@ -487,11 +487,11 @@ "treefmt-nix": "treefmt-nix" }, "locked": { - "lastModified": 1790814856, - "narHash": "sha256-MLYoDU/GvvNFS5NmG5FqG2YG88Dc7ESDNix+qnE4JdE=", + "lastModified": 1791001326, + "narHash": "sha256-pwJhtpRcNX1pJ9luUy3Eh1EYUFsZjv5m2xSqZ1hEhMU=", "owner": "numtide", "repo": "llm-agents.nix", - "rev": "5ee7c2b107f6b218b764e907ed49070170895108", + "rev": "83984ebbbe5322b261d9fdc24eb15cf44f23abec", "type": "github" }, "original": { @@ -748,16 +748,16 @@ ] }, "locked": { - "lastModified": 1790517835, - "narHash": "sha256-RfRxWi9PfJVSyoLrLj5mQ5vo24FjkgfBIi+UmE96zZo=", + "lastModified": 1790905070, + "narHash": "sha256-ukT5U54WQSpq6sktl5QJOZ8S4ZF3LLmP8CAFel1XJf0=", "owner": "noctalia-dev", "repo": "noctalia", - "rev": "ec704377180fc4ffe79322a14a6ae87e9f922cae", + "rev": "6ef43e2bf2f3d5b4205ec72a72e34a2ab76ce3b4", "type": "github" }, "original": { "owner": "noctalia-dev", - "ref": "v5.2.0", + "ref": "v5.2.1", "repo": "noctalia", "type": "github" } diff --git a/flake.nix b/flake.nix @@ -196,7 +196,7 @@ # Desktop Shell noctalia = { - url = "github:noctalia-dev/noctalia/v5.2.0"; + url = "github:noctalia-dev/noctalia/v5.2.1"; inputs.nixpkgs.follows = "nixpkgs"; }; diff --git a/modules/apps/codex.nix b/modules/apps/codex.nix @@ -10,7 +10,7 @@ _: { programs.vscode.profiles.default.extensions = lib.mkIf config.programs.vscode.enable - [pkgs.vscode-marketplace.openai.chatgpt]; + (with pkgs.vscode-marketplace.openai; [chatgpt codex-audio]); home = { packages = [pkgs.llm.chatgpt]; diff --git a/modules/desktop/_wm/files.nix b/modules/desktop/_wm/files.nix @@ -12,7 +12,14 @@ cinnamon-desktop bulky file-roller - lxqt.pcmanfm-qt + (lxqt.pcmanfm-qt.overrideAttrs (old: { + postPatch = + (old.postPatch or "") + + '' + substituteInPlace pcmanfm/application.cpp \ + --replace-fail 'dbus.interface()->registerService(fileManagerService, QDBusConnectionInterface::QueueService);' "" + ''; + })) ]; }; @@ -30,6 +37,9 @@ directory = ["nemo.desktop"]; }; + # Prefer Nemo + xdg.dataFile."dbus-1/services/org.freedesktop.FileManager1.service".source = "${pkgs.nemo-with-extensions}/share/dbus-1/services/nemo.FileManager1.service"; + # Settings dconf.settings = { "org/gtk/gtk4/settings/file-chooser".sort-directories-first = true; diff --git a/modules/desktop/hyprland/_features/shell.nix b/modules/desktop/hyprland/_features/shell.nix @@ -26,14 +26,19 @@ _: { ]; }; - # Minimize Button - widget.minimize = { - type = "custom_button"; - glyph = "arrow-bar-to-down"; - tooltip = "Minimize window"; - actions = { - right = "exec hyprutils toggle minimized"; - left = ''exec hyprctl dispatch 'hl.dsp.window.move({ workspace = "special:minimized", follow = false })' ''; + widget = { + # Game Mode + battery.actions.right = "exec hyprutils gamemode"; + + # Minimize Button + minimize = { + type = "custom_button"; + glyph = "arrow-bar-to-down"; + tooltip = "Minimize window"; + actions = { + right = "exec hyprutils toggle minimized"; + left = ''exec hyprctl dispatch 'hl.dsp.window.move({ workspace = "special:minimized", follow = false })' ''; + }; }; }; diff --git a/modules/hosts/valkyrie/_asus/default.nix b/modules/hosts/valkyrie/_asus/default.nix @@ -3,19 +3,21 @@ _: { config, lib, ... - }: { + }: let + perf = config.hardware.cpu.mode == "performance"; + in { boot = { plymouth.extraConfig = "DeviceScale=2"; # ! # https://gitlab.freedesktop.org/drm/amd/-/issues/3388 - kernelParams = lib.mkIf (config.hardware.cpu.mode == "performance") [ + kernelParams = lib.mkIf perf [ "amdgpu.dcdebugmask=0x10" "usbcore.autosuspend=-1" ]; }; environment.sessionVariables.AQ_DRM_DEVICES = - lib.mkIf (config.hardware.cpu.mode == "performance") + lib.mkIf (config.hardware.gpu.enable && perf) "/dev/dri/nvidia-dgpu:/dev/dri/integrated-gpu"; services = { diff --git a/modules/hosts/valkyrie/_vm/default.nix b/modules/hosts/valkyrie/_vm/default.nix @@ -4,8 +4,46 @@ config, inputs, ... -}: { - nixos = {pkgs, ...}: { +}: let + files = config.flake.files.path.files; +in { + nixos = { + config, + pkgs, + ... + }: let + vfio = !config.virt.vfio.setup; + template = pkgs.writeText "windows-template.xml" ( + builtins.replaceStrings ["@files"] [files] + (builtins.readFile ./windows.xml) + ); + + conf-vfio = + pkgs.runCommand "windows.xml" { + nativeBuildInputs = [pkgs.xmlstarlet]; + } '' + xmlstarlet ed \ + -u '/domain/os/loader' -x 'normalize-space(.)' \ + -u '/domain/os/nvram' -x 'normalize-space(.)' \ + ${template} > "$out" + ''; + + conf-desktop = + pkgs.runCommand "windows-desktop.xml" { + nativeBuildInputs = [pkgs.xmlstarlet]; + } '' + xmlstarlet ed -N qemu='http://libvirt.org/schemas/domain/qemu/1.0' \ + -d '/domain/memoryBacking/hugepages' \ + -s '/domain/memoryBacking' -t elem -n source -v "" \ + -i '/domain/memoryBacking/source' -t attr -n type -v memfd \ + -d '/domain/cputune' \ + -d "/domain/devices/hostdev[@type='pci']" \ + -s "/domain/devices/graphics[@type='spice']" -t elem -n mouse -v "" \ + -i "/domain/devices/graphics[@type='spice']/mouse" -t attr -n mode -v server \ + -d '/domain/qemu:commandline' \ + ${conf-vfio} > "$out" + ''; + in { imports = [inputs.nixvirt.nixosModules.default]; disko.devices.zpool.fspool.datasets = { @@ -18,7 +56,7 @@ }; "vm/windows" = { type = "zfs_volume"; - size = "128G"; + size = "256G"; options = { volblocksize = "16k"; refreservation = "none"; @@ -39,11 +77,12 @@ domains = [ { - definition = pkgs.writeText "windows.xml" ( - builtins.replaceStrings ["@files"] [config.flake.files.path.files] - (builtins.readFile ./windows.xml) - ); + definition = + if vfio + then conf-vfio + else conf-desktop; active = null; + restart = false; } ]; }; diff --git a/modules/hosts/valkyrie/_vm/windows.xml b/modules/hosts/valkyrie/_vm/windows.xml @@ -56,7 +56,7 @@ <vmport state='off' /> <smm state='on' /> </features> - <cpu mode='host-passthrough' check='none' migratable='on'> + <cpu mode='host-passthrough' check='none' migratable='off'> <topology sockets='1' dies='1' clusters='1' cores='3' threads='2' /> <cache mode='passthrough' /> <feature policy='require' name='topoext' /> @@ -239,7 +239,7 @@ <address type='pci' domain='0x0000' bus='0x07' slot='0x00' function='0x0' /> </hostdev> <hostdev mode='subsystem' type='usb' managed='yes'> - <source> <!-- Webcam --> + <source startupPolicy='optional'> <!-- Webcam --> <vendor id='0x3277' /> <product id='0x0018' /> </source> @@ -252,6 +252,10 @@ </redirdev> <watchdog model='itco' action='reset' /> <memballoon model='none' /> + <rng model='virtio'> + <backend model='random'>/dev/urandom</backend> + <address type='pci' domain='0x0000' bus='0x08' slot='0x00' function='0x0' /> + </rng> </devices> <qemu:commandline> <qemu:arg value='-device' /> diff --git a/modules/hosts/valkyrie/default.nix b/modules/hosts/valkyrie/default.nix @@ -14,7 +14,7 @@ "docker" "mc-server" #"roblox" - #"vfio" + "vfio" ]; hmModules = [ @@ -29,6 +29,7 @@ "vscode" "zed" "codex" + "antigravity" "stream" "minecraft" "osu" @@ -47,7 +48,7 @@ "latex" #"flatpak" #"wine" - #"libvirt" + "libvirt" "hyprland" ]; @@ -58,7 +59,7 @@ disk = import ./_disk/full.nix args; asus = import ./_asus {}; dev = import ./_dev.nix {}; - #vm = import ./_vm args; + vm = import ./_vm args; in { configurations.nixos.valkyrie = { system = "x86_64-linux"; @@ -74,6 +75,7 @@ in { disk.nixos (asus.nixos or {}) (dev.nixos or {}) + vm.nixos ] ++ util.map.array ["asus-zephyrus-ga402x-nvidia"] inputs.hardware.nixosModules; @@ -144,15 +146,15 @@ in { ]; # Virtualisation - # virt.vfio = { - # setup = true; - # passthrough = [ - # "10de:28e0" # Graphics - # "10de:22be" # Audio - # ]; - # isolate = "2-4,10-12"; - # hugepages = 16; - # }; + virt.vfio = { + setup = true; + passthrough = [ + "10de:28e0" # Graphics + "10de:22be" # Audio + ]; + isolate = "2-4,10-12"; + hugepages = 16; + }; # User V7 users.users.v7 = { diff --git a/modules/shell/shell.nix b/modules/shell/shell.nix @@ -98,6 +98,7 @@ in { bindkey '^[[D' backward-char bindkey '^[[F' end-of-linegestures bindkey '^[[H' beginning-of-line + bindkey '^H' backward-kill-word bindkey '^J' backward-kill-line ''; diff --git a/site/content/blog/nixos/win11vm.md b/site/content/blog/nixos/win11vm.md @@ -2,6 +2,7 @@ title = "Windows VM" description = "A declarative, performant Windows 11 VM with dGPU passthrough and Looking Glass" date = 2026-06-27 +updated = 2026-10-04 [taxonomies] series = ["NixOS Desktop"] @@ -111,11 +112,11 @@ $ sudo zfs create -s -V 120G -o volblocksize=16k <pool>/vm/windows # appears as /dev/zvol/<pool>/vm/windows ``` -Now create a standard Windows 11 guest (`virt-manager` makes this easy, you may refer to [**this guide**](https://sysguides.com/install-a-windows-11-virtual-machine-on-kvm)). The settings that matter: +Now create a standard Windows 11 guest (`virt-manager` makes this easy, you may refer to [**this guide**](https://sysguides.com/install-windows-11-on-kvm)). The settings that matter: - **Q35** chipset + **UEFI/OVMF** with **Secure Boot**, and **TPM 2.0** (`swtpm`) - Windows 11 requires the latter two. - **`host-passthrough`** CPU. -- **virtio everywhere** - disk (on the zvol above) with `cache=none`, `io=native`, `discard=unmap`; virtio NIC (for performance). +- **virtio everywhere** - disk (on the zvol above) with `cache=none`, `io=native`, `discard=unmap` + virtio NIC (for performance). - **Hyper-V enlightenments** so Windows uses its kernel fast paths. - A **QEMU guest agent** channel. @@ -152,6 +153,23 @@ services.udev.extraRules = '' environment.systemPackages = [ pkgs.looking-glass-client ]; ``` +With `runAsRoot = false`, QEMU runs as `qemu-libvirtd`, so it also needs membership in the `kvm` group. +Because the device is passed through a custom QEMU command line, libvirt also needs explicit device-access settings: + +```nix +users.users.qemu-libvirtd.extraGroups = [ "kvm" ]; +virtualisation.libvirtd.qemu.verbatimConfig = '' + namespaces = [] + cgroup_device_acl = [ + "/dev/null", "/dev/full", "/dev/zero", + "/dev/random", "/dev/urandom", + "/dev/ptmx", "/dev/kvm", + "/dev/userfaultfd", + "/dev/kvmfr0" + ] +''; +``` + Give the VM the matching `ivshmem` device via a `<qemu:commandline>` block that points `mem-path` at `/dev/kvmfr0` (this needs `xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'` on the root `<domain>` tag): ```xml @@ -166,7 +184,7 @@ Give the VM the matching `ivshmem` device via a `<qemu:commandline>` block that Inside Windows, install the following: 1. **NVIDIA driver** - Automatic via Windows Update. -2. **A virtual display driver** ([MikeTheTech's VDD](https://github.com/VirtualDrivers/Virtual-Display-Driver)) - gives the desktop a head to render on. Its config (`C:\VirtualDisplayDriver\vdd_settings.xml`) can pin the virtual display to a specific GPU and define exact modes, so bind it to the passed-through GPU at your native resolution: +2. **A virtual display driver** ([MikeTheTech's VDD](https://github.com/VirtualDrivers/Virtual-Display-Driver)) - gives the desktop a head to render on. Its config (`C:\VirtualDisplayDriver\vdd_settings.xml`) can pin the virtual display to a specific GPU and define exact modes, so bind it to the passed-through GPU at your native resolution: ```xml <vdd_settings> @@ -270,13 +288,14 @@ Run the host CPU governor at `performance` (`powerManagement.cpuFreqGovernor = " { definition = ./windows.xml; active = null; + restart = false; } ]; }; } ``` -`active = null` is important: NixVirt redefines the domain on every rebuild but never starts, stops or destroys a running guest. +`active = null` and `restart = false` is important: NixVirt redefines the domain on every rebuild but never starts, stops or destroys a running guest. If you use **impermanence** (an erase-on-boot root), the domain definition is now regenerated from Nix, so you only need to persist the actual state. Two directories matter: