···493493- The `electron` packages now places its application files in `$out/libexec/electron` instead of `$out/lib/electron`. Packages using electron-builder will fail to build and need to be adjusted by changing `lib` to `libexec`.
494494495495- `teleport` has been upgraded from major version 12 to major version 14. Please see upstream [upgrade instructions](https://goteleport.com/docs/management/operations/upgrading/) and release notes for versions [13](https://goteleport.com/docs/changelog/#1300-050823) and [14](https://goteleport.com/docs/changelog/#1400-092023). Note that Teleport does not officially support upgrades across more than one major version at a time. If you're running Teleport server components, it is recommended to first upgrade to an intermediate 13.x version by setting `services.teleport.package = pkgs.teleport_13`. Afterwards, this option can be removed to upgrade to the default version (14).
496496+497497+- The Linux kernel module `msr` (see [`msr(4)`](https://man7.org/linux/man-pages/man4/msr.4.html)), which provides an interface to read and write the model-specific registers (MSRs) of an x86 CPU, can now be configured via `hardware.cpu.x86.msr`.
+91
nixos/modules/hardware/cpu/x86-msr.nix
···11+{ lib
22+, config
33+, options
44+, ...
55+}:
66+let
77+ inherit (builtins) hasAttr;
88+ inherit (lib) mkIf mdDoc;
99+ cfg = config.hardware.cpu.x86.msr;
1010+ opt = options.hardware.cpu.x86.msr;
1111+ defaultGroup = "msr";
1212+ isDefaultGroup = cfg.group == defaultGroup;
1313+ set = "to set for devices of the `msr` kernel subsystem.";
1414+1515+ # Generates `foo=bar` parameters to pass to the kernel.
1616+ # If `module = baz` is passed, generates `baz.foo=bar`.
1717+ # Adds double quotes on demand to handle `foo="bar baz"`.
1818+ kernelParam = { module ? null }: name: value:
1919+ assert lib.asserts.assertMsg (!lib.strings.hasInfix "=" name) "kernel parameter cannot have '=' in name";
2020+ let
2121+ key = (if module == null then "" else module + ".") + name;
2222+ valueString = lib.generators.mkValueStringDefault {} value;
2323+ quotedValueString = if lib.strings.hasInfix " " valueString
2424+ then lib.strings.escape ["\""] valueString
2525+ else valueString;
2626+ in "${key}=${quotedValueString}";
2727+ msrKernelParam = kernelParam { module = "msr"; };
2828+in
2929+{
3030+ options.hardware.cpu.x86.msr = with lib.options; with lib.types; {
3131+ enable = mkEnableOption (mdDoc "the `msr` (Model-Specific Registers) kernel module and configure `udev` rules for its devices (usually `/dev/cpu/*/msr`)");
3232+ owner = mkOption {
3333+ type = str;
3434+ default = "root";
3535+ example = "nobody";
3636+ description = mdDoc "Owner ${set}";
3737+ };
3838+ group = mkOption {
3939+ type = str;
4040+ default = defaultGroup;
4141+ example = "nobody";
4242+ description = mdDoc "Group ${set}";
4343+ };
4444+ mode = mkOption {
4545+ type = str;
4646+ default = "0640";
4747+ example = "0660";
4848+ description = mdDoc "Mode ${set}";
4949+ };
5050+ settings = mkOption {
5151+ type = submodule {
5252+ freeformType = attrsOf (oneOf [ bool int str ]);
5353+ options.allow-writes = mkOption {
5454+ type = nullOr (enum ["on" "off"]);
5555+ default = null;
5656+ description = "Whether to allow writes to MSRs (`\"on\"`) or not (`\"off\"`).";
5757+ };
5858+ };
5959+ default = {};
6060+ description = "Parameters for the `msr` kernel module.";
6161+ };
6262+ };
6363+6464+ config = mkIf cfg.enable {
6565+ assertions = [
6666+ {
6767+ assertion = hasAttr cfg.owner config.users.users;
6868+ message = "Owner '${cfg.owner}' set in `${opt.owner}` is not configured via `${options.users.users}.\"${cfg.owner}\"`.";
6969+ }
7070+ {
7171+ assertion = isDefaultGroup || (hasAttr cfg.group config.users.groups);
7272+ message = "Group '${cfg.group}' set in `${opt.group}` is not configured via `${options.users.groups}.\"${cfg.group}\"`.";
7373+ }
7474+ ];
7575+7676+ boot = {
7777+ kernelModules = [ "msr" ];
7878+ kernelParams = lib.attrsets.mapAttrsToList msrKernelParam (lib.attrsets.filterAttrs (_: value: value != null) cfg.settings);
7979+ };
8080+8181+ users.groups.${cfg.group} = mkIf isDefaultGroup { };
8282+8383+ services.udev.extraRules = ''
8484+ SUBSYSTEM=="msr", OWNER="${cfg.owner}", GROUP="${cfg.group}", MODE="${cfg.mode}"
8585+ '';
8686+ };
8787+8888+ meta = with lib; {
8989+ maintainers = with maintainers; [ lorenzleutgeb ];
9090+ };
9191+}