vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / services / hardware / undervolt.nix
blob1fce225db3669f9981f8dd21494d90b343b2e2ac
1 { config, pkgs, lib, ... }:
2 let
3   cfg = config.services.undervolt;
5   mkPLimit = limit: window:
6     if (limit == null && window == null) then null
7     else assert lib.asserts.assertMsg (limit != null && window != null) "Both power limit and window must be set";
8       "${toString limit} ${toString window}";
9   cliArgs = lib.cli.toGNUCommandLine {} {
10     inherit (cfg)
11       verbose
12       temp
13       turbo
14       ;
15     # `core` and `cache` are both intentionally set to `cfg.coreOffset` as according to the undervolt docs:
16     #
17     #     Core or Cache offsets have no effect. It is not possible to set different offsets for
18     #     CPU Core and Cache. The CPU will take the smaller of the two offsets, and apply that to
19     #     both CPU and Cache. A warning message will be displayed if you attempt to set different offsets.
20     core = cfg.coreOffset;
21     cache = cfg.coreOffset;
22     gpu = cfg.gpuOffset;
23     uncore = cfg.uncoreOffset;
24     analogio = cfg.analogioOffset;
26     temp-bat = cfg.tempBat;
27     temp-ac = cfg.tempAc;
29     power-limit-long = mkPLimit cfg.p1.limit cfg.p1.window;
30     power-limit-short = mkPLimit cfg.p2.limit cfg.p2.window;
31   };
34   options.services.undervolt = {
35     enable = lib.mkEnableOption ''
36        Undervolting service for Intel CPUs.
38        Warning: This service is not endorsed by Intel and may permanently damage your hardware. Use at your own risk
39     '';
41     verbose = lib.mkOption {
42       type = lib.types.bool;
43       default = false;
44       description = ''
45         Whether to enable verbose logging.
46       '';
47     };
49     package = lib.mkPackageOption pkgs "undervolt" { };
51     coreOffset = lib.mkOption {
52       type = lib.types.nullOr lib.types.int;
53       default = null;
54       description = ''
55         The amount of voltage in mV to offset the CPU cores by.
56       '';
57     };
59     gpuOffset = lib.mkOption {
60       type = lib.types.nullOr lib.types.int;
61       default = null;
62       description = ''
63         The amount of voltage in mV to offset the GPU by.
64       '';
65     };
67     uncoreOffset = lib.mkOption {
68       type = lib.types.nullOr lib.types.int;
69       default = null;
70       description = ''
71         The amount of voltage in mV to offset uncore by.
72       '';
73     };
75     analogioOffset = lib.mkOption {
76       type = lib.types.nullOr lib.types.int;
77       default = null;
78       description = ''
79         The amount of voltage in mV to offset analogio by.
80       '';
81     };
83     temp = lib.mkOption {
84       type = lib.types.nullOr lib.types.int;
85       default = null;
86       description = ''
87         The temperature target in Celsius degrees.
88       '';
89     };
91     tempAc = lib.mkOption {
92       type = lib.types.nullOr lib.types.int;
93       default = null;
94       description = ''
95         The temperature target on AC power in Celsius degrees.
96       '';
97     };
99     tempBat = lib.mkOption {
100       type = lib.types.nullOr lib.types.int;
101       default = null;
102       description = ''
103         The temperature target on battery power in Celsius degrees.
104       '';
105     };
107     turbo = lib.mkOption {
108       type = lib.types.nullOr lib.types.int;
109       default = null;
110       description = ''
111         Changes the Intel Turbo feature status (1 is disabled and 0 is enabled).
112       '';
113     };
115     p1.limit = lib.mkOption {
116       type = with lib.types; nullOr int;
117       default = null;
118       description = ''
119         The P1 Power Limit in Watts.
120         Both limit and window must be set.
121       '';
122     };
123     p1.window = lib.mkOption {
124       type = with lib.types; nullOr (oneOf [ float int ]);
125       default = null;
126       description = ''
127         The P1 Time Window in seconds.
128         Both limit and window must be set.
129       '';
130     };
132     p2.limit = lib.mkOption {
133       type = with lib.types; nullOr int;
134       default = null;
135       description = ''
136         The P2 Power Limit in Watts.
137         Both limit and window must be set.
138       '';
139     };
140     p2.window = lib.mkOption {
141       type = with lib.types; nullOr (oneOf [ float int ]);
142       default = null;
143       description = ''
144         The P2 Time Window in seconds.
145         Both limit and window must be set.
146       '';
147     };
149     useTimer = lib.mkOption {
150       type = lib.types.bool;
151       default = false;
152       description = ''
153         Whether to set a timer that applies the undervolt settings every 30s.
154         This will cause spam in the journal but might be required for some
155         hardware under specific conditions.
156         Enable this if your undervolt settings don't hold.
157       '';
158     };
159   };
161   config = lib.mkIf cfg.enable {
162     hardware.cpu.x86.msr.enable = true;
164     environment.systemPackages = [ cfg.package ];
166     systemd.services.undervolt = {
167       description = "Intel Undervolting Service";
169       # Apply undervolt on boot, nixos generation switch and resume
170       wantedBy = [ "multi-user.target" "post-resume.target" ];
171       after = [ "post-resume.target" ]; # Not sure why but it won't work without this
173       serviceConfig = {
174         Type = "oneshot";
175         Restart = "no";
176         ExecStart = "${cfg.package}/bin/undervolt ${toString cliArgs}";
177       };
178     };
180     systemd.timers.undervolt = lib.mkIf cfg.useTimer {
181       description = "Undervolt timer to ensure voltage settings are always applied";
182       partOf = [ "undervolt.service" ];
183       wantedBy = [ "multi-user.target" ];
184       timerConfig = {
185         OnBootSec = "2min";
186         OnUnitActiveSec = "30";
187       };
188     };
189   };