vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / hardware / cpu / x86-msr.nix
blob95e1be23cd9561cdb9c2695e204a842254576c60
1 { lib
2 , config
3 , options
4 , ...
5 }:
6 let
7   inherit (builtins) hasAttr;
8   inherit (lib) mkIf;
9   cfg = config.hardware.cpu.x86.msr;
10   opt = options.hardware.cpu.x86.msr;
11   defaultGroup = "msr";
12   isDefaultGroup = cfg.group == defaultGroup;
13   set = "to set for devices of the `msr` kernel subsystem.";
15   # Generates `foo=bar` parameters to pass to the kernel.
16   # If `module = baz` is passed, generates `baz.foo=bar`.
17   # Adds double quotes on demand to handle `foo="bar baz"`.
18   kernelParam = { module ? null }: name: value:
19     assert lib.asserts.assertMsg (!lib.strings.hasInfix "=" name) "kernel parameter cannot have '=' in name";
20     let
21       key = (if module == null then "" else module + ".") + name;
22       valueString = lib.generators.mkValueStringDefault {} value;
23       quotedValueString = if lib.strings.hasInfix " " valueString
24         then lib.strings.escape ["\""] valueString
25         else valueString;
26     in "${key}=${quotedValueString}";
27   msrKernelParam = kernelParam { module = "msr"; };
30   options.hardware.cpu.x86.msr = with lib.options; with lib.types; {
31     enable = mkEnableOption "the `msr` (Model-Specific Registers) kernel module and configure `udev` rules for its devices (usually `/dev/cpu/*/msr`)";
32     owner = mkOption {
33       type = str;
34       default = "root";
35       example = "nobody";
36       description = "Owner ${set}";
37     };
38     group = mkOption {
39       type = str;
40       default = defaultGroup;
41       example = "nobody";
42       description = "Group ${set}";
43     };
44     mode = mkOption {
45       type = str;
46       default = "0640";
47       example = "0660";
48       description = "Mode ${set}";
49     };
50     settings = mkOption {
51       type = submodule {
52         freeformType = attrsOf (oneOf [ bool int str ]);
53         options.allow-writes = mkOption {
54           type = nullOr (enum ["on" "off"]);
55           default = null;
56           description = "Whether to allow writes to MSRs (`\"on\"`) or not (`\"off\"`).";
57         };
58       };
59       default = {};
60       description = "Parameters for the `msr` kernel module.";
61     };
62   };
64   config = mkIf cfg.enable {
65     assertions = [
66       {
67         assertion = hasAttr cfg.owner config.users.users;
68         message = "Owner '${cfg.owner}' set in `${opt.owner}` is not configured via `${options.users.users}.\"${cfg.owner}\"`.";
69       }
70       {
71         assertion = isDefaultGroup || (hasAttr cfg.group config.users.groups);
72         message = "Group '${cfg.group}' set in `${opt.group}` is not configured via `${options.users.groups}.\"${cfg.group}\"`.";
73       }
74     ];
76     boot = {
77       kernelModules = [ "msr" ];
78       kernelParams = lib.attrsets.mapAttrsToList msrKernelParam (lib.attrsets.filterAttrs (_: value: value != null) cfg.settings);
79     };
81     users.groups.${cfg.group} = mkIf isDefaultGroup { };
83     services.udev.extraRules = ''
84       SUBSYSTEM=="msr", OWNER="${cfg.owner}", GROUP="${cfg.group}", MODE="${cfg.mode}"
85     '';
86   };
88   meta = with lib; {
89     maintainers = with maintainers; [ lorenzleutgeb ];
90   };