about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorRyan Lahfa <masterancpp@gmail.com>2023-09-25 13:10:42 +0200
committerGitHub <noreply@github.com>2023-09-25 13:10:42 +0200
commit4242ecd871251416179bd8264ea4d8a4dae88da6 (patch)
treea88022f5eac0ba1fc13c00cc251f7d4b1c0eab44 /nixos
parentec9b914767dcd589bc47d8ed73f21e429b95c4e6 (diff)
parentf13bf0c0d4ae69ef5752cfc0489019451f319e01 (diff)
Merge pull request #248372 from yaxitech/amd-sev-guest
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/hardware/cpu/amd-sev.nix89
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--nixos/tests/amd-sev.nix56
3 files changed, 116 insertions, 30 deletions
diff --git a/nixos/modules/hardware/cpu/amd-sev.nix b/nixos/modules/hardware/cpu/amd-sev.nix
index 28ee07f005bab..08e1de496383b 100644
--- a/nixos/modules/hardware/cpu/amd-sev.nix
+++ b/nixos/modules/hardware/cpu/amd-sev.nix
@@ -1,37 +1,43 @@
-{ config, lib, ... }:
+{ config, options, lib, ... }:
 with lib;
 let
-  cfg = config.hardware.cpu.amd.sev;
-  defaultGroup = "sev";
-in
-  with lib; {
-    options.hardware.cpu.amd.sev = {
-      enable = mkEnableOption (lib.mdDoc "access to the AMD SEV device");
-      user = mkOption {
-        description = lib.mdDoc "Owner to assign to the SEV device.";
-        type = types.str;
-        default = "root";
-      };
-      group = mkOption {
-        description = lib.mdDoc "Group to assign to the SEV device.";
-        type = types.str;
-        default = defaultGroup;
-      };
-      mode = mkOption {
-        description = lib.mdDoc "Mode to set for the SEV device.";
-        type = types.str;
-        default = "0660";
-      };
+  cfgSev = config.hardware.cpu.amd.sev;
+  cfgSevGuest = config.hardware.cpu.amd.sevGuest;
+
+  optionsFor = device: group: {
+    enable = mkEnableOption (lib.mdDoc "access to the AMD ${device} device");
+    user = mkOption {
+      description = lib.mdDoc "Owner to assign to the ${device} device.";
+      type = types.str;
+      default = "root";
+    };
+    group = mkOption {
+      description = lib.mdDoc "Group to assign to the ${device} device.";
+      type = types.str;
+      default = group;
     };
+    mode = mkOption {
+      description = lib.mdDoc "Mode to set for the ${device} device.";
+      type = types.str;
+      default = "0660";
+    };
+  };
+in
+with lib; {
+  options.hardware.cpu.amd.sev = optionsFor "SEV" "sev";
+
+  options.hardware.cpu.amd.sevGuest = optionsFor "SEV guest" "sev-guest";
 
-    config = mkIf cfg.enable {
+  config = mkMerge [
+    # /dev/sev
+    (mkIf cfgSev.enable {
       assertions = [
         {
-          assertion = hasAttr cfg.user config.users.users;
+          assertion = hasAttr cfgSev.user config.users.users;
           message = "Given user does not exist";
         }
         {
-          assertion = (cfg.group == defaultGroup) || (hasAttr cfg.group config.users.groups);
+          assertion = (cfgSev.group == options.hardware.cpu.amd.sev.group.default) || (hasAttr cfgSev.group config.users.groups);
           message = "Given group does not exist";
         }
       ];
@@ -40,12 +46,35 @@ in
         options kvm_amd sev=1
       '';
 
-      users.groups = optionalAttrs (cfg.group == defaultGroup) {
-        "${cfg.group}" = {};
+      users.groups = optionalAttrs (cfgSev.group == options.hardware.cpu.amd.sev.group.default) {
+        "${cfgSev.group}" = { };
       };
 
-      services.udev.extraRules = with cfg; ''
+      services.udev.extraRules = with cfgSev; ''
         KERNEL=="sev", OWNER="${user}", GROUP="${group}", MODE="${mode}"
       '';
-    };
-  }
+    })
+
+    # /dev/sev-guest
+    (mkIf cfgSevGuest.enable {
+      assertions = [
+        {
+          assertion = hasAttr cfgSevGuest.user config.users.users;
+          message = "Given user does not exist";
+        }
+        {
+          assertion = (cfgSevGuest.group == options.hardware.cpu.amd.sevGuest.group.default) || (hasAttr cfgSevGuest.group config.users.groups);
+          message = "Given group does not exist";
+        }
+      ];
+
+      users.groups = optionalAttrs (cfgSevGuest.group == options.hardware.cpu.amd.sevGuest.group.default) {
+        "${cfgSevGuest.group}" = { };
+      };
+
+      services.udev.extraRules = with cfgSevGuest; ''
+        KERNEL=="sev-guest", OWNER="${user}", GROUP="${group}", MODE="${mode}"
+      '';
+    })
+  ];
+}
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 11cc12f071ce9..a3e85c337aa27 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -109,6 +109,7 @@ in {
   allTerminfo = handleTest ./all-terminfo.nix {};
   alps = handleTest ./alps.nix {};
   amazon-init-shell = handleTest ./amazon-init-shell.nix {};
+  amd-sev = runTest ./amd-sev.nix;
   anbox = runTest ./anbox.nix;
   anuko-time-tracker = handleTest ./anuko-time-tracker.nix {};
   apcupsd = handleTest ./apcupsd.nix {};
diff --git a/nixos/tests/amd-sev.nix b/nixos/tests/amd-sev.nix
new file mode 100644
index 0000000000000..bf9a50c10d0d2
--- /dev/null
+++ b/nixos/tests/amd-sev.nix
@@ -0,0 +1,56 @@
+{ lib, ... }: {
+  name = "amd-sev";
+  meta = {
+    maintainers = with lib.maintainers; [ trundle veehaitch ];
+  };
+
+  nodes.machine = { lib, ... }: {
+    hardware.cpu.amd.sev.enable = true;
+    hardware.cpu.amd.sevGuest.enable = true;
+
+    specialisation.sevCustomUserGroup.configuration = {
+      users.groups.sevtest = { };
+
+      hardware.cpu.amd.sev = {
+        enable = true;
+        group = "root";
+        mode = "0600";
+      };
+      hardware.cpu.amd.sevGuest = {
+        enable = true;
+        group = "sevtest";
+      };
+    };
+  };
+
+  testScript = { nodes, ... }:
+    let
+      specialisations = "${nodes.machine.system.build.toplevel}/specialisation";
+    in
+    ''
+      machine.wait_for_unit("multi-user.target")
+
+      with subtest("Check default settings"):
+        out = machine.succeed("cat /etc/udev/rules.d/99-local.rules")
+        assert 'KERNEL=="sev", OWNER="root", GROUP="sev", MODE="0660"' in out
+        assert 'KERNEL=="sev-guest", OWNER="root", GROUP="sev-guest", MODE="0660"' in out
+
+        out = machine.succeed("cat /etc/group")
+        assert "sev:" in out
+        assert "sev-guest:" in out
+        assert "sevtest:" not in out
+
+      with subtest("Activate configuration with custom user/group"):
+        machine.succeed('${specialisations}/sevCustomUserGroup/bin/switch-to-configuration test')
+
+      with subtest("Check custom user and group"):
+        out = machine.succeed("cat /etc/udev/rules.d/99-local.rules")
+        assert 'KERNEL=="sev", OWNER="root", GROUP="root", MODE="0600"' in out
+        assert 'KERNEL=="sev-guest", OWNER="root", GROUP="sevtest", MODE="0660"' in out
+
+        out = machine.succeed("cat /etc/group")
+        assert "sev:" not in out
+        assert "sev-guest:" not in out
+        assert "sevtest:" in out
+    '';
+}