{
lib,
config,
options,
...
}:
let
inherit (builtins) hasAttr;
inherit (lib) mkIf;
cfg = config.hardware.cpu.x86.msr;
opt = options.hardware.cpu.x86.msr;
defaultGroup = "msr";
isDefaultGroup = cfg.group == defaultGroup;
set = "to set for devices of the `msr` kernel subsystem.";
# Generates `foo=bar` parameters to pass to the kernel.
# If `module = baz` is passed, generates `baz.foo=bar`.
# Adds double quotes on demand to handle `foo="bar baz"`.
kernelParam =
module ? null,
name: value:
assert lib.asserts.assertMsg (
!lib.strings.hasInfix "=" name
) "kernel parameter cannot have '=' in name";
key = (if module == null then "" else module + ".") + name;
valueString = lib.generators.mkValueStringDefault { } value;
quotedValueString =
if lib.strings.hasInfix " " valueString then
lib.strings.escape [ "\"" ] valueString
else
valueString;
in
"${key}=${quotedValueString}";
msrKernelParam = kernelParam { module = "msr"; };
options.hardware.cpu.x86.msr =
with lib.options;
with lib.types;
enable = mkEnableOption "the `msr` (Model-Specific Registers) kernel module and configure `udev` rules for its devices (usually `/dev/cpu/*/msr`)";
owner = mkOption {
type = str;
default = "root";
example = "nobody";
description = "Owner ${set}";
};
group = mkOption {
default = defaultGroup;
description = "Group ${set}";
mode = mkOption {
default = "0640";
example = "0660";
description = "Mode ${set}";
settings = mkOption {
type = submodule {
freeformType = attrsOf (oneOf [
bool
int
str
]);
options.allow-writes = mkOption {
type = nullOr (enum [
"on"
"off"
default = null;
description = "Whether to allow writes to MSRs (`\"on\"`) or not (`\"off\"`).";
default = { };
description = "Parameters for the `msr` kernel module.";
config = mkIf cfg.enable {
assertions = [
assertion = hasAttr cfg.owner config.users.users;
message = "Owner '${cfg.owner}' set in `${opt.owner}` is not configured via `${options.users.users}.\"${cfg.owner}\"`.";
}
assertion = isDefaultGroup || (hasAttr cfg.group config.users.groups);
message = "Group '${cfg.group}' set in `${opt.group}` is not configured via `${options.users.groups}.\"${cfg.group}\"`.";
];
boot = {
kernelModules = [ "msr" ];
kernelParams = lib.attrsets.mapAttrsToList msrKernelParam (
lib.attrsets.filterAttrs (_: value: value != null) cfg.settings
);
users.groups.${cfg.group} = mkIf isDefaultGroup { };
services.udev.extraRules = ''
SUBSYSTEM=="msr", OWNER="${cfg.owner}", GROUP="${cfg.group}", MODE="${cfg.mode}"
'';
meta = with lib; {
maintainers = with maintainers; [ lorenzleutgeb ];