/ nix / hosts / rig / hardware.nix
hardware.nix
 1  # Hardware configuration for rig.lan
 2  # Based on actual hardware: AMD Ryzen 9 8945HS, 3x RTX 3090 via Thunderbolt PCIe
 3  
 4  { config, lib, pkgs, modulesPath, ... }:
 5  
 6  {
 7    imports = [
 8      (modulesPath + "/installer/scan/not-detected.nix")
 9    ];
10  
11    # ── Kernel ───────────────────────────────────────────────────────────
12    boot.initrd.availableKernelModules = [
13      "nvme" "xhci_pci" "ahci" "usbhid" "sd_mod" "thunderbolt"
14    ];
15    boot.kernelModules = [ "kvm-amd" ];
16  
17    # ── CPU ──────────────────────────────────────────────────────────────
18    hardware.cpu.amd.updateMicrocode = true;
19  
20    # ── Thunderbolt ─────────────────────────────────────────────────────
21    # GPUs 1 & 2 (bus 08:00.0, 68:00.0) are behind Intel JHL6340
22    # Thunderbolt 3 PCIe switches. Without authorization they stay powered
23    # down and invisible to nvidia-smi.
24    services.hardware.bolt.enable = true;
25  
26    # Auto-authorize all Thunderbolt devices on connect (security = none).
27    # Required for headless GPU operation — no user session to approve.
28    # The udev rule fires before nvidia-persistenced starts.
29    services.udev.extraRules = ''
30      ACTION=="add", SUBSYSTEM=="thunderbolt", ATTR{authorized}!="1", ATTR{authorized}="1"
31    '';
32  
33    # After Thunderbolt devices are authorized, rescan PCI so the nvidia
34    # driver binds to the newly-visible GPUs.
35    systemd.services.thunderbolt-pci-rescan = {
36      description = "Rescan PCI bus after Thunderbolt GPU authorization";
37      after = [ "bolt.service" ];
38      wants = [ "bolt.service" ];
39      before = [ "nvidia-persistenced.service" "nvidia-container-toolkit-cdi-generator.service" ];
40      wantedBy = [ "multi-user.target" ];
41      serviceConfig = {
42        Type = "oneshot";
43        RemainAfterExit = true;
44        ExecStartPre = "${pkgs.coreutils}/bin/sleep 3";
45        ExecStart = "${pkgs.bash}/bin/bash -c 'echo 1 > /sys/bus/pci/rescan'";
46      };
47    };
48  
49    # ── Filesystem mounts ────────────────────────────────────────────────
50    # disko handles these — see disk-config.nix
51  }