1{ config, options, lib, ... }:
2with lib;
3let
4 cfgSev = config.hardware.cpu.amd.sev;
5 cfgSevGuest = config.hardware.cpu.amd.sevGuest;
6
7 optionsFor = device: group: {
8 enable = mkEnableOption "access to the AMD ${device} device";
9 user = mkOption {
10 description = "Owner to assign to the ${device} device.";
11 type = types.str;
12 default = "root";
13 };
14 group = mkOption {
15 description = "Group to assign to the ${device} device.";
16 type = types.str;
17 default = group;
18 };
19 mode = mkOption {
20 description = "Mode to set for the ${device} device.";
21 type = types.str;
22 default = "0660";
23 };
24 };
25in
26with lib; {
27 options.hardware.cpu.amd.sev = optionsFor "SEV" "sev";
28
29 options.hardware.cpu.amd.sevGuest = optionsFor "SEV guest" "sev-guest";
30
31 config = mkMerge [
32 # /dev/sev
33 (mkIf cfgSev.enable {
34 assertions = [
35 {
36 assertion = hasAttr cfgSev.user config.users.users;
37 message = "Given user does not exist";
38 }
39 {
40 assertion = (cfgSev.group == options.hardware.cpu.amd.sev.group.default) || (hasAttr cfgSev.group config.users.groups);
41 message = "Given group does not exist";
42 }
43 ];
44
45 boot.extraModprobeConfig = ''
46 options kvm_amd sev=1
47 '';
48
49 users.groups = optionalAttrs (cfgSev.group == options.hardware.cpu.amd.sev.group.default) {
50 "${cfgSev.group}" = { };
51 };
52
53 services.udev.extraRules = with cfgSev; ''
54 KERNEL=="sev", OWNER="${user}", GROUP="${group}", MODE="${mode}"
55 '';
56 })
57
58 # /dev/sev-guest
59 (mkIf cfgSevGuest.enable {
60 assertions = [
61 {
62 assertion = hasAttr cfgSevGuest.user config.users.users;
63 message = "Given user does not exist";
64 }
65 {
66 assertion = (cfgSevGuest.group == options.hardware.cpu.amd.sevGuest.group.default) || (hasAttr cfgSevGuest.group config.users.groups);
67 message = "Given group does not exist";
68 }
69 ];
70
71 users.groups = optionalAttrs (cfgSevGuest.group == options.hardware.cpu.amd.sevGuest.group.default) {
72 "${cfgSevGuest.group}" = { };
73 };
74
75 services.udev.extraRules = with cfgSevGuest; ''
76 KERNEL=="sev-guest", OWNER="${user}", GROUP="${group}", MODE="${mode}"
77 '';
78 })
79 ];
80}