about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNaïm Favier <n@monade.li>2022-12-27 17:10:43 +0100
committerGitHub <noreply@github.com>2022-12-27 17:10:43 +0100
commit3fc528ff7fa9d0de0343ffd877cdb76287be2549 (patch)
treefdddc2dadde85f4b516a4f3759a66c503a1dbb7e
parentb25ad6c15358d02fd3560f27ec9e545fa73c2b1f (diff)
parenta8fd50b79c899b3b4958f8bb95bb5717906a37b6 (diff)
Merge pull request #207095 from ncfavier/linux-custom-kernel
-rw-r--r--lib/tests/misc.nix15
-rw-r--r--lib/versions.nix15
-rw-r--r--nixos/doc/manual/configuration/linux-kernel.chapter.md83
-rw-r--r--nixos/doc/manual/from_md/configuration/linux-kernel.chapter.xml105
-rw-r--r--nixos/lib/testing/legacy.nix3
-rw-r--r--nixos/lib/testing/nodes.nix10
-rw-r--r--nixos/modules/testing/minimal-kernel.nix28
-rw-r--r--pkgs/os-specific/linux/kernel/generic.nix20
-rw-r--r--pkgs/os-specific/linux/kernel/linux-4.14.nix4
-rw-r--r--pkgs/os-specific/linux/kernel/linux-4.19.nix4
-rw-r--r--pkgs/os-specific/linux/kernel/linux-5.10.nix4
-rw-r--r--pkgs/os-specific/linux/kernel/linux-5.15.nix4
-rw-r--r--pkgs/os-specific/linux/kernel/linux-5.4.nix4
-rw-r--r--pkgs/os-specific/linux/kernel/linux-6.0.nix4
-rw-r--r--pkgs/os-specific/linux/kernel/linux-6.1.nix4
-rw-r--r--pkgs/os-specific/linux/kernel/linux-rt-5.10.nix3
-rw-r--r--pkgs/os-specific/linux/kernel/linux-testing.nix4
-rw-r--r--pkgs/os-specific/linux/kernel/manual-config.nix21
-rw-r--r--pkgs/os-specific/linux/kernel/xanmod-kernels.nix2
-rw-r--r--pkgs/os-specific/linux/kernel/zen-kernels.nix2
-rw-r--r--pkgs/top-level/all-packages.nix2
-rw-r--r--pkgs/top-level/linux-kernels.nix8
22 files changed, 189 insertions, 160 deletions
diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix
index c719fcf5d4fae..faf2b96530c1c 100644
--- a/lib/tests/misc.nix
+++ b/lib/tests/misc.nix
@@ -212,6 +212,21 @@ runTests {
     expected = [ "1" "2" "3" ];
   };
 
+  testPadVersionLess = {
+    expr = versions.pad 3 "1.2";
+    expected = "1.2.0";
+  };
+
+  testPadVersionLessExtra = {
+    expr = versions.pad 3 "1.3-rc1";
+    expected = "1.3.0-rc1";
+  };
+
+  testPadVersionMore = {
+    expr = versions.pad 3 "1.2.3.4";
+    expected = "1.2.3";
+  };
+
   testIsStorePath =  {
     expr =
       let goodPath =
diff --git a/lib/versions.nix b/lib/versions.nix
index 0e9d81ac78b1e..986e7e5f9b37d 100644
--- a/lib/versions.nix
+++ b/lib/versions.nix
@@ -46,4 +46,19 @@ rec {
     builtins.concatStringsSep "."
     (lib.take 2 (splitVersion v));
 
+  /* Pad a version string with zeros to match the given number of components.
+
+     Example:
+       pad 3 "1.2"
+       => "1.2.0"
+       pad 3 "1.3-rc1"
+       => "1.3.0-rc1"
+       pad 3 "1.2.3.4"
+       => "1.2.3"
+  */
+  pad = n: version: let
+    numericVersion = lib.head (lib.splitString "-" version);
+    versionSuffix = lib.removePrefix numericVersion version;
+  in lib.concatStringsSep "." (lib.take n (lib.splitVersion numericVersion ++ lib.genList (_: "0") n)) + versionSuffix;
+
 }
diff --git a/nixos/doc/manual/configuration/linux-kernel.chapter.md b/nixos/doc/manual/configuration/linux-kernel.chapter.md
index 7b84416a86465..f5bce99dd1bbe 100644
--- a/nixos/doc/manual/configuration/linux-kernel.chapter.md
+++ b/nixos/doc/manual/configuration/linux-kernel.chapter.md
@@ -82,61 +82,68 @@ boot.kernel.sysctl."net.ipv4.tcp_keepalive_time" = 120;
 sets the kernel's TCP keepalive time to 120 seconds. To see the
 available parameters, run `sysctl -a`.
 
-## Customize your kernel {#sec-linux-config-customizing}
+## Building a custom kernel {#sec-linux-config-customizing}
 
-The first step before compiling the kernel is to generate an appropriate
-`.config` configuration. Either you pass your own config via the
-`configfile` setting of `linuxKernel.manualConfig`:
+You can customize the default kernel configuration by overriding the arguments for your kernel package:
 
 ```nix
-custom-kernel = let base_kernel = linuxKernel.kernels.linux_4_9;
-  in super.linuxKernel.manualConfig {
-    inherit (super) stdenv hostPlatform;
-    inherit (base_kernel) src;
-    version = "${base_kernel.version}-custom";
-
-    configfile = /home/me/my_kernel_config;
-    allowImportFromDerivation = true;
-};
+pkgs.linux_latest.override {
+  ignoreConfigErrors = true;
+  autoModules = false;
+  kernelPreferBuiltin = true;
+  extraStructuredConfig = with lib.kernel; {
+    DEBUG_KERNEL = yes;
+    FRAME_POINTER = yes;
+    KGDB = yes;
+    KGDB_SERIAL_CONSOLE = yes;
+    DEBUG_INFO = yes;
+  };
+}
 ```
 
-You can edit the config with this snippet (by default `make
-   menuconfig` won\'t work out of the box on nixos):
+See `pkgs/os-specific/linux/kernel/generic.nix` for details on how these arguments
+affect the generated configuration. You can also build a custom version of Linux by calling
+`pkgs.buildLinux` directly, which requires the `src` and `version` arguments to be specified.
 
-```ShellSession
-nix-shell -E 'with import <nixpkgs> {}; kernelToOverride.overrideAttrs (o: {nativeBuildInputs=o.nativeBuildInputs ++ [ pkg-config ncurses ];})'
+To use your custom kernel package in your NixOS configuration, set
+
+```nix
+boot.kernelPackages = pkgs.linuxPackagesFor yourCustomKernel;
 ```
 
-or you can let nixpkgs generate the configuration. Nixpkgs generates it
-via answering the interactive kernel utility `make config`. The answers
-depend on parameters passed to
-`pkgs/os-specific/linux/kernel/generic.nix` (which you can influence by
-overriding `extraConfig, autoModules,
-   modDirVersion, preferBuiltin, extraConfig`).
+Note that this method will use the common configuration defined in `pkgs/os-specific/linux/kernel/common-config.nix`,
+which is suitable for a NixOS system.
+
+If you already have a generated configuration file, you can build a kernel that uses it with `pkgs.linuxManualConfig`:
 
 ```nix
-mptcp93.override ({
-  name="mptcp-local";
+let
+  baseKernel = pkgs.linux_latest;
+in pkgs.linuxManualConfig {
+  inherit (baseKernel) src modDirVersion;
+  version = "${baseKernel.version}-custom";
+  configfile = ./my_kernel_config;
+  allowImportFromDerivation = true;
+}
+```
 
-  ignoreConfigErrors = true;
-  autoModules = false;
-  kernelPreferBuiltin = true;
+::: {.note}
+The build will fail if `modDirVersion` does not match the source's `kernel.release` file,
+so `modDirVersion` should remain tied to `src`.
+:::
 
-  enableParallelBuilding = true;
+To edit the `.config` file for Linux X.Y, proceed as follows:
 
-  extraConfig = ''
-    DEBUG_KERNEL y
-    FRAME_POINTER y
-    KGDB y
-    KGDB_SERIAL_CONSOLE y
-    DEBUG_INFO y
-  '';
-});
+```ShellSession
+$ nix-shell '<nixpkgs>' -A linuxKernel.kernels.linux_X_Y.configEnv
+$ unpackPhase
+$ cd linux-*
+$ make nconfig
 ```
 
 ## Developing kernel modules {#sec-linux-config-developing-modules}
 
-When developing kernel modules it\'s often convenient to run
+When developing kernel modules it's often convenient to run
 edit-compile-run loop as quickly as possible. See below snippet as an
 example of developing `mellanox` drivers.
 
diff --git a/nixos/doc/manual/from_md/configuration/linux-kernel.chapter.xml b/nixos/doc/manual/from_md/configuration/linux-kernel.chapter.xml
index dd570e1d66c27..058a890d7a3e3 100644
--- a/nixos/doc/manual/from_md/configuration/linux-kernel.chapter.xml
+++ b/nixos/doc/manual/from_md/configuration/linux-kernel.chapter.xml
@@ -96,65 +96,82 @@ boot.kernel.sysctl.&quot;net.ipv4.tcp_keepalive_time&quot; = 120;
     available parameters, run <literal>sysctl -a</literal>.
   </para>
   <section xml:id="sec-linux-config-customizing">
-    <title>Customize your kernel</title>
+    <title>Building a custom kernel</title>
     <para>
-      The first step before compiling the kernel is to generate an
-      appropriate <literal>.config</literal> configuration. Either you
-      pass your own config via the <literal>configfile</literal> setting
-      of <literal>linuxKernel.manualConfig</literal>:
+      You can customize the default kernel configuration by overriding
+      the arguments for your kernel package:
     </para>
     <programlisting language="bash">
-custom-kernel = let base_kernel = linuxKernel.kernels.linux_4_9;
-  in super.linuxKernel.manualConfig {
-    inherit (super) stdenv hostPlatform;
-    inherit (base_kernel) src;
-    version = &quot;${base_kernel.version}-custom&quot;;
-
-    configfile = /home/me/my_kernel_config;
-    allowImportFromDerivation = true;
-};
+pkgs.linux_latest.override {
+  ignoreConfigErrors = true;
+  autoModules = false;
+  kernelPreferBuiltin = true;
+  extraStructuredConfig = with lib.kernel; {
+    DEBUG_KERNEL = yes;
+    FRAME_POINTER = yes;
+    KGDB = yes;
+    KGDB_SERIAL_CONSOLE = yes;
+    DEBUG_INFO = yes;
+  };
+}
 </programlisting>
     <para>
-      You can edit the config with this snippet (by default
-      <literal>make menuconfig</literal> won't work out of the box on
-      nixos):
+      See <literal>pkgs/os-specific/linux/kernel/generic.nix</literal>
+      for details on how these arguments affect the generated
+      configuration. You can also build a custom version of Linux by
+      calling <literal>pkgs.buildLinux</literal> directly, which
+      requires the <literal>src</literal> and <literal>version</literal>
+      arguments to be specified.
     </para>
-    <programlisting>
-nix-shell -E 'with import &lt;nixpkgs&gt; {}; kernelToOverride.overrideAttrs (o: {nativeBuildInputs=o.nativeBuildInputs ++ [ pkg-config ncurses ];})'
+    <para>
+      To use your custom kernel package in your NixOS configuration, set
+    </para>
+    <programlisting language="bash">
+boot.kernelPackages = pkgs.linuxPackagesFor yourCustomKernel;
 </programlisting>
     <para>
-      or you can let nixpkgs generate the configuration. Nixpkgs
-      generates it via answering the interactive kernel utility
-      <literal>make config</literal>. The answers depend on parameters
-      passed to
-      <literal>pkgs/os-specific/linux/kernel/generic.nix</literal>
-      (which you can influence by overriding
-      <literal>extraConfig, autoModules, modDirVersion, preferBuiltin, extraConfig</literal>).
+      Note that this method will use the common configuration defined in
+      <literal>pkgs/os-specific/linux/kernel/common-config.nix</literal>,
+      which is suitable for a NixOS system.
+    </para>
+    <para>
+      If you already have a generated configuration file, you can build
+      a kernel that uses it with
+      <literal>pkgs.linuxManualConfig</literal>:
     </para>
     <programlisting language="bash">
-mptcp93.override ({
-  name=&quot;mptcp-local&quot;;
-
-  ignoreConfigErrors = true;
-  autoModules = false;
-  kernelPreferBuiltin = true;
-
-  enableParallelBuilding = true;
-
-  extraConfig = ''
-    DEBUG_KERNEL y
-    FRAME_POINTER y
-    KGDB y
-    KGDB_SERIAL_CONSOLE y
-    DEBUG_INFO y
-  '';
-});
+let
+  baseKernel = pkgs.linux_latest;
+in pkgs.linuxManualConfig {
+  inherit (baseKernel) src modDirVersion;
+  version = &quot;${baseKernel.version}-custom&quot;;
+  configfile = ./my_kernel_config;
+  allowImportFromDerivation = true;
+}
+</programlisting>
+    <note>
+      <para>
+        The build will fail if <literal>modDirVersion</literal> does not
+        match the source’s <literal>kernel.release</literal> file, so
+        <literal>modDirVersion</literal> should remain tied to
+        <literal>src</literal>.
+      </para>
+    </note>
+    <para>
+      To edit the <literal>.config</literal> file for Linux X.Y, proceed
+      as follows:
+    </para>
+    <programlisting>
+$ nix-shell '&lt;nixpkgs&gt;' -A linuxKernel.kernels.linux_X_Y.configEnv
+$ unpackPhase
+$ cd linux-*
+$ make nconfig
 </programlisting>
   </section>
   <section xml:id="sec-linux-config-developing-modules">
     <title>Developing kernel modules</title>
     <para>
-      When developing kernel modules it's often convenient to run
+      When developing kernel modules it’s often convenient to run
       edit-compile-run loop as quickly as possible. See below snippet as
       an example of developing <literal>mellanox</literal> drivers.
     </para>
diff --git a/nixos/lib/testing/legacy.nix b/nixos/lib/testing/legacy.nix
index 868b8b65b17d5..b310575566015 100644
--- a/nixos/lib/testing/legacy.nix
+++ b/nixos/lib/testing/legacy.nix
@@ -3,9 +3,10 @@ let
   inherit (lib) mkIf mkOption types;
 in
 {
-  # This needs options.warnings, which we don't have (yet?).
+  # This needs options.warnings and options.assertions, which we don't have (yet?).
   # imports = [
   #   (lib.mkRenamedOptionModule [ "machine" ] [ "nodes" "machine" ])
+  #   (lib.mkRemovedOptionModule [ "minimal" ] "The minimal kernel module was removed as it was broken and not used any more in nixpkgs.")
   # ];
 
   options = {
diff --git a/nixos/lib/testing/nodes.nix b/nixos/lib/testing/nodes.nix
index 8e620c96b3bb1..c538ab468c526 100644
--- a/nixos/lib/testing/nodes.nix
+++ b/nixos/lib/testing/nodes.nix
@@ -23,7 +23,7 @@ let
               nixpkgs.config.allowAliases = false;
             })
           testModuleArgs.config.extraBaseModules
-        ] ++ optional config.minimal ../../modules/testing/minimal-kernel.nix;
+        ];
     };
 
 
@@ -78,14 +78,6 @@ in
       '';
     };
 
-    minimal = mkOption {
-      type = types.bool;
-      default = false;
-      description = mdDoc ''
-        Enable to configure all [{option}`nodes`](#test-opt-nodes) to run with a minimal kernel.
-      '';
-    };
-
     nodesCompat = mkOption {
       internal = true;
       description = mdDoc ''
diff --git a/nixos/modules/testing/minimal-kernel.nix b/nixos/modules/testing/minimal-kernel.nix
deleted file mode 100644
index 7c2b9c05cf9a0..0000000000000
--- a/nixos/modules/testing/minimal-kernel.nix
+++ /dev/null
@@ -1,28 +0,0 @@
-{ config, pkgs, lib, ... }:
-
-let
-  configfile = builtins.storePath (builtins.toFile "config" (lib.concatStringsSep "\n"
-    (map (builtins.getAttr "configLine") config.system.requiredKernelConfig))
-  );
-
-  origKernel = pkgs.buildLinux {
-    inherit (pkgs.linux) src version stdenv;
-    inherit configfile;
-    allowImportFromDerivation = true;
-    kernelPatches = [ pkgs.kernelPatches.cifs_timeout_2_6_38 ];
-  };
-
-  kernel = origKernel // (derivation (origKernel.drvAttrs // {
-    configurePhase = ''
-      runHook preConfigure
-      mkdir ../build
-      make $makeFlags "''${makeFlagsArray[@]}" mrproper
-      make $makeFlags "''${makeFlagsArray[@]}" KCONFIG_ALLCONFIG=${configfile} allnoconfig
-      runHook postConfigure
-    '';
-  }));
-
-   kernelPackages = pkgs.linuxPackagesFor kernel;
-in {
-  boot.kernelPackages = kernelPackages;
-}
diff --git a/pkgs/os-specific/linux/kernel/generic.nix b/pkgs/os-specific/linux/kernel/generic.nix
index 5a4c2858f95f7..5a39ef9150006 100644
--- a/pkgs/os-specific/linux/kernel/generic.nix
+++ b/pkgs/os-specific/linux/kernel/generic.nix
@@ -29,7 +29,8 @@
  structuredExtraConfig ? {}
 
 , # The version number used for the module directory
-  modDirVersion ? version
+  # If unspecified, this is determined automatically from the version.
+  modDirVersion ? null
 
 , # An attribute set whose attributes express the availability of
   # certain features in this kernel.  E.g. `{iwlwifi = true;}'
@@ -194,17 +195,26 @@ let
     };
   }; # end of configfile derivation
 
-  kernel = (callPackage ./manual-config.nix { inherit buildPackages;  }) (basicArgs // {
-    inherit modDirVersion kernelPatches randstructSeed lib stdenv extraMakeFlags extraMeta configfile;
+  kernel = (callPackage ./manual-config.nix { inherit lib stdenv buildPackages; }) (basicArgs // {
+    inherit kernelPatches randstructSeed extraMakeFlags extraMeta configfile;
     pos = builtins.unsafeGetAttrPos "version" args;
 
     config = { CONFIG_MODULES = "y"; CONFIG_FW_LOADER = "m"; };
-  });
+  } // lib.optionalAttrs (modDirVersion != null) { inherit modDirVersion; });
 
   passthru = basicArgs // {
     features = kernelFeatures;
-    inherit commonStructuredConfig structuredExtraConfig extraMakeFlags isZen isHardened isLibre modDirVersion;
+    inherit commonStructuredConfig structuredExtraConfig extraMakeFlags isZen isHardened isLibre;
     isXen = lib.warn "The isXen attribute is deprecated. All Nixpkgs kernels that support it now have Xen enabled." true;
+
+    # Adds dependencies needed to edit the config:
+    # nix-shell '<nixpkgs>' -A linux.configEnv --command 'make nconfig'
+    configEnv = kernel.overrideAttrs (old: {
+      nativeBuildInputs = old.nativeBuildInputs or [] ++ (with buildPackages; [
+        pkg-config ncurses
+      ]);
+    });
+
     passthru = kernel.passthru // (removeAttrs passthru [ "passthru" ]);
     tests = let
       overridableKernel = finalKernel // {
diff --git a/pkgs/os-specific/linux/kernel/linux-4.14.nix b/pkgs/os-specific/linux/kernel/linux-4.14.nix
index 02893f731e3ee..0b954a0ef902c 100644
--- a/pkgs/os-specific/linux/kernel/linux-4.14.nix
+++ b/pkgs/os-specific/linux/kernel/linux-4.14.nix
@@ -1,4 +1,4 @@
-{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, ... } @ args:
 
 with lib;
 
@@ -6,7 +6,7 @@ buildLinux (args // rec {
   version = "4.14.302";
 
   # modDirVersion needs to be x.y.z, will automatically add .0 if needed
-  modDirVersion = if (modDirVersionArg == null) then concatStringsSep "." (take 3 (splitVersion "${version}.0")) else modDirVersionArg;
+  modDirVersion = versions.pad 3 version;
 
   # branchVersion needs to be x.y
   extraMeta.branch = versions.majorMinor version;
diff --git a/pkgs/os-specific/linux/kernel/linux-4.19.nix b/pkgs/os-specific/linux/kernel/linux-4.19.nix
index 44a976ef0c7d9..07583ccb4df6c 100644
--- a/pkgs/os-specific/linux/kernel/linux-4.19.nix
+++ b/pkgs/os-specific/linux/kernel/linux-4.19.nix
@@ -1,4 +1,4 @@
-{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, ... } @ args:
 
 with lib;
 
@@ -6,7 +6,7 @@ buildLinux (args // rec {
   version = "4.19.269";
 
   # modDirVersion needs to be x.y.z, will automatically add .0 if needed
-  modDirVersion = if (modDirVersionArg == null) then concatStringsSep "." (take 3 (splitVersion "${version}.0")) else modDirVersionArg;
+  modDirVersion = versions.pad 3 version;
 
   # branchVersion needs to be x.y
   extraMeta.branch = versions.majorMinor version;
diff --git a/pkgs/os-specific/linux/kernel/linux-5.10.nix b/pkgs/os-specific/linux/kernel/linux-5.10.nix
index 72b62e6b2d899..56d3acb0580ad 100644
--- a/pkgs/os-specific/linux/kernel/linux-5.10.nix
+++ b/pkgs/os-specific/linux/kernel/linux-5.10.nix
@@ -1,4 +1,4 @@
-{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, ... } @ args:
 
 with lib;
 
@@ -6,7 +6,7 @@ buildLinux (args // rec {
   version = "5.10.161";
 
   # modDirVersion needs to be x.y.z, will automatically add .0 if needed
-  modDirVersion = if (modDirVersionArg == null) then concatStringsSep "." (take 3 (splitVersion "${version}.0")) else modDirVersionArg;
+  modDirVersion = versions.pad 3 version;
 
   # branchVersion needs to be x.y
   extraMeta.branch = versions.majorMinor version;
diff --git a/pkgs/os-specific/linux/kernel/linux-5.15.nix b/pkgs/os-specific/linux/kernel/linux-5.15.nix
index 65abe73b120fd..561447eca00bc 100644
--- a/pkgs/os-specific/linux/kernel/linux-5.15.nix
+++ b/pkgs/os-specific/linux/kernel/linux-5.15.nix
@@ -1,4 +1,4 @@
-{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, ... } @ args:
 
 with lib;
 
@@ -6,7 +6,7 @@ buildLinux (args // rec {
   version = "5.15.85";
 
   # modDirVersion needs to be x.y.z, will automatically add .0 if needed
-  modDirVersion = if (modDirVersionArg == null) then concatStringsSep "." (take 3 (splitVersion "${version}.0")) else modDirVersionArg;
+  modDirVersion = versions.pad 3 version;
 
   # branchVersion needs to be x.y
   extraMeta.branch = versions.majorMinor version;
diff --git a/pkgs/os-specific/linux/kernel/linux-5.4.nix b/pkgs/os-specific/linux/kernel/linux-5.4.nix
index 1dd9521ad0d2c..382abbaa84e12 100644
--- a/pkgs/os-specific/linux/kernel/linux-5.4.nix
+++ b/pkgs/os-specific/linux/kernel/linux-5.4.nix
@@ -1,4 +1,4 @@
-{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, ... } @ args:
 
 with lib;
 
@@ -6,7 +6,7 @@ buildLinux (args // rec {
   version = "5.4.228";
 
   # modDirVersion needs to be x.y.z, will automatically add .0 if needed
-  modDirVersion = if (modDirVersionArg == null) then concatStringsSep "." (take 3 (splitVersion "${version}.0")) else modDirVersionArg;
+  modDirVersion = versions.pad 3 version;
 
   # branchVersion needs to be x.y
   extraMeta.branch = versions.majorMinor version;
diff --git a/pkgs/os-specific/linux/kernel/linux-6.0.nix b/pkgs/os-specific/linux/kernel/linux-6.0.nix
index 6865bd9f6ed08..6cb9aae83be31 100644
--- a/pkgs/os-specific/linux/kernel/linux-6.0.nix
+++ b/pkgs/os-specific/linux/kernel/linux-6.0.nix
@@ -1,4 +1,4 @@
-{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, ... } @ args:
 
 with lib;
 
@@ -6,7 +6,7 @@ buildLinux (args // rec {
   version = "6.0.15";
 
   # modDirVersion needs to be x.y.z, will automatically add .0 if needed
-  modDirVersion = if (modDirVersionArg == null) then concatStringsSep "." (take 3 (splitVersion "${version}.0")) else modDirVersionArg;
+  modDirVersion = versions.pad 3 version;
 
   # branchVersion needs to be x.y
   extraMeta.branch = versions.majorMinor version;
diff --git a/pkgs/os-specific/linux/kernel/linux-6.1.nix b/pkgs/os-specific/linux/kernel/linux-6.1.nix
index 1e5917db8de57..594fcb45573fb 100644
--- a/pkgs/os-specific/linux/kernel/linux-6.1.nix
+++ b/pkgs/os-specific/linux/kernel/linux-6.1.nix
@@ -1,4 +1,4 @@
-{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, ... } @ args:
 
 with lib;
 
@@ -6,7 +6,7 @@ buildLinux (args // rec {
   version = "6.1.1";
 
   # modDirVersion needs to be x.y.z, will automatically add .0 if needed
-  modDirVersion = if (modDirVersionArg == null) then concatStringsSep "." (take 3 (splitVersion "${version}.0")) else modDirVersionArg;
+  modDirVersion = versions.pad 3 version;
 
   # branchVersion needs to be x.y
   extraMeta.branch = versions.majorMinor version;
diff --git a/pkgs/os-specific/linux/kernel/linux-rt-5.10.nix b/pkgs/os-specific/linux/kernel/linux-rt-5.10.nix
index 103b142054af7..a97b1acb5aad9 100644
--- a/pkgs/os-specific/linux/kernel/linux-rt-5.10.nix
+++ b/pkgs/os-specific/linux/kernel/linux-rt-5.10.nix
@@ -13,8 +13,7 @@ in buildLinux (args // {
   inherit version;
 
   # modDirVersion needs a patch number, change X.Y-rtZ to X.Y.0-rtZ.
-  modDirVersion = if (builtins.match "[^.]*[.][^.]*-.*" version) == null then version
-    else lib.replaceStrings ["-"] [".0-"] version;
+  modDirVersion = lib.versions.pad 3 version;
 
   src = fetchurl {
     url = "mirror://kernel/linux/kernel/v5.x/linux-${kversion}.tar.xz";
diff --git a/pkgs/os-specific/linux/kernel/linux-testing.nix b/pkgs/os-specific/linux/kernel/linux-testing.nix
index 76db1b11bbd25..f9060325051c7 100644
--- a/pkgs/os-specific/linux/kernel/linux-testing.nix
+++ b/pkgs/os-specific/linux/kernel/linux-testing.nix
@@ -1,4 +1,4 @@
-{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, ... } @ args:
 
 with lib;
 
@@ -7,7 +7,7 @@ buildLinux (args // rec {
   extraMeta.branch = lib.versions.majorMinor version;
 
   # modDirVersion needs to be x.y.z, will always add .0
-  modDirVersion = if (modDirVersionArg == null) then builtins.replaceStrings ["-"] [".0-"] version else modDirVersionArg;
+  modDirVersion = versions.pad 3 version;
 
   src = fetchurl {
     url = "https://git.kernel.org/torvalds/t/linux-${version}.tar.gz";
diff --git a/pkgs/os-specific/linux/kernel/manual-config.nix b/pkgs/os-specific/linux/kernel/manual-config.nix
index edfd1f7dbc28a..45281d5d3bdb4 100644
--- a/pkgs/os-specific/linux/kernel/manual-config.nix
+++ b/pkgs/os-specific/linux/kernel/manual-config.nix
@@ -1,8 +1,11 @@
-{ lib, buildPackages, runCommand, nettools, bc, bison, flex, perl, rsync, gmp, libmpc, mpfr, openssl
+{ lib, stdenv, buildPackages, runCommand, nettools, bc, bison, flex, perl, rsync, gmp, libmpc, mpfr, openssl
 , libelf, cpio, elfutils, zstd, python3Minimal, zlib, pahole
 }:
 
 let
+  lib_ = lib;
+  stdenv_ = stdenv;
+
   readConfig = configfile: import (runCommand "config.nix" {} ''
     echo "{" > "$out"
     while IFS='=' read key val; do
@@ -12,18 +15,16 @@ let
     done < "${configfile}"
     echo "}" >> $out
   '').outPath;
-in {
-  lib,
-  # Allow overriding stdenv on each buildLinux call
-  stdenv,
+in lib.makeOverridable ({
   # The kernel version
   version,
   # Position of the Linux build expression
   pos ? null,
   # Additional kernel make flags
   extraMakeFlags ? [],
-  # The version of the kernel module directory
-  modDirVersion ? version,
+  # The name of the kernel module directory
+  # Needs to be X.Y.Z[-extra], so pad with zeros if needed.
+  modDirVersion ? lib.versions.pad 3 version,
   # The kernel source (tarball, git checkout, etc.)
   src,
   # a list of { name=..., patch=..., extraConfig=...} patches
@@ -36,7 +37,7 @@ in {
   # Custom seed used for CONFIG_GCC_PLUGIN_RANDSTRUCT if enabled. This is
   # automatically extended with extra per-version and per-config values.
   randstructSeed ? "",
-  # Use defaultMeta // extraMeta
+  # Extra meta attributes
   extraMeta ? {},
 
   # for module compatibility
@@ -47,7 +48,7 @@ in {
   # Whether to utilize the controversial import-from-derivation feature to parse the config
   allowImportFromDerivation ? false,
   # ignored
-  features ? null,
+  features ? null, lib ? lib_, stdenv ? stdenv_,
 }:
 
 let
@@ -386,4 +387,4 @@ stdenv.mkDerivation ((drvAttrs config stdenv.hostPlatform.linux-kernel kernelPat
     ++ extraMakeFlags;
 
   karch = stdenv.hostPlatform.linuxArch;
-} // (optionalAttrs (pos != null) { inherit pos; }))
+} // (optionalAttrs (pos != null) { inherit pos; })))
diff --git a/pkgs/os-specific/linux/kernel/xanmod-kernels.nix b/pkgs/os-specific/linux/kernel/xanmod-kernels.nix
index 7450dab107a23..d203a46294570 100644
--- a/pkgs/os-specific/linux/kernel/xanmod-kernels.nix
+++ b/pkgs/os-specific/linux/kernel/xanmod-kernels.nix
@@ -16,7 +16,7 @@ let
 
   xanmodKernelFor = { version, suffix ? "xanmod1", hash, variant }: buildLinux (args // rec {
     inherit version;
-    modDirVersion = "${version}-${suffix}";
+    modDirVersion = lib.versions.pad 3 "${version}-${suffix}";
 
     src = fetchFromGitHub {
       owner = "xanmod";
diff --git a/pkgs/os-specific/linux/kernel/zen-kernels.nix b/pkgs/os-specific/linux/kernel/zen-kernels.nix
index a58782828478a..08671e83ffc51 100644
--- a/pkgs/os-specific/linux/kernel/zen-kernels.nix
+++ b/pkgs/os-specific/linux/kernel/zen-kernels.nix
@@ -18,7 +18,7 @@ let
   };
   zenKernelsFor = { version, suffix, sha256, isLqx }: buildLinux (args // {
     inherit version;
-    modDirVersion = "${lib.concatStringsSep "." (lib.take 3 (lib.splitVersion version ++ [ "0" "0" ]))}-${suffix}";
+    modDirVersion = lib.versions.pad 3 "${version}-${suffix}";
     isZen = true;
 
     src = fetchFromGitHub {
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 342052eb5f85f..4effc9ca5f02c 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -25546,7 +25546,7 @@ with pkgs;
   linuxPackages_custom_tinyconfig_kernel = let
     base = linuxPackages.kernel;
     tinyLinuxPackages = linuxKernel.customPackage {
-      inherit (base) version src;
+      inherit (base) version modDirVersion src;
       allowImportFromDerivation = false;
       configfile = linuxConfig {
         makeTarget = "tinyconfig";
diff --git a/pkgs/top-level/linux-kernels.nix b/pkgs/top-level/linux-kernels.nix
index ac0511a649bf1..d6c9bd3ceeaef 100644
--- a/pkgs/top-level/linux-kernels.nix
+++ b/pkgs/top-level/linux-kernels.nix
@@ -40,6 +40,7 @@ let
       };
       argsOverride = {
         inherit version;
+        modDirVersion = modDirVersion' + kernelPatches.hardened.${kernel.meta.branch}.extra;
         src = fetchurl {
           url = "mirror://kernel/linux/kernel/v${major}.x/linux-${version}.tar.xz";
           inherit sha256;
@@ -48,7 +49,6 @@ let
       kernelPatches = kernel.kernelPatches ++ [
         kernelPatches.hardened.${kernel.meta.branch}
       ];
-      modDirVersionArg = modDirVersion' + (kernelPatches.hardened.${kernel.meta.branch}).extra;
       isHardened = true;
   };
 in {
@@ -593,11 +593,11 @@ in {
     linux_hardkernel_latest = packages.hardkernel_4_14;
   };
 
-  manualConfig = makeOverridable (callPackage ../os-specific/linux/kernel/manual-config.nix {});
+  manualConfig = callPackage ../os-specific/linux/kernel/manual-config.nix {};
 
-  customPackage = { version, src, configfile, allowImportFromDerivation ? true }:
+  customPackage = { version, src, modDirVersion ? lib.versions.pad 3 version, configfile, allowImportFromDerivation ? true }:
     recurseIntoAttrs (packagesFor (manualConfig {
-      inherit version src configfile lib stdenv allowImportFromDerivation;
+      inherit version src modDirVersion configfile allowImportFromDerivation;
     }));
 
   # Derive one of the default .config files