summary refs log tree commit diff
path: root/pkgs/os-specific/linux/kernel
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2021-08-04 10:43:07 +0000
committerAlyssa Ross <hi@alyssa.is>2021-08-04 10:43:07 +0000
commit62614cbef7da005c1eda8c9400160f6bcd6546b8 (patch)
treec2630f69080637987b68acb1ee8676d2681fe304 /pkgs/os-specific/linux/kernel
parentd9c82ed3044c72cecf01c6ea042489d30914577c (diff)
parente24069138dfec3ef94f211f1da005bb5395adc11 (diff)
downloadnixpkgs-62614cbef7da005c1eda8c9400160f6bcd6546b8.tar
nixpkgs-62614cbef7da005c1eda8c9400160f6bcd6546b8.tar.gz
nixpkgs-62614cbef7da005c1eda8c9400160f6bcd6546b8.tar.bz2
nixpkgs-62614cbef7da005c1eda8c9400160f6bcd6546b8.tar.lz
nixpkgs-62614cbef7da005c1eda8c9400160f6bcd6546b8.tar.xz
nixpkgs-62614cbef7da005c1eda8c9400160f6bcd6546b8.tar.zst
nixpkgs-62614cbef7da005c1eda8c9400160f6bcd6546b8.zip
Merge branch 'nixpkgs-update' into master
Diffstat (limited to 'pkgs/os-specific/linux/kernel')
-rw-r--r--pkgs/os-specific/linux/kernel/common-config.nix139
-rw-r--r--pkgs/os-specific/linux/kernel/export-rt-sched-migrate.patch11
-rw-r--r--pkgs/os-specific/linux/kernel/generate-config.pl9
-rw-r--r--pkgs/os-specific/linux/kernel/generic.nix68
-rw-r--r--pkgs/os-specific/linux/kernel/hardened/config.nix24
-rw-r--r--pkgs/os-specific/linux/kernel/hardened/patches.json38
-rw-r--r--pkgs/os-specific/linux/kernel/hardened/tag-hardened.patch7
-rwxr-xr-xpkgs/os-specific/linux/kernel/hardened/update.py15
-rw-r--r--pkgs/os-specific/linux/kernel/linux-4.14.nix10
-rw-r--r--pkgs/os-specific/linux/kernel/linux-4.19.nix10
-rw-r--r--pkgs/os-specific/linux/kernel/linux-4.4.nix9
-rw-r--r--pkgs/os-specific/linux/kernel/linux-4.9.nix9
-rw-r--r--pkgs/os-specific/linux/kernel/linux-5.10.nix (renamed from pkgs/os-specific/linux/kernel/linux-5.7.nix)10
-rw-r--r--pkgs/os-specific/linux/kernel/linux-5.12.nix (renamed from pkgs/os-specific/linux/kernel/linux-5.8.nix)10
-rw-r--r--pkgs/os-specific/linux/kernel/linux-5.13.nix21
-rw-r--r--pkgs/os-specific/linux/kernel/linux-5.4.nix10
-rw-r--r--pkgs/os-specific/linux/kernel/linux-hardkernel-4.14.nix2
-rw-r--r--pkgs/os-specific/linux/kernel/linux-libre.nix7
-rw-r--r--pkgs/os-specific/linux/kernel/linux-lqx.nix26
-rw-r--r--pkgs/os-specific/linux/kernel/linux-mptcp-94.nix26
-rw-r--r--pkgs/os-specific/linux/kernel/linux-mptcp-95.nix14
-rw-r--r--pkgs/os-specific/linux/kernel/linux-rpi.nix15
-rw-r--r--pkgs/os-specific/linux/kernel/linux-rt-5.10.nix45
-rw-r--r--pkgs/os-specific/linux/kernel/linux-rt-5.11.nix45
-rw-r--r--pkgs/os-specific/linux/kernel/linux-rt-5.4.nix41
-rw-r--r--pkgs/os-specific/linux/kernel/linux-testing-bcachefs.nix47
-rw-r--r--pkgs/os-specific/linux/kernel/linux-testing.nix12
-rw-r--r--pkgs/os-specific/linux/kernel/linux-xanmod.nix54
-rw-r--r--pkgs/os-specific/linux/kernel/linux-zen.nix19
-rw-r--r--pkgs/os-specific/linux/kernel/manual-config.nix104
-rw-r--r--pkgs/os-specific/linux/kernel/mptcp-config.nix4
-rw-r--r--pkgs/os-specific/linux/kernel/patches.nix33
-rw-r--r--pkgs/os-specific/linux/kernel/perf.nix23
-rw-r--r--pkgs/os-specific/linux/kernel/rtl8761b-support.patch33
-rwxr-xr-xpkgs/os-specific/linux/kernel/update-rt.sh79
-rwxr-xr-xpkgs/os-specific/linux/kernel/update.sh3
36 files changed, 782 insertions, 250 deletions
diff --git a/pkgs/os-specific/linux/kernel/common-config.nix b/pkgs/os-specific/linux/kernel/common-config.nix
index c0da19dd391..355e653c8ea 100644
--- a/pkgs/os-specific/linux/kernel/common-config.nix
+++ b/pkgs/os-specific/linux/kernel/common-config.nix
@@ -10,14 +10,14 @@
 # hardware problems with a new one.
 
 # Configuration
-{ stdenv, version
+{ lib, stdenv, version
 
-, features ? { grsecurity = false; }
+, features ? {}
 }:
 
-with stdenv.lib;
-with stdenv.lib.kernel;
-with (stdenv.lib.kernel.whenHelpers version);
+with lib;
+with lib.kernel;
+with (lib.kernel.whenHelpers version);
 
 let
 
@@ -42,7 +42,7 @@ let
       TIMER_STATS               = whenOlder "4.11" yes;
       DEBUG_NX_TEST             = whenOlder "4.11" no;
       DEBUG_STACK_USAGE         = no;
-      DEBUG_STACKOVERFLOW       = mkIf (!features.grsecurity) (option no);
+      DEBUG_STACKOVERFLOW       = option no;
       RCU_TORTURE_TEST          = no;
       SCHEDSTATS                = no;
       DETECT_HUNG_TASK          = yes;
@@ -132,6 +132,7 @@ let
       IP_MROUTE_MULTIPLE_TABLES   = yes;
       IP_MULTICAST                = yes;
       IP_MULTIPLE_TABLES          = yes;
+      IPV6                        = yes;
       IPV6_ROUTER_PREF            = yes;
       IPV6_ROUTE_INFO             = yes;
       IPV6_OPTIMISTIC_DAD         = yes;
@@ -141,6 +142,9 @@ let
       IPV6_MROUTE_MULTIPLE_TABLES = yes;
       IPV6_PIMSM_V2               = yes;
       IPV6_FOU_TUNNEL             = whenAtLeast "4.7" module;
+      IPV6_SEG6_LWTUNNEL          = whenAtLeast "4.10" yes;
+      IPV6_SEG6_HMAC              = whenAtLeast "4.10" yes;
+      IPV6_SEG6_BPF               = whenAtLeast "4.18" yes;
       NET_CLS_BPF                 = whenAtLeast "4.4" module;
       NET_ACT_BPF                 = whenAtLeast "4.4" module;
       NET_SCHED                   = yes;
@@ -173,6 +177,8 @@ let
                                               (whenAtLeast "4.17" yes) ];
       NF_TABLES_NETDEV            = mkMerge [ (whenOlder "4.17" module)
                                               (whenAtLeast "4.17" yes) ];
+      NFT_REJECT_NETDEV           = whenAtLeast "5.11" module;
+
       # IP: Netfilter Configuration
       NF_TABLES_IPV4              = mkMerge [ (whenOlder "4.17" module)
                                               (whenAtLeast "4.17" yes) ];
@@ -190,11 +196,17 @@ let
       NET_DROP_MONITOR = yes;
 
       # needed for ss
-      INET_DIAG         = module;
-      INET_TCP_DIAG     = module;
-      INET_UDP_DIAG     = module;
-      INET_RAW_DIAG     = whenAtLeast "4.14" module;
-      INET_DIAG_DESTROY = whenAtLeast "4.9" yes;
+      # Use a lower priority to allow these options to be overridden in hardened/config.nix
+      INET_DIAG         = mkDefault module;
+      INET_TCP_DIAG     = mkDefault module;
+      INET_UDP_DIAG     = mkDefault module;
+      INET_RAW_DIAG     = whenAtLeast "4.14" (mkDefault module);
+      INET_DIAG_DESTROY = whenAtLeast "4.9" (mkDefault yes);
+
+      # enable multipath-tcp
+      MPTCP           = whenAtLeast "5.6" yes;
+      MPTCP_IPV6      = whenAtLeast "5.6" yes;
+      INET_MPTCP_DIAG = whenAtLeast "5.9" (mkDefault module);
     };
 
     wireless = {
@@ -235,8 +247,9 @@ let
       # Allow specifying custom EDID on the kernel command line
       DRM_LOAD_EDID_FIRMWARE = yes;
       VGA_SWITCHEROO         = yes; # Hybrid graphics support
-      DRM_GMA600             = yes;
-      DRM_GMA3600            = yes;
+      DRM_GMA500             = whenAtLeast "5.12" module;
+      DRM_GMA600             = whenOlder "5.13" yes;
+      DRM_GMA3600            = whenOlder "5.12" yes;
       DRM_VMWGFX_FBCON       = yes;
       # necessary for amdgpu polaris support
       DRM_AMD_POWERPLAY = whenBetween "4.5" "4.9" yes;
@@ -244,6 +257,17 @@ let
       DRM_AMDGPU_SI = whenAtLeast "4.9" yes;
       # (stable) amdgpu support for bonaire and newer chipsets
       DRM_AMDGPU_CIK = whenAtLeast "4.9" yes;
+      # Allow device firmware updates
+      DRM_DP_AUX_CHARDEV = whenAtLeast "4.6" yes;
+      # amdgpu display core (DC) support
+      DRM_AMD_DC_DCN1_0 = whenBetween "4.15" "5.6" yes;
+      DRM_AMD_DC_PRE_VEGA = whenBetween "4.15" "4.18" yes;
+      DRM_AMD_DC_DCN2_0 = whenBetween "5.3" "5.6" yes;
+      DRM_AMD_DC_DCN2_1 = whenBetween "5.4" "5.6" yes;
+      DRM_AMD_DC_DCN3_0 = whenBetween "5.9" "5.11" yes;
+      DRM_AMD_DC_DCN = whenAtLeast "5.11" yes;
+      DRM_AMD_DC_HDCP = whenAtLeast "5.5" yes;
+      DRM_AMD_DC_SI = whenAtLeast "5.10" yes;
     } // optionalAttrs (stdenv.hostPlatform.system == "x86_64-linux") {
       # Intel GVT-g graphics virtualization supports 64-bit only
       DRM_I915_GVT = whenAtLeast "4.16" yes;
@@ -268,21 +292,31 @@ let
       SND_SOC_SOF_TOPLEVEL              = yes;
       SND_SOC_SOF_ACPI                  = module;
       SND_SOC_SOF_PCI                   = module;
-      SND_SOC_SOF_APOLLOLAKE_SUPPORT    = yes;
-      SND_SOC_SOF_CANNONLAKE_SUPPORT    = yes;
-      SND_SOC_SOF_COFFEELAKE_SUPPORT    = yes;
+      SND_SOC_SOF_APOLLOLAKE            = whenAtLeast "5.12" module;
+      SND_SOC_SOF_APOLLOLAKE_SUPPORT    = whenOlder "5.12" yes;
+      SND_SOC_SOF_CANNONLAKE            = whenAtLeast "5.12" module;
+      SND_SOC_SOF_CANNONLAKE_SUPPORT    = whenOlder "5.12" yes;
+      SND_SOC_SOF_COFFEELAKE            = whenAtLeast "5.12" module;
+      SND_SOC_SOF_COFFEELAKE_SUPPORT    = whenOlder "5.12" yes;
+      SND_SOC_SOF_COMETLAKE             = whenAtLeast "5.12" module;
       SND_SOC_SOF_COMETLAKE_H_SUPPORT   = whenOlder "5.8" yes;
-      SND_SOC_SOF_COMETLAKE_LP_SUPPORT  = yes;
-      SND_SOC_SOF_ELKHARTLAKE_SUPPORT   = yes;
-      SND_SOC_SOF_GEMINILAKE_SUPPORT    = yes;
+      SND_SOC_SOF_COMETLAKE_LP_SUPPORT  = whenOlder "5.12" yes;
+      SND_SOC_SOF_ELKHARTLAKE           = whenAtLeast "5.12" module;
+      SND_SOC_SOF_ELKHARTLAKE_SUPPORT   = whenOlder "5.12" yes;
+      SND_SOC_SOF_GEMINILAKE            = whenAtLeast "5.12" module;
+      SND_SOC_SOF_GEMINILAKE_SUPPORT    = whenOlder "5.12" yes;
       SND_SOC_SOF_HDA_AUDIO_CODEC       = yes;
       SND_SOC_SOF_HDA_COMMON_HDMI_CODEC = whenOlder "5.7" yes;
       SND_SOC_SOF_HDA_LINK              = yes;
-      SND_SOC_SOF_ICELAKE_SUPPORT       = yes;
+      SND_SOC_SOF_ICELAKE               = whenAtLeast "5.12" module;
+      SND_SOC_SOF_ICELAKE_SUPPORT       = whenOlder "5.12" yes;
       SND_SOC_SOF_INTEL_TOPLEVEL        = yes;
-      SND_SOC_SOF_JASPERLAKE_SUPPORT    = yes;
-      SND_SOC_SOF_MERRIFIELD_SUPPORT    = yes;
-      SND_SOC_SOF_TIGERLAKE_SUPPORT     = yes;
+      SND_SOC_SOF_JASPERLAKE            = whenAtLeast "5.12" module;
+      SND_SOC_SOF_JASPERLAKE_SUPPORT    = whenOlder "5.12" yes;
+      SND_SOC_SOF_MERRIFIELD            = whenAtLeast "5.12" module;
+      SND_SOC_SOF_MERRIFIELD_SUPPORT    = whenOlder "5.12" yes;
+      SND_SOC_SOF_TIGERLAKE             = whenAtLeast "5.12" module;
+      SND_SOC_SOF_TIGERLAKE_SUPPORT     = whenOlder "5.12" yes;
     };
 
     usb-serial = {
@@ -350,6 +384,7 @@ let
       F2FS_FS             = module;
       F2FS_FS_SECURITY    = option yes;
       F2FS_FS_ENCRYPTION  = option yes;
+      F2FS_FS_COMPRESSION = whenAtLeast "5.6" yes;
       UDF_FS              = module;
 
       NFSD_PNFS              = whenBetween "4.0" "4.6" yes;
@@ -396,6 +431,8 @@ let
       NLS_ISO8859_1    = module; # VFAT default for the iocharset= mount option
 
       DEVTMPFS = yes;
+
+      UNICODE = whenAtLeast "5.2" yes; # Casefolding support for filesystems
     };
 
     security = {
@@ -406,14 +443,19 @@ let
       SECURITY_SELINUX_BOOTPARAM_VALUE = whenOlder "5.1" (freeform "0"); # Disable SELinux by default
       # Prevent processes from ptracing non-children processes
       SECURITY_YAMA                    = option yes;
-      DEVKMEM                          = mkIf (!features.grsecurity) no; # Disable /dev/kmem
+      DEVKMEM                          = whenOlder "5.13" no; # Disable /dev/kmem
 
       USER_NS                          = yes; # Support for user namespaces
 
       SECURITY_APPARMOR                = yes;
       DEFAULT_SECURITY_APPARMOR        = yes;
 
-      SECURITY_LOCKDOWN_LSM            = whenAtLeast "5.4" yes;
+      RANDOM_TRUST_CPU                 = whenAtLeast "4.19" yes; # allow RDRAND to seed the RNG
+
+      MODULE_SIG            = no; # r13y, generates a random key during build and bakes it in
+      # Depends on MODULE_SIG and only really helps when you sign your modules
+      # and enforce signatures which we don't do by default.
+      SECURITY_LOCKDOWN_LSM = option no;
     } // optionalAttrs (!stdenv.hostPlatform.isAarch32) {
 
       # Detect buffer overflows on the stack
@@ -481,7 +523,7 @@ let
     virtualisation = {
       PARAVIRT = option yes;
 
-      HYPERVISOR_GUEST = mkIf (!features.grsecurity) yes;
+      HYPERVISOR_GUEST = yes;
       PARAVIRT_SPINLOCKS  = option yes;
 
       KVM_APIC_ARCHITECTURE             = whenOlder "4.8" yes;
@@ -489,12 +531,12 @@ let
       KVM_COMPAT = { optional = true; tristate = whenBetween "4.0" "4.12" "y"; };
       KVM_DEVICE_ASSIGNMENT  = { optional = true; tristate = whenBetween "3.10" "4.12" "y"; };
       KVM_GENERIC_DIRTYLOG_READ_PROTECT = whenAtLeast "4.0"  yes;
-      KVM_GUEST                         = mkIf (!features.grsecurity) yes;
+      KVM_GUEST                         = yes;
       KVM_MMIO                          = yes;
       KVM_VFIO                          = yes;
       KSM = yes;
       VIRT_DRIVERS = yes;
-      # We nneed 64 GB (PAE) support for Xen guest support
+      # We need 64 GB (PAE) support for Xen guest support
       HIGHMEM64G = { optional = true; tristate = mkIf (!stdenv.is64bit) "y";};
 
       VFIO_PCI_VGA = mkIf stdenv.is64bit yes;
@@ -618,7 +660,12 @@ let
       XZ_DEC_TEST              = option no;
     };
 
-    criu = optionalAttrs (features.criu or false) ({
+    criu = if (versionAtLeast version "4.19") then {
+      # Unconditionally enabled, because it is required for CRIU and
+      # it provides the kcmp() system call that Mesa depends on.
+      CHECKPOINT_RESTORE  = yes;
+    } else optionalAttrs (features.criu or false) ({
+      # For older kernels, CHECKPOINT_RESTORE is hidden behind EXPERT.
       EXPERT              = yes;
       CHECKPOINT_RESTORE  = yes;
     } // optionalAttrs (features.criu_revert_expert or true) {
@@ -631,7 +678,14 @@ let
       DEBUG_MEMORY_INIT     = option yes;
     });
 
-    misc = {
+    misc = let
+      # Use zstd for kernel compression if 64-bit and newer than 5.9, otherwise xz.
+      # i686 issues: https://github.com/NixOS/nixpkgs/pull/117961#issuecomment-812106375
+      useZstd = stdenv.buildPlatform.is64bit && versionAtLeast version "5.9";
+    in {
+      KERNEL_XZ            = mkIf (!useZstd) yes;
+      KERNEL_ZSTD          = mkIf useZstd yes;
+
       HID_BATTERY_STRENGTH = yes;
       # enabled by default in x86_64 but not arm64, so we do that here
       HIDRAW               = yes;
@@ -644,9 +698,8 @@ let
       THRUSTMASTER_FF    = yes;
       ZEROPLUS_FF        = yes;
 
-      MODULE_COMPRESS    = yes;
+      MODULE_COMPRESS    = whenOlder "5.13" yes;
       MODULE_COMPRESS_XZ = yes;
-      KERNEL_XZ          = yes;
 
       SYSVIPC            = yes;  # System-V IPC
 
@@ -657,7 +710,6 @@ let
       MD                 = yes;     # Device mapper (RAID, LVM, etc.)
 
       # Enable initrd support.
-      BLK_DEV_RAM       = yes;
       BLK_DEV_INITRD    = yes;
 
       PM_TRACE_RTC         = no; # Disable some expensive (?) features.
@@ -731,6 +783,8 @@ let
       MLX4_EN_VXLAN = whenOlder "4.8" yes;
       MLX5_CORE_EN       = option yes;
 
+      NVME_MULTIPATH = whenAtLeast "4.15" yes;
+
       PSI = whenAtLeast "4.20" yes;
 
       MODVERSIONS        = whenOlder "4.9" yes;
@@ -767,6 +821,8 @@ let
       X86_CHECK_BIOS_CORRUPTION = yes;
       X86_MCE                   = yes;
 
+      RAS = yes; # Needed for EDAC support
+
       # Our initrd init uses shebang scripts, so can't be modular.
       BINFMT_SCRIPT = yes;
       # For systemd-binfmt
@@ -788,6 +844,7 @@ let
       PREEMPT_VOLUNTARY = yes;
 
       X86_AMD_PLATFORM_DEVICE = yes;
+      X86_PLATFORM_DRIVERS_DELL = whenAtLeast "5.12" yes;
 
     } // optionalAttrs (stdenv.hostPlatform.system == "x86_64-linux" || stdenv.hostPlatform.system == "aarch64-linux") {
       # Enable CPU/memory hotplug support
@@ -803,12 +860,26 @@ let
       # Bump the maximum number of CPUs to support systems like EC2 x1.*
       # instances and Xeon Phi.
       NR_CPUS = freeform "384";
-    } // optionalAttrs (stdenv.hostPlatform.system == "aarch64-linux") {
+    } // optionalAttrs (stdenv.hostPlatform.system == "armv7l-linux" || stdenv.hostPlatform.system == "aarch64-linux") {
       # Enables support for the Allwinner Display Engine 2.0
       SUN8I_DE2_CCU = whenAtLeast "4.13" yes;
 
       # See comments on https://github.com/NixOS/nixpkgs/commit/9b67ea9106102d882f53d62890468071900b9647
       CRYPTO_AEGIS128_SIMD = whenAtLeast "5.4" no;
+
+      # Distros should configure the default as a kernel option.
+      # We previously defined it on the kernel command line as cma=
+      # The kernel command line will override a platform-specific configuration from its device tree.
+      # https://github.com/torvalds/linux/blob/856deb866d16e29bd65952e0289066f6078af773/kernel/dma/contiguous.c#L35-L44
+      CMA_SIZE_MBYTES = freeform "32";
+
+      # Many ARM SBCs hand off a pre-configured framebuffer.
+      # This always can can be replaced by the actual native driver.
+      # Keeping it a built-in ensures it will be used if possible.
+      FB_SIMPLE = yes;
+
+    } // optionalAttrs (stdenv.hostPlatform.system == "armv7l-linux") {
+      ARM_LPAE = yes;
     };
   };
 in
diff --git a/pkgs/os-specific/linux/kernel/export-rt-sched-migrate.patch b/pkgs/os-specific/linux/kernel/export-rt-sched-migrate.patch
new file mode 100644
index 00000000000..1d8ed6f712c
--- /dev/null
+++ b/pkgs/os-specific/linux/kernel/export-rt-sched-migrate.patch
@@ -0,0 +1,11 @@
+Export linux-rt (PREEMPT_RT) specific symbols needed by ZFS.
+(Regular kernel provides them static inline in linux/preempt.h.)
+
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -1812 +1812 @@ void migrate_disable(void)
+-EXPORT_SYMBOL_GPL(migrate_disable);
++EXPORT_SYMBOL(migrate_disable);
+@@ -1843 +1843 @@ void migrate_enable(void)
+-EXPORT_SYMBOL_GPL(migrate_enable);
++EXPORT_SYMBOL(migrate_enable);
diff --git a/pkgs/os-specific/linux/kernel/generate-config.pl b/pkgs/os-specific/linux/kernel/generate-config.pl
index 26c559ea908..df807188f14 100644
--- a/pkgs/os-specific/linux/kernel/generate-config.pl
+++ b/pkgs/os-specific/linux/kernel/generate-config.pl
@@ -19,6 +19,7 @@ my $autoModules = $ENV{'AUTO_MODULES'};
 my $preferBuiltin = $ENV{'PREFER_BUILTIN'};
 my $ignoreConfigErrors = $ENV{'ignoreConfigErrors'};
 my $buildRoot = $ENV{'BUILD_ROOT'};
+my $makeFlags = $ENV{'MAKE_FLAGS'};
 $SIG{PIPE} = 'IGNORE';
 
 # Read the answers.
@@ -40,7 +41,7 @@ close ANSWERS;
 sub runConfig {
 
     # Run `make config'.
-    my $pid = open2(\*IN, \*OUT, "make -C $ENV{SRC} O=$buildRoot config SHELL=bash ARCH=$ENV{ARCH}");
+    my $pid = open2(\*IN, \*OUT, "make -C $ENV{SRC} O=$buildRoot config SHELL=bash ARCH=$ENV{ARCH} CC=$ENV{CC} HOSTCC=$ENV{HOSTCC} HOSTCXX=$ENV{HOSTCXX} $makeFlags");
 
     # Parse the output, look for questions and then send an
     # appropriate answer.
@@ -61,6 +62,12 @@ sub runConfig {
             # Remember choice alternatives ("> 1. bla (FOO)" or " 2. bla (BAR) (NEW)").
             if ($line =~ /^\s*>?\s*(\d+)\.\s+.*?\(([A-Za-z0-9_]+)\)(?:\s+\(NEW\))?\s*$/) {
                 $choices{$2} = $1;
+            } else {
+                # The list of choices has ended without us being
+                # asked. This happens for options where only one value
+                # is valid, for instance. The results can foul up
+                # later options, so forget about it.
+                %choices = ();
             }
 
             $line = "";
diff --git a/pkgs/os-specific/linux/kernel/generic.nix b/pkgs/os-specific/linux/kernel/generic.nix
index cab11cc87ae..7f4f0f2d6bb 100644
--- a/pkgs/os-specific/linux/kernel/generic.nix
+++ b/pkgs/os-specific/linux/kernel/generic.nix
@@ -6,6 +6,7 @@
 , gmp ? null
 , libmpc ? null
 , mpfr ? null
+, lib
 , stdenv
 
 , # The kernel source tarball.
@@ -20,6 +21,9 @@
 , # Legacy overrides to the intermediate kernel config, as string
   extraConfig ? ""
 
+  # Additional make flags passed to kbuild
+, extraMakeFlags ? []
+
 , # kernel intermediate config overrides, as a set
  structuredExtraConfig ? {}
 
@@ -41,15 +45,19 @@
   # symbolic name and `patch' is the actual patch.  The patch may
   # optionally be compressed with gzip or bzip2.
   kernelPatches ? []
-, ignoreConfigErrors ? stdenv.hostPlatform.platform.name != "pc" ||
+, ignoreConfigErrors ? stdenv.hostPlatform.linux-kernel.name != "pc" ||
                        stdenv.hostPlatform != stdenv.buildPlatform
 , extraMeta ? {}
 
-# easy overrides to stdenv.hostPlatform.platform members
-, autoModules ? stdenv.hostPlatform.platform.kernelAutoModules
-, preferBuiltin ? stdenv.hostPlatform.platform.kernelPreferBuiltin or false
-, kernelArch ? stdenv.hostPlatform.platform.kernelArch
+, isZen      ? false
+, isLibre    ? false
+, isHardened ? false
 
+# easy overrides to stdenv.hostPlatform.linux-kernel members
+, autoModules ? stdenv.hostPlatform.linux-kernel.autoModules
+, preferBuiltin ? stdenv.hostPlatform.linux-kernel.preferBuiltin or false
+, kernelArch ? stdenv.hostPlatform.linuxArch
+, kernelTests ? []
 , ...
 }:
 
@@ -61,22 +69,17 @@
 assert stdenv.isLinux;
 
 let
-
-  lib = stdenv.lib;
-
   # Combine the `features' attribute sets of all the kernel patches.
-  kernelFeatures = lib.fold (x: y: (x.features or {}) // y) ({
+  kernelFeatures = lib.foldr (x: y: (x.features or {}) // y) ({
     iwlwifi = true;
     efiBootStub = true;
     needsCifsUtils = true;
     netfilterRPFilter = true;
-    grsecurity = false;
-    xen_dom0 = false;
     ia32Emulation = true;
   } // features) kernelPatches;
 
   commonStructuredConfig = import ./common-config.nix {
-    inherit stdenv version ;
+    inherit lib stdenv version;
 
     features = kernelFeatures; # Ensure we know of all extra patches, etc.
   };
@@ -84,7 +87,7 @@ let
   intermediateNixConfig = configfile.moduleStructuredConfig.intermediateNixConfig
     # extra config in legacy string format
     + extraConfig
-    + lib.optionalString (stdenv.hostPlatform.platform ? kernelExtraConfig) stdenv.hostPlatform.platform.kernelExtraConfig;
+    + stdenv.hostPlatform.linux-kernel.extraConfig or "";
 
   structuredConfigFromPatches =
         map ({extraStructuredConfig ? {}, ...}: {settings=extraStructuredConfig;}) kernelPatches;
@@ -97,7 +100,7 @@ let
     in lib.concatStringsSep "\n" ([baseConfigStr] ++ configFromPatches);
 
   configfile = stdenv.mkDerivation {
-    inherit ignoreConfigErrors autoModules preferBuiltin kernelArch;
+    inherit ignoreConfigErrors autoModules preferBuiltin kernelArch extraMakeFlags;
     pname = "linux-config";
     inherit version;
 
@@ -108,13 +111,16 @@ let
 
     depsBuildBuild = [ buildPackages.stdenv.cc ];
     nativeBuildInputs = [ perl gmp libmpc mpfr ]
-      ++ lib.optionals (stdenv.lib.versionAtLeast version "4.16") [ bison flex ];
+      ++ lib.optionals (lib.versionAtLeast version "4.16") [ bison flex ];
 
-    platformName = stdenv.hostPlatform.platform.name;
+    platformName = stdenv.hostPlatform.linux-kernel.name;
     # e.g. "defconfig"
-    kernelBaseConfig = if defconfig != null then defconfig else stdenv.hostPlatform.platform.kernelBaseConfig;
+    kernelBaseConfig = if defconfig != null then defconfig else stdenv.hostPlatform.linux-kernel.baseConfig;
     # e.g. "bzImage"
-    kernelTarget = stdenv.hostPlatform.platform.kernelTarget;
+    kernelTarget = stdenv.hostPlatform.linux-kernel.target;
+
+    makeFlags = lib.optionals (stdenv.hostPlatform.linux-kernel ? makeFlags) stdenv.hostPlatform.linux-kernel.makeFlags
+      ++ extraMakeFlags;
 
     prePatch = kernel.prePatch + ''
       # Patch kconfig to print "###" after every question so that
@@ -128,18 +134,25 @@ let
 
     buildPhase = ''
       export buildRoot="''${buildRoot:-build}"
+      export HOSTCC=$CC_FOR_BUILD
+      export HOSTCXX=$CXX_FOR_BUILD
+      export HOSTAR=$AR_FOR_BUILD
+      export HOSTLD=$LD_FOR_BUILD
 
       # Get a basic config file for later refinement with $generateConfig.
-      make -C .  O="$buildRoot" $kernelBaseConfig \
+      make $makeFlags \
+          -C . O="$buildRoot" $kernelBaseConfig \
           ARCH=$kernelArch \
-          HOSTCC=${buildPackages.stdenv.cc.targetPrefix}gcc \
-          HOSTCXX=${buildPackages.stdenv.cc.targetPrefix}g++
+          HOSTCC=$HOSTCC HOSTCXX=$HOSTCXX HOSTAR=$HOSTAR HOSTLD=$HOSTLD \
+          CC=$CC OBJCOPY=$OBJCOPY OBJDUMP=$OBJDUMP READELF=$READELF \
+          $makeFlags
 
       # Create the config file.
       echo "generating kernel configuration..."
       ln -s "$kernelConfigPath" "$buildRoot/kernel-config"
       DEBUG=1 ARCH=$kernelArch KERNEL_CONFIG="$buildRoot/kernel-config" AUTO_MODULES=$autoModules \
-           PREFER_BUILTIN=$preferBuiltin BUILD_ROOT="$buildRoot" SRC=. perl -w $generateConfig
+        PREFER_BUILTIN=$preferBuiltin BUILD_ROOT="$buildRoot" SRC=. MAKE_FLAGS="$makeFlags" \
+        perl -w $generateConfig
     '';
 
     installPhase = "mv $buildRoot/.config $out";
@@ -147,7 +160,6 @@ let
     enableParallelBuilding = true;
 
     passthru = rec {
-
       module = import ../../../../nixos/modules/system/boot/kernel_config.nix;
       # used also in apache
       # { modules = [ { options = res.options; config = svc.config or svc; } ];
@@ -167,16 +179,20 @@ let
     };
   }; # end of configfile derivation
 
-  kernel = (callPackage ./manual-config.nix {}) {
-    inherit version modDirVersion src kernelPatches randstructSeed stdenv extraMeta configfile;
+  kernel = (callPackage ./manual-config.nix { inherit buildPackages;  }) {
+    inherit version modDirVersion src kernelPatches randstructSeed lib stdenv extraMakeFlags extraMeta configfile;
 
     config = { CONFIG_MODULES = "y"; CONFIG_FW_LOADER = "m"; };
   };
 
   passthru = {
     features = kernelFeatures;
-    inherit commonStructuredConfig;
+    inherit commonStructuredConfig structuredExtraConfig extraMakeFlags isZen isHardened isLibre modDirVersion;
+    isXen = lib.warn "The isXen attribute is deprecated. All Nixpkgs kernels that support it now have Xen enabled." true;
+    kernelOlder = lib.versionOlder version;
+    kernelAtLeast = lib.versionAtLeast version;
     passthru = kernel.passthru // (removeAttrs passthru [ "passthru" ]);
+    tests = kernelTests;
   };
 
 in lib.extendDerivation true passthru kernel
diff --git a/pkgs/os-specific/linux/kernel/hardened/config.nix b/pkgs/os-specific/linux/kernel/hardened/config.nix
index c817f104427..20f9f5aaa14 100644
--- a/pkgs/os-specific/linux/kernel/hardened/config.nix
+++ b/pkgs/os-specific/linux/kernel/hardened/config.nix
@@ -8,11 +8,11 @@
 #
 # See also <nixos/modules/profiles/hardened.nix>
 
-{ stdenv, version }:
+{ lib, version }:
 
-with stdenv.lib;
-with stdenv.lib.kernel;
-with (stdenv.lib.kernel.whenHelpers version);
+with lib;
+with lib.kernel;
+with (lib.kernel.whenHelpers version);
 
 assert (versionAtLeast version "4.9");
 
@@ -55,8 +55,8 @@ assert (versionAtLeast version "4.9");
 
   # Wipe higher-level memory allocations on free() with page_poison=1
   PAGE_POISONING           = yes;
-  PAGE_POISONING_NO_SANITY = yes;
-  PAGE_POISONING_ZERO      = yes;
+  PAGE_POISONING_NO_SANITY = whenOlder "5.11" yes;
+  PAGE_POISONING_ZERO      = whenOlder "5.11" yes;
 
   # Enable the SafeSetId LSM
   SECURITY_SAFESETID = whenAtLeast "5.1" yes;
@@ -65,7 +65,7 @@ assert (versionAtLeast version "4.9");
   PANIC_TIMEOUT = freeform "-1";
 
   GCC_PLUGINS = yes; # Enable gcc plugin options
-  # Gather additional entropy at boot time for systems that may = no;ot have appropriate entropy sources.
+  # Gather additional entropy at boot time for systems that may not have appropriate entropy sources.
   GCC_PLUGIN_LATENT_ENTROPY = yes;
 
   GCC_PLUGIN_STRUCTLEAK = whenAtLeast "4.11" yes; # A port of the PaX structleak plugin
@@ -79,8 +79,18 @@ assert (versionAtLeast version "4.9");
   PROC_KCORE         = no; # Exposes kernel text image layout
   INET_DIAG          = no; # Has been used for heap based attacks in the past
 
+  # INET_DIAG=n causes the following options to not exist anymore, but since they are defined in common-config.nix,
+  # make them optional
+  INET_DIAG_DESTROY = option no;
+  INET_RAW_DIAG     = option no;
+  INET_TCP_DIAG     = option no;
+  INET_UDP_DIAG     = option no;
+  INET_MPTCP_DIAG   = option no;
+
   # Use -fstack-protector-strong (gcc 4.9+) for best stack canary coverage.
   CC_STACKPROTECTOR_REGULAR = whenOlder "4.18" no;
   CC_STACKPROTECTOR_STRONG  = whenOlder "4.18" yes;
 
+  # Detect out-of-bound reads/writes and use-after-free
+  KFENCE = whenAtLeast "5.12" yes;
 }
diff --git a/pkgs/os-specific/linux/kernel/hardened/patches.json b/pkgs/os-specific/linux/kernel/hardened/patches.json
index 824eb1a6966..412e5041500 100644
--- a/pkgs/os-specific/linux/kernel/hardened/patches.json
+++ b/pkgs/os-specific/linux/kernel/hardened/patches.json
@@ -1,22 +1,32 @@
 {
     "4.14": {
-        "name": "linux-hardened-4.14.194.a.patch",
-        "sha256": "07z3lr3mbm6c95d7fra2qp071n1c45f9241cl19zs63g00avi11p",
-        "url": "https://github.com/anthraxx/linux-hardened/releases/download/4.14.194.a/linux-hardened-4.14.194.a.patch"
+        "extra": "-hardened1",
+        "name": "linux-hardened-4.14.240-hardened1.patch",
+        "sha256": "0j5zp0f8s4w3f60yam2spg3bx56bdjvv0mh632zlhchz8rdk5zs4",
+        "url": "https://github.com/anthraxx/linux-hardened/releases/download/4.14.240-hardened1/linux-hardened-4.14.240-hardened1.patch"
     },
     "4.19": {
-        "name": "linux-hardened-4.19.141.a.patch",
-        "sha256": "0yiqkkp17pf9r6nakpnqhvmf8awpzp5n27cmh15ril7vn1y71sxw",
-        "url": "https://github.com/anthraxx/linux-hardened/releases/download/4.19.141.a/linux-hardened-4.19.141.a.patch"
+        "extra": "-hardened1",
+        "name": "linux-hardened-4.19.198-hardened1.patch",
+        "sha256": "18c5j00xiwc0xn5klcrwazk6wvjiy3cixbfbrw4xj7zal9r5p6q9",
+        "url": "https://github.com/anthraxx/linux-hardened/releases/download/4.19.198-hardened1/linux-hardened-4.19.198-hardened1.patch"
     },
-    "5.4": {
-        "name": "linux-hardened-5.4.60.a.patch",
-        "sha256": "138kms73rlj5zmsb2ivjzz1jr5aa8y8pmwzx02c7j1qk08v82823",
-        "url": "https://github.com/anthraxx/linux-hardened/releases/download/5.4.60.a/linux-hardened-5.4.60.a.patch"
+    "5.10": {
+        "extra": "-hardened1",
+        "name": "linux-hardened-5.10.52-hardened1.patch",
+        "sha256": "062a32rb1g5xk1npiz9fa114k7g4x9pmygycn3alc0phngjmvr98",
+        "url": "https://github.com/anthraxx/linux-hardened/releases/download/5.10.52-hardened1/linux-hardened-5.10.52-hardened1.patch"
+    },
+    "5.12": {
+        "extra": "-hardened1",
+        "name": "linux-hardened-5.12.19-hardened1.patch",
+        "sha256": "1nr3922gd6il69k5cpp9g3knpy6yjb6jsmpi9k4v02bkvypg86dc",
+        "url": "https://github.com/anthraxx/linux-hardened/releases/download/5.12.19-hardened1/linux-hardened-5.12.19-hardened1.patch"
     },
-    "5.7": {
-        "name": "linux-hardened-5.7.17.a.patch",
-        "sha256": "181b473y0hkw076hsndw6nfynr2yhcaypj48iqnk25hzcj40nnaz",
-        "url": "https://github.com/anthraxx/linux-hardened/releases/download/5.7.17.a/linux-hardened-5.7.17.a.patch"
+    "5.4": {
+        "extra": "-hardened1",
+        "name": "linux-hardened-5.4.134-hardened1.patch",
+        "sha256": "0iay6dxwd1vqj02ljf0ghncrqpr6b0gby90xiza8kkk8wnh3r9hh",
+        "url": "https://github.com/anthraxx/linux-hardened/releases/download/5.4.134-hardened1/linux-hardened-5.4.134-hardened1.patch"
     }
 }
diff --git a/pkgs/os-specific/linux/kernel/hardened/tag-hardened.patch b/pkgs/os-specific/linux/kernel/hardened/tag-hardened.patch
deleted file mode 100644
index ff8a3a12797..00000000000
--- a/pkgs/os-specific/linux/kernel/hardened/tag-hardened.patch
+++ /dev/null
@@ -1,7 +0,0 @@
-diff --git a/localversion-hardened b/localversion-hardened
-new file mode 100644
-index 0000000000..e578045860
---- /dev/null
-+++ b/localversion-hardened
-@@ -0,0 +1 @@
-+-hardened
diff --git a/pkgs/os-specific/linux/kernel/hardened/update.py b/pkgs/os-specific/linux/kernel/hardened/update.py
index d6443d2e751..e96ac9ca855 100755
--- a/pkgs/os-specific/linux/kernel/hardened/update.py
+++ b/pkgs/os-specific/linux/kernel/hardened/update.py
@@ -31,7 +31,7 @@ VersionComponent = Union[int, str]
 Version = List[VersionComponent]
 
 
-Patch = TypedDict("Patch", {"name": str, "url": str, "sha256": str})
+Patch = TypedDict("Patch", {"name": str, "url": str, "sha256": str, "extra": str})
 
 
 @dataclass
@@ -99,7 +99,10 @@ def verify_openpgp_signature(
             return False
 
 
-def fetch_patch(*, name: str, release: GitRelease) -> Optional[Patch]:
+def fetch_patch(*, name: str, release_info: ReleaseInfo) -> Optional[Patch]:
+    release = release_info.release
+    extra = f'-{release_info.version[-1]}'
+
     def find_asset(filename: str) -> str:
         try:
             it: Iterator[str] = (
@@ -130,12 +133,12 @@ def fetch_patch(*, name: str, release: GitRelease) -> Optional[Patch]:
     if not sig_ok:
         return None
 
-    return Patch(name=patch_filename, url=patch_url, sha256=sha256)
+    return Patch(name=patch_filename, url=patch_url, sha256=sha256, extra=extra)
 
 
 def parse_version(version_str: str) -> Version:
     version: Version = []
-    for component in version_str.split("."):
+    for component in re.split('\.|\-', version_str):
         try:
             version.append(int(component))
         except ValueError:
@@ -205,7 +208,7 @@ failures = False
 releases = {}
 for release in repo.get_releases():
     version = parse_version(release.tag_name)
-    # needs to look like e.g. 5.6.3.a
+    # needs to look like e.g. 5.6.3-hardened1
     if len(version) < 4:
         continue
 
@@ -252,7 +255,7 @@ for kernel_key in sorted(releases.keys()):
         update = True
 
     if update:
-        patch = fetch_patch(name=name, release=release)
+        patch = fetch_patch(name=name, release_info=release_info)
         if patch is None:
             failures = True
         else:
diff --git a/pkgs/os-specific/linux/kernel/linux-4.14.nix b/pkgs/os-specific/linux/kernel/linux-4.14.nix
index 4807ff7dba4..ccecc433a4a 100644
--- a/pkgs/os-specific/linux/kernel/linux-4.14.nix
+++ b/pkgs/os-specific/linux/kernel/linux-4.14.nix
@@ -1,9 +1,9 @@
-{ stdenv, buildPackages, fetchurl, perl, buildLinux, modDirVersionArg ? null, ... } @ args:
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
 
-with stdenv.lib;
+with lib;
 
 buildLinux (args // rec {
-  version = "4.14.194";
+  version = "4.14.240";
 
   # 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;
@@ -13,6 +13,8 @@ buildLinux (args // rec {
 
   src = fetchurl {
     url = "mirror://kernel/linux/kernel/v4.x/linux-${version}.tar.xz";
-    sha256 = "1q7ssi2790bqjn8s8ra5ihma70hmxykahink7iq5h78738id191y";
+    sha256 = "1k65qwzlnqnh9ym0n2fxpa8nk2qwvykwhwgaixk3b7ndzmr8b6c8";
   };
+
+  kernelTests = args.kernelTests or [ nixosTests.kernel-generic.linux_4_14 ];
 } // (args.argsOverride or {}))
diff --git a/pkgs/os-specific/linux/kernel/linux-4.19.nix b/pkgs/os-specific/linux/kernel/linux-4.19.nix
index e0c9c69061a..4ed06ee2205 100644
--- a/pkgs/os-specific/linux/kernel/linux-4.19.nix
+++ b/pkgs/os-specific/linux/kernel/linux-4.19.nix
@@ -1,9 +1,9 @@
-{ stdenv, buildPackages, fetchurl, perl, buildLinux, modDirVersionArg ? null, ... } @ args:
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
 
-with stdenv.lib;
+with lib;
 
 buildLinux (args // rec {
-  version = "4.19.141";
+  version = "4.19.198";
 
   # 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;
@@ -13,6 +13,8 @@ buildLinux (args // rec {
 
   src = fetchurl {
     url = "mirror://kernel/linux/kernel/v4.x/linux-${version}.tar.xz";
-    sha256 = "0511vb9rfpy5l6cz69v0v97rw2rk2pscc4hkz2pfmgikagm1shm4";
+    sha256 = "13k0r6a4n8nbni64a18wqzy0pg4vn1zw2li78xrm78rqcrnah85y";
   };
+
+  kernelTests = args.kernelTests or [ nixosTests.kernel-generic.linux_4_19 ];
 } // (args.argsOverride or {}))
diff --git a/pkgs/os-specific/linux/kernel/linux-4.4.nix b/pkgs/os-specific/linux/kernel/linux-4.4.nix
index 033599900ff..6c2595386e0 100644
--- a/pkgs/os-specific/linux/kernel/linux-4.4.nix
+++ b/pkgs/os-specific/linux/kernel/linux-4.4.nix
@@ -1,11 +1,14 @@
-{ stdenv, buildPackages, fetchurl, perl, buildLinux, ... } @ args:
+{ buildPackages, fetchurl, perl, buildLinux, nixosTests, stdenv, ... } @ args:
 
 buildLinux (args // rec {
-  version = "4.4.233";
+  version = "4.4.276";
   extraMeta.branch = "4.4";
+  extraMeta.broken = stdenv.isAarch64;
 
   src = fetchurl {
     url = "mirror://kernel/linux/kernel/v4.x/linux-${version}.tar.xz";
-    sha256 = "1z77dikgkvkp9ggwxp07hl8vxsf9kq57rhfdpbvhny1x13fqkrlp";
+    sha256 = "1hf9h5kr1ws2lvinzq6cv7aps8af1kx4q8j4bsk2vv4i2zvmfr7y";
   };
+
+  kernelTests = args.kernelTests or [ nixosTests.kernel-generic.linux_4_4 ];
 } // (args.argsOverride or {}))
diff --git a/pkgs/os-specific/linux/kernel/linux-4.9.nix b/pkgs/os-specific/linux/kernel/linux-4.9.nix
index c1da330e4ae..0dc5cfeae6e 100644
--- a/pkgs/os-specific/linux/kernel/linux-4.9.nix
+++ b/pkgs/os-specific/linux/kernel/linux-4.9.nix
@@ -1,11 +1,14 @@
-{ stdenv, buildPackages, fetchurl, perl, buildLinux, ... } @ args:
+{ buildPackages, fetchurl, perl, buildLinux, nixosTests, stdenv, ... } @ args:
 
 buildLinux (args // rec {
-  version = "4.9.233";
+  version = "4.9.276";
   extraMeta.branch = "4.9";
+  extraMeta.broken = stdenv.isAarch64;
 
   src = fetchurl {
     url = "mirror://kernel/linux/kernel/v4.x/linux-${version}.tar.xz";
-    sha256 = "19dcwylhy5iqq3dmppqf7s9wy9d16m103djn1n183c9acnqclv9a";
+    sha256 = "16jp05jhmqcp8lawqga69gxn1acdkxsskn3a6wf0635863fky3hv";
   };
+
+  kernelTests = args.kernelTests or [ nixosTests.kernel-generic.linux_4_9 ];
 } // (args.argsOverride or {}))
diff --git a/pkgs/os-specific/linux/kernel/linux-5.7.nix b/pkgs/os-specific/linux/kernel/linux-5.10.nix
index 8583b3b1628..f59cca3e12f 100644
--- a/pkgs/os-specific/linux/kernel/linux-5.7.nix
+++ b/pkgs/os-specific/linux/kernel/linux-5.10.nix
@@ -1,9 +1,9 @@
-{ stdenv, buildPackages, fetchurl, perl, buildLinux, modDirVersionArg ? null, ... } @ args:
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
 
-with stdenv.lib;
+with lib;
 
 buildLinux (args // rec {
-  version = "5.7.17";
+  version = "5.10.52";
 
   # 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;
@@ -13,6 +13,8 @@ buildLinux (args // rec {
 
   src = fetchurl {
     url = "mirror://kernel/linux/kernel/v5.x/linux-${version}.tar.xz";
-    sha256 = "09ajavdyvr0025rwvwfp9yv2z8q779nan1i6dck2kkdxr48kd36c";
+    sha256 = "0ydf09wsg0pkjm9dk8y730ksg15p5rlbhq445zx8k191zah5g7kn";
   };
+
+  kernelTests = args.kernelTests or [ nixosTests.kernel-generic.linux_5_10 ];
 } // (args.argsOverride or {}))
diff --git a/pkgs/os-specific/linux/kernel/linux-5.8.nix b/pkgs/os-specific/linux/kernel/linux-5.12.nix
index 44ce98ce65e..e1e7aec2ce2 100644
--- a/pkgs/os-specific/linux/kernel/linux-5.8.nix
+++ b/pkgs/os-specific/linux/kernel/linux-5.12.nix
@@ -1,9 +1,9 @@
-{ stdenv, buildPackages, fetchurl, perl, buildLinux, modDirVersionArg ? null, ... } @ args:
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
 
-with stdenv.lib;
+with lib;
 
 buildLinux (args // rec {
-  version = "5.8.3";
+  version = "5.12.19";
 
   # 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;
@@ -13,6 +13,8 @@ buildLinux (args // rec {
 
   src = fetchurl {
     url = "mirror://kernel/linux/kernel/v5.x/linux-${version}.tar.xz";
-    sha256 = "0y8prifvkywqsx5lk80bh31m505vinmicpvdrirgg0c9scg7x8lf";
+    sha256 = "0wscz736n13m833cd12lskn47r0b8ki4fhgpjnwga0jsab9iqf79";
   };
+
+  kernelTests = args.kernelTests or [ nixosTests.kernel-generic.linux_5_12 ];
 } // (args.argsOverride or {}))
diff --git a/pkgs/os-specific/linux/kernel/linux-5.13.nix b/pkgs/os-specific/linux/kernel/linux-5.13.nix
new file mode 100644
index 00000000000..dd97944de78
--- /dev/null
+++ b/pkgs/os-specific/linux/kernel/linux-5.13.nix
@@ -0,0 +1,21 @@
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
+
+with lib;
+
+buildLinux (args // rec {
+  version = "5.13.5";
+
+  # 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;
+
+  # branchVersion needs to be x.y
+  extraMeta.branch = versions.majorMinor version;
+
+  src = fetchurl {
+    url = "mirror://kernel/linux/kernel/v5.x/linux-${version}.tar.xz";
+    sha256 = "0lqh7krxxnbrvr3w1kag92z9r4n9436fr6answjkjfbvw0z7q74m";
+  };
+
+  kernelTests = args.kernelTests or [ nixosTests.kernel-generic.linux_5_13 ];
+} // (args.argsOverride or { }))
+
diff --git a/pkgs/os-specific/linux/kernel/linux-5.4.nix b/pkgs/os-specific/linux/kernel/linux-5.4.nix
index 1c903902b61..c4e08b685b5 100644
--- a/pkgs/os-specific/linux/kernel/linux-5.4.nix
+++ b/pkgs/os-specific/linux/kernel/linux-5.4.nix
@@ -1,9 +1,9 @@
-{ stdenv, buildPackages, fetchurl, perl, buildLinux, modDirVersionArg ? null, ... } @ args:
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
 
-with stdenv.lib;
+with lib;
 
 buildLinux (args // rec {
-  version = "5.4.60";
+  version = "5.4.134";
 
   # 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;
@@ -13,6 +13,8 @@ buildLinux (args // rec {
 
   src = fetchurl {
     url = "mirror://kernel/linux/kernel/v5.x/linux-${version}.tar.xz";
-    sha256 = "08x2a78n23371k7l5p677mihnl58dpjh7r7bvyiwj3y4hlisplmd";
+    sha256 = "0haqw1w6f8p330ydbsl7iml1x0qqrv63az6921p2a70n88b8dyy9";
   };
+
+  kernelTests = args.kernelTests or [ nixosTests.kernel-generic.linux_5_4 ];
 } // (args.argsOverride or {}))
diff --git a/pkgs/os-specific/linux/kernel/linux-hardkernel-4.14.nix b/pkgs/os-specific/linux/kernel/linux-hardkernel-4.14.nix
index ba37c71d134..a64520ab893 100644
--- a/pkgs/os-specific/linux/kernel/linux-hardkernel-4.14.nix
+++ b/pkgs/os-specific/linux/kernel/linux-hardkernel-4.14.nix
@@ -1,4 +1,4 @@
-{ stdenv, buildPackages, fetchFromGitHub, perl, buildLinux, libelf, utillinux, ... } @ args:
+{ buildPackages, fetchFromGitHub, perl, buildLinux, libelf, util-linux, ... } @ args:
 
 buildLinux (args // rec {
   version = "4.14.165-172";
diff --git a/pkgs/os-specific/linux/kernel/linux-libre.nix b/pkgs/os-specific/linux/kernel/linux-libre.nix
index d3ea80ecb22..f02c1ad1250 100644
--- a/pkgs/os-specific/linux/kernel/linux-libre.nix
+++ b/pkgs/os-specific/linux/kernel/linux-libre.nix
@@ -1,8 +1,8 @@
 { stdenv, lib, fetchsvn, linux
 , scripts ? fetchsvn {
     url = "https://www.fsfla.org/svn/fsfla/software/linux-libre/releases/branches/";
-    rev = "17624";
-    sha256 = "0gs3mpiffny408l9kdrxpj48axarfb2fxvcw4w8zsz5wr7yig0n2";
+    rev = "18191";
+    sha256 = "0ggaccg7z540kh5if48v6sjy39xllzvznqx5srvrlycrs2r89iyr";
   }
 , ...
 }:
@@ -17,6 +17,7 @@ let
 in linux.override {
   argsOverride = {
     modDirVersion = "${linux.modDirVersion}-gnu";
+    isLibre = true;
 
     src = stdenv.mkDerivation {
       name = "${linux.name}-libre-src";
@@ -34,6 +35,8 @@ in linux.override {
       '';
     };
 
+    extraMeta.broken = true;
+
     passthru.updateScript = ./update-libre.sh;
 
     maintainers = [ lib.maintainers.qyliss ];
diff --git a/pkgs/os-specific/linux/kernel/linux-lqx.nix b/pkgs/os-specific/linux/kernel/linux-lqx.nix
new file mode 100644
index 00000000000..23a6b0b2d36
--- /dev/null
+++ b/pkgs/os-specific/linux/kernel/linux-lqx.nix
@@ -0,0 +1,26 @@
+{ lib, fetchFromGitHub, buildLinux, linux_zen, ... } @ args:
+
+let
+  version = "5.12.19";
+  suffix = "lqx2";
+in
+
+buildLinux (args // {
+  modDirVersion = "${version}-${suffix}";
+  inherit version;
+  isZen = true;
+
+  src = fetchFromGitHub {
+    owner = "zen-kernel";
+    repo = "zen-kernel";
+    rev = "v${version}-${suffix}";
+    sha256 = "sha256-r2DvKLlm1a1VuJwC81tRuRwCd6H21T3MsBAC3b9TUbs=";
+  };
+
+  extraMeta = {
+    branch = "5.12/master";
+    maintainers = with lib.maintainers; [ atemu ];
+    description = linux_zen.meta.description + " (Same as linux_zen but less aggressive release schedule)";
+  };
+
+} // (args.argsOverride or { }))
diff --git a/pkgs/os-specific/linux/kernel/linux-mptcp-94.nix b/pkgs/os-specific/linux/kernel/linux-mptcp-94.nix
deleted file mode 100644
index e53c3ceb5c4..00000000000
--- a/pkgs/os-specific/linux/kernel/linux-mptcp-94.nix
+++ /dev/null
@@ -1,26 +0,0 @@
-{ stdenv, buildPackages, fetchFromGitHub, perl, buildLinux, structuredExtraConfig ? {}, ... } @ args:
-let
-  mptcpVersion = "0.94.6";
-  modDirVersion = "4.14.127";
-in
-buildLinux ({
-  version = "${modDirVersion}-mptcp_v${mptcpVersion}";
-  inherit modDirVersion;
-
-  extraMeta = {
-    branch = "4.4";
-    maintainers = with stdenv.lib.maintainers; [ teto layus ];
-  };
-
-  src = fetchFromGitHub {
-    owner = "multipath-tcp";
-    repo = "mptcp";
-    rev = "v${mptcpVersion}";
-    sha256 = "071cx9205wpzhi5gc2da79w2abs3czd60jg0xml7j1szc5wl4yfn";
-  };
-
-  structuredExtraConfig = stdenv.lib.mkMerge [
-    (import ./mptcp-config.nix { inherit stdenv; })
-    structuredExtraConfig
-  ];
-} // args)
diff --git a/pkgs/os-specific/linux/kernel/linux-mptcp-95.nix b/pkgs/os-specific/linux/kernel/linux-mptcp-95.nix
index ad933ff63a7..a6a8d4936d4 100644
--- a/pkgs/os-specific/linux/kernel/linux-mptcp-95.nix
+++ b/pkgs/os-specific/linux/kernel/linux-mptcp-95.nix
@@ -1,7 +1,7 @@
-{ stdenv, buildPackages, fetchFromGitHub, perl, buildLinux, structuredExtraConfig ? {}, ... } @ args:
+{ lib, buildPackages, fetchFromGitHub, perl, buildLinux, structuredExtraConfig ? {}, ... } @ args:
 let
-  mptcpVersion = "0.95";
-  modDirVersion = "4.19.55";
+  mptcpVersion = "0.95.1";
+  modDirVersion = "4.19.126";
 in
 buildLinux ({
   version = "${modDirVersion}-mptcp_v${mptcpVersion}";
@@ -9,18 +9,18 @@ buildLinux ({
 
   extraMeta = {
     branch = "4.19";
-    maintainers = with stdenv.lib.maintainers; [ teto layus ];
+    maintainers = with lib.maintainers; [ teto layus ];
   };
 
   src = fetchFromGitHub {
     owner = "multipath-tcp";
     repo = "mptcp";
     rev = "v${mptcpVersion}";
-    sha256 = "04a66iq5vsiz8mkpszfxmqknz7y4w3lsckrcz6q1syjpk0pdyiyw";
+    sha256 = "sha256-J9UXhkI49cq83EtojLHieRtp8fT3LXTJNIqb+mUwZdM=";
   };
 
-  structuredExtraConfig = stdenv.lib.mkMerge [
-    (import ./mptcp-config.nix { inherit stdenv; })
+  structuredExtraConfig = lib.mkMerge [
+    (import ./mptcp-config.nix { inherit lib; })
     structuredExtraConfig
   ];
 
diff --git a/pkgs/os-specific/linux/kernel/linux-rpi.nix b/pkgs/os-specific/linux/kernel/linux-rpi.nix
index a3d2bfd4836..8ccf46b402b 100644
--- a/pkgs/os-specific/linux/kernel/linux-rpi.nix
+++ b/pkgs/os-specific/linux/kernel/linux-rpi.nix
@@ -1,8 +1,9 @@
 { stdenv, lib, buildPackages, fetchFromGitHub, perl, buildLinux, rpiVersion, ... } @ args:
 
 let
-  modDirVersion = "4.19.118";
-  tag = "1.20200601";
+  # NOTE: raspberrypifw & raspberryPiWirelessFirmware should be updated with this
+  modDirVersion = "5.10.17";
+  tag = "1.20210303";
 in
 lib.overrideDerivation (buildLinux (args // {
   version = "${modDirVersion}-${tag}";
@@ -12,7 +13,7 @@ lib.overrideDerivation (buildLinux (args // {
     owner = "raspberrypi";
     repo = "linux";
     rev = "raspberrypi-kernel_${tag}-1";
-    sha256 = "11jzsmnd1qry2ir9vmsv0nfdzjpgkn5yab5ylxcz406plc073anp";
+    sha256 = "0ffsllayl18ka4mgp4rdy9h0da5gy1n6g0kfvinvzdzabb5wzvrx";
   };
 
   defconfig = {
@@ -26,6 +27,14 @@ lib.overrideDerivation (buildLinux (args // {
     efiBootStub = false;
   } // (args.features or {});
 
+  extraConfig = ''
+    # ../drivers/gpu/drm/ast/ast_mode.c:851:18: error: initialization of 'void (*)(struct drm_crtc *, struct drm_atomic_state *)' from incompatible pointer type 'void (*)(struct drm_crtc *, struct drm_crtc_state *)' [-Werror=incompatible-pointer-types]
+    #   851 |  .atomic_flush = ast_crtc_helper_atomic_flush,
+    #       |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    # ../drivers/gpu/drm/ast/ast_mode.c:851:18: note: (near initialization for 'ast_crtc_helper_funcs.atomic_flush')
+    DRM_AST n
+  '';
+
   extraMeta = if (rpiVersion < 3) then {
     platforms = with lib.platforms; [ arm ];
     hydraPlatforms = [];
diff --git a/pkgs/os-specific/linux/kernel/linux-rt-5.10.nix b/pkgs/os-specific/linux/kernel/linux-rt-5.10.nix
new file mode 100644
index 00000000000..83b2fc05093
--- /dev/null
+++ b/pkgs/os-specific/linux/kernel/linux-rt-5.10.nix
@@ -0,0 +1,45 @@
+{ lib, buildLinux, fetchurl
+, kernelPatches ? [ ]
+, structuredExtraConfig ? {}
+, extraMeta ? {}
+, argsOverride ? {}
+, ... } @ args:
+
+let
+  version = "5.10.52-rt47"; # updated by ./update-rt.sh
+  branch = lib.versions.majorMinor version;
+  kversion = builtins.elemAt (lib.splitString "-" version) 0;
+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;
+
+  src = fetchurl {
+    url = "mirror://kernel/linux/kernel/v5.x/linux-${kversion}.tar.xz";
+    sha256 = "0ydf09wsg0pkjm9dk8y730ksg15p5rlbhq445zx8k191zah5g7kn";
+  };
+
+  kernelPatches = let rt-patch = {
+    name = "rt";
+    patch = fetchurl {
+      url = "mirror://kernel/linux/kernel/projects/rt/${branch}/older/patch-${version}.patch.xz";
+      sha256 = "1n71nbshma0gxyrifyymrd0wii1q0plj020amc0wdzzm27xs5k2k";
+    };
+  }; in [ rt-patch ] ++ kernelPatches;
+
+  structuredExtraConfig = with lib.kernel; {
+    PREEMPT_RT = yes;
+    # Fix error: unused option: PREEMPT_RT.
+    EXPERT = yes; # PREEMPT_RT depends on it (in kernel/Kconfig.preempt)
+    # Fix error: option not set correctly: PREEMPT_VOLUNTARY (wanted 'y', got 'n').
+    PREEMPT_VOLUNTARY = lib.mkForce no; # PREEMPT_RT deselects it.
+    # Fix error: unused option: RT_GROUP_SCHED.
+    RT_GROUP_SCHED = lib.mkForce (option no); # Removed by sched-disable-rt-group-sched-on-rt.patch.
+  } // structuredExtraConfig;
+
+  extraMeta = extraMeta // {
+    inherit branch;
+  };
+} // argsOverride)
diff --git a/pkgs/os-specific/linux/kernel/linux-rt-5.11.nix b/pkgs/os-specific/linux/kernel/linux-rt-5.11.nix
new file mode 100644
index 00000000000..5d1b14f1d0f
--- /dev/null
+++ b/pkgs/os-specific/linux/kernel/linux-rt-5.11.nix
@@ -0,0 +1,45 @@
+{ lib, buildLinux, fetchurl
+, kernelPatches ? [ ]
+, structuredExtraConfig ? {}
+, extraMeta ? {}
+, argsOverride ? {}
+, ... } @ args:
+
+let
+  version = "5.11.4-rt11"; # updated by ./update-rt.sh
+  branch = lib.versions.majorMinor version;
+  kversion = builtins.elemAt (lib.splitString "-" version) 0;
+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;
+
+  src = fetchurl {
+    url = "mirror://kernel/linux/kernel/v5.x/linux-${kversion}.tar.xz";
+    sha256 = "1i8dfw83ndaylwji7lazfckk113plvnz7kh1yppbfg35r6przrc8";
+  };
+
+  kernelPatches = let rt-patch = {
+    name = "rt";
+    patch = fetchurl {
+      url = "mirror://kernel/linux/kernel/projects/rt/${branch}/older/patch-${version}.patch.xz";
+      sha256 = "1az6cn9jj3bnjgwzzrjy1adnrnn06p2vzsnc1iib4xhs0sfr27hc";
+    };
+  }; in [ rt-patch ] ++ kernelPatches;
+
+  structuredExtraConfig = with lib.kernel; {
+    PREEMPT_RT = yes;
+    # Fix error: unused option: PREEMPT_RT.
+    EXPERT = yes; # PREEMPT_RT depends on it (in kernel/Kconfig.preempt)
+    # Fix error: option not set correctly: PREEMPT_VOLUNTARY (wanted 'y', got 'n').
+    PREEMPT_VOLUNTARY = lib.mkForce no; # PREEMPT_RT deselects it.
+    # Fix error: unused option: RT_GROUP_SCHED.
+    RT_GROUP_SCHED = lib.mkForce (option no); # Removed by sched-disable-rt-group-sched-on-rt.patch.
+  } // structuredExtraConfig;
+
+  extraMeta = extraMeta // {
+    inherit branch;
+  };
+} // argsOverride)
diff --git a/pkgs/os-specific/linux/kernel/linux-rt-5.4.nix b/pkgs/os-specific/linux/kernel/linux-rt-5.4.nix
new file mode 100644
index 00000000000..4c49dc9c42a
--- /dev/null
+++ b/pkgs/os-specific/linux/kernel/linux-rt-5.4.nix
@@ -0,0 +1,41 @@
+{ lib, buildLinux, fetchurl
+, kernelPatches ? [ ]
+, structuredExtraConfig ? {}
+, extraMeta ? {}
+, argsOverride ? {}
+, ... } @ args:
+
+let
+  version = "5.4.129-rt61"; # updated by ./update-rt.sh
+  branch = lib.versions.majorMinor version;
+  kversion = builtins.elemAt (lib.splitString "-" version) 0;
+in buildLinux (args // {
+  inherit version;
+
+  src = fetchurl {
+    url = "mirror://kernel/linux/kernel/v5.x/linux-${kversion}.tar.xz";
+    sha256 = "1ps64gx85lmbriq445hd2hcv4g4b1d1cwf4r3nd90x6i2cj4c9j4";
+  };
+
+  kernelPatches = let rt-patch = {
+    name = "rt";
+    patch = fetchurl {
+      url = "mirror://kernel/linux/kernel/projects/rt/${branch}/older/patch-${version}.patch.xz";
+      sha256 = "0b3hp6a7afkjqd7an4hj423nq6flwzd42kjcyk4pifv5fx6c7pgq";
+    };
+  }; in [ rt-patch ] ++ kernelPatches;
+
+  structuredExtraConfig = with lib.kernel; {
+    PREEMPT_RT = yes;
+    # Fix error: unused option: PREEMPT_RT.
+    EXPERT = yes; # PREEMPT_RT depends on it (in kernel/Kconfig.preempt)
+    # Fix error: option not set correctly: PREEMPT_VOLUNTARY (wanted 'y', got 'n').
+    PREEMPT_VOLUNTARY = lib.mkForce no; # PREEMPT_RT deselects it.
+    # Fix error: unused option: RT_GROUP_SCHED.
+    RT_GROUP_SCHED = lib.mkForce (option no); # Removed by sched-disable-rt-group-sched-on-rt.patch.
+  } // structuredExtraConfig;
+
+  extraMeta = extraMeta // {
+    inherit branch;
+  };
+} // argsOverride)
diff --git a/pkgs/os-specific/linux/kernel/linux-testing-bcachefs.nix b/pkgs/os-specific/linux/kernel/linux-testing-bcachefs.nix
index 456913c5e6d..a12633eb6d7 100644
--- a/pkgs/os-specific/linux/kernel/linux-testing-bcachefs.nix
+++ b/pkgs/os-specific/linux/kernel/linux-testing-bcachefs.nix
@@ -1,22 +1,33 @@
-{ stdenv, buildPackages, fetchgit, fetchpatch, perl, buildLinux, ... } @ args:
+{ lib
+, fetchpatch
+, kernel
+, date ? "2021-07-08"
+, commit ? "3693b2ca83ff9eda49660b31299d2bebe3a1075f"
+, diffHash ? "1sfq3vwc2kxa761s292f2cqrm0vvqvkdx6drpyn5yaxwnapwidcw"
+, kernelPatches # must always be defined in bcachefs' all-packages.nix entry because it's also a top-level attribute supplied by callPackage
+, argsOverride ? {}
+, ...
+} @ args:
 
-buildLinux (args // {
-  version = "5.3.2020.04.04";
-  modDirVersion = "5.3.0";
+kernel.override ( args // {
 
-  src = fetchgit {
-    url = "https://evilpiepirate.org/git/bcachefs.git";
-    rev = "a27d7265e75f6d65c2b972ce4ac27abfc153c230";
-    sha256 = "0wnjl4xs7073d5ipcsplv5qpcxb7zpfqd5gqvh3mhqc5j3qn816x";
-  };
+  argsOverride = {
+    version = "${kernel.version}-bcachefs-unstable-${date}";
+    extraMeta = {
+      branch = "master";
+      maintainers = with lib.maintainers; [ davidak chiiruno ];
+      platforms = [ "x86_64-linux" ];
+    };
+  } // argsOverride;
 
-  extraConfig = "BCACHEFS_FS m";
+  kernelPatches = [ {
+      name = "bcachefs-${commit}";
+      patch = fetchpatch {
+        name = "bcachefs-${commit}.diff";
+        url = "https://evilpiepirate.org/git/bcachefs.git/rawdiff/?id=${commit}&id2=v${lib.versions.majorMinor kernel.version}";
+        sha256 = diffHash;
+      };
+      extraConfig = "BCACHEFS_FS m";
+    } ] ++ kernelPatches;
 
-  extraMeta = {
-    branch = "master";
-    hydraPlatforms = []; # Should the testing kernels ever be built on Hydra?
-    maintainers = with stdenv.lib.maintainers; [ davidak chiiruno ];
-    platforms = [ "x86_64-linux" ];
-  };
-
-} // (args.argsOverride or {}))
+})
diff --git a/pkgs/os-specific/linux/kernel/linux-testing.nix b/pkgs/os-specific/linux/kernel/linux-testing.nix
index cf2ca99f6f5..4e2ef7b4652 100644
--- a/pkgs/os-specific/linux/kernel/linux-testing.nix
+++ b/pkgs/os-specific/linux/kernel/linux-testing.nix
@@ -1,19 +1,21 @@
-{ stdenv, buildPackages, fetchurl, perl, buildLinux, modDirVersionArg ? null, ... } @ args:
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
 
-with stdenv.lib;
+with lib;
 
 buildLinux (args // rec {
-  version = "5.9-rc2";
-  extraMeta.branch = "5.9";
+  version = "5.13-rc6";
+  extraMeta.branch = "5.12";
 
   # modDirVersion needs to be x.y.z, will always add .0
   modDirVersion = if (modDirVersionArg == null) then builtins.replaceStrings ["-"] [".0-"] version else modDirVersionArg;
 
   src = fetchurl {
     url = "https://git.kernel.org/torvalds/t/linux-${version}.tar.gz";
-    sha256 = "0mdh6gsd305kcgfqzyfgl5m886asjm5030ahg63gyias3ywzn5wd";
+    sha256 = "sha256-PunFd6tOsmrsPItp2QX4TEVxHnvvi1BMSwWio/DTlMU=";
   };
 
+  kernelTests = args.kernelTests or [ nixosTests.kernel-generic.linux_testing ];
+
   # Should the testing kernels ever be built on Hydra?
   extraMeta.hydraPlatforms = [];
 
diff --git a/pkgs/os-specific/linux/kernel/linux-xanmod.nix b/pkgs/os-specific/linux/kernel/linux-xanmod.nix
new file mode 100644
index 00000000000..701f5d3b104
--- /dev/null
+++ b/pkgs/os-specific/linux/kernel/linux-xanmod.nix
@@ -0,0 +1,54 @@
+{ lib, stdenv, buildLinux, fetchFromGitHub, ... } @ args:
+
+let
+  version = "5.13.5";
+  suffix = "xanmod1-cacule";
+in
+buildLinux (args // rec {
+  inherit version;
+  modDirVersion = "${version}-${suffix}";
+
+  src = fetchFromGitHub {
+    owner = "xanmod";
+    repo = "linux";
+    rev = modDirVersion;
+    sha256 = "sha256-Vhshu3mNkQ58TEOUBOuF7jLBlablxg/BioUyd96lI5g=";
+  };
+
+  structuredExtraConfig = with lib.kernel; {
+    # Preemptive Full Tickless Kernel at 500Hz
+    PREEMPT_VOLUNTARY = lib.mkForce no;
+    PREEMPT = lib.mkForce yes;
+    NO_HZ_FULL = yes;
+    HZ_500 = yes;
+
+    # Google's Multigenerational LRU Framework
+    LRU_GEN = yes;
+    LRU_GEN_ENABLED = yes;
+
+    # Google's BBRv2 TCP congestion Control
+    TCP_CONG_BBR2 = yes;
+    DEFAULT_BBR2 = yes;
+
+    # FQ-PIE Packet Scheduling
+    NET_SCH_DEFAULT = yes;
+    DEFAULT_FQ_PIE = yes;
+
+    # Graysky's additional CPU optimizations
+    CC_OPTIMIZE_FOR_PERFORMANCE_O3 = yes;
+
+    # Android Ashmem and Binder IPC Driver as module for Anbox
+    ASHMEM = module;
+    ANDROID = yes;
+    ANDROID_BINDER_IPC = module;
+    ANDROID_BINDERFS = module;
+    ANDROID_BINDER_DEVICES = freeform "binder,hwbinder,vndbinder";
+  };
+
+  extraMeta = {
+    branch = "5.13-cacule";
+    maintainers = with lib.maintainers; [ fortuneteller2k ];
+    description = "Built with custom settings and new features built to provide a stable, responsive and smooth desktop experience";
+    broken = stdenv.isAarch64;
+  };
+} // (args.argsOverride or { }))
diff --git a/pkgs/os-specific/linux/kernel/linux-zen.nix b/pkgs/os-specific/linux/kernel/linux-zen.nix
index c7d14a45068..caf65508210 100644
--- a/pkgs/os-specific/linux/kernel/linux-zen.nix
+++ b/pkgs/os-specific/linux/kernel/linux-zen.nix
@@ -1,23 +1,26 @@
-{ stdenv, fetchFromGitHub, buildLinux, ... } @ args:
+{ lib, fetchFromGitHub, buildLinux, ... } @ args:
 
 let
-  version = "5.8.1";
+  version = "5.12.19";
+  suffix = "zen2";
 in
 
 buildLinux (args // {
-  modDirVersion = "${version}-zen1";
+  modDirVersion = "${version}-${suffix}";
   inherit version;
+  isZen = true;
 
   src = fetchFromGitHub {
     owner = "zen-kernel";
     repo = "zen-kernel";
-    rev = "v${version}-zen1";
-    sha256 = "122q09d0sybi9lqlaxpq6ffc0ha9127bg3wzjync256lbj5394b7";
+    rev = "v${version}-${suffix}";
+    sha256 = "sha256-l+KIlaXoq/Nzf7mUom9DUjaAsn7UxeKGL6MbYN7mBZk=";
   };
 
   extraMeta = {
-    branch = "5.8/master";
-    maintainers = with stdenv.lib.maintainers; [ atemu ];
+    branch = "5.12/master";
+    maintainers = with lib.maintainers; [ atemu andresilva ];
+    description = "Built using the best configuration and kernel sources for desktop, multimedia, and gaming workloads.";
   };
 
-} // (args.argsOverride or {}))
+} // (args.argsOverride or { }))
diff --git a/pkgs/os-specific/linux/kernel/manual-config.nix b/pkgs/os-specific/linux/kernel/manual-config.nix
index 3a2682b2cfe..77add0aef53 100644
--- a/pkgs/os-specific/linux/kernel/manual-config.nix
+++ b/pkgs/os-specific/linux/kernel/manual-config.nix
@@ -1,6 +1,5 @@
-{ buildPackages, runCommand, nettools, bc, bison, flex, perl, rsync, gmp, libmpc, mpfr, openssl
-, libelf, cpio, elfutils
-, utillinuxMinimal
+{ lib, buildPackages, runCommand, nettools, bc, bison, flex, perl, rsync, gmp, libmpc, mpfr, openssl
+, libelf, cpio, elfutils, zstd, gawk, python3Minimal
 , writeTextFile
 }:
 
@@ -15,10 +14,13 @@ let
     echo "}" >> $out
   '').outPath;
 in {
+  lib,
   # Allow overriding stdenv on each buildLinux call
   stdenv,
   # The kernel version
   version,
+  # Additional kernel make flags
+  extraMakeFlags ? [],
   # The version of the kernel module directory
   modDirVersion ? version,
   # The kernel source (tarball, git checkout, etc.)
@@ -29,12 +31,18 @@ in {
   configfile,
   # Manually specified nixexpr representing the config
   # If unspecified, this will be autodetected from the .config
-  config ? stdenv.lib.optionalAttrs allowImportFromDerivation (readConfig configfile),
+  config ? lib.optionalAttrs allowImportFromDerivation (readConfig configfile),
   # 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
   extraMeta ? {},
+
+  # for module compatibility
+  isZen      ? false,
+  isLibre    ? false,
+  isHardened ? false,
+
   # Whether to utilize the controversial import-from-derivation feature to parse the config
   allowImportFromDerivation ? false,
   # ignored
@@ -42,11 +50,11 @@ in {
 }:
 
 let
-  inherit (stdenv.lib)
+  inherit (lib)
     hasAttr getAttr optional optionals optionalString optionalAttrs maintainers platforms;
 
   # Dependencies that are required to build kernel modules
-  moduleBuildDependencies = optional (stdenv.lib.versionAtLeast version "4.14") libelf;
+  moduleBuildDependencies = optional (lib.versionAtLeast version "4.14") libelf;
 
   installkernel = writeTextFile { name = "installkernel"; executable=true; text = ''
     #!${stdenv.shell} -e
@@ -57,10 +65,10 @@ let
 
   commonMakeFlags = [
     "O=$(buildRoot)"
-  ] ++ stdenv.lib.optionals (stdenv.hostPlatform.platform ? kernelMakeFlags)
-    stdenv.hostPlatform.platform.kernelMakeFlags;
+  ] ++ lib.optionals (stdenv.hostPlatform.linux-kernel ? makeFlags)
+    stdenv.hostPlatform.linux-kernel.makeFlags;
 
-  drvAttrs = config_: platform: kernelPatches: configfile:
+  drvAttrs = config_: kernelConf: kernelPatches: configfile:
     let
       config = let attrName = attr: "CONFIG_" + attr; in {
         isSet = attr: hasAttr (attrName attr) config;
@@ -82,11 +90,15 @@ let
 
       installsFirmware = (config.isEnabled "FW_LOADER") &&
         (isModular || (config.isDisabled "FIRMWARE_IN_KERNEL")) &&
-        (stdenv.lib.versionOlder version "4.14");
+        (lib.versionOlder version "4.14");
     in (optionalAttrs isModular { outputs = [ "out" "dev" ]; }) // {
       passthru = {
         inherit version modDirVersion config kernelPatches configfile
           moduleBuildDependencies stdenv;
+        inherit isZen isHardened isLibre;
+        isXen = lib.warn "The isXen attribute is deprecated. All Nixpkgs kernels that support it now have Xen enabled." true;
+        kernelOlder = lib.versionOlder version;
+        kernelAtLeast = lib.versionAtLeast version;
       };
 
       inherit src;
@@ -94,9 +106,9 @@ let
       patches =
         map (p: p.patch) kernelPatches
         # Required for deterministic builds along with some postPatch magic.
-        ++ optional (stdenv.lib.versionAtLeast version "4.13") ./randstruct-provide-seed.patch
+        ++ optional (lib.versionAtLeast version "4.13") ./randstruct-provide-seed.patch
         # Fixes determinism by normalizing metadata for the archive of kheaders
-        ++ optional (stdenv.lib.versionAtLeast version "5.2" && stdenv.lib.versionOlder version "5.4") ./gen-kheaders-metadata.patch;
+        ++ optional (lib.versionAtLeast version "5.2" && lib.versionOlder version "5.4") ./gen-kheaders-metadata.patch;
 
       prePatch = ''
         for mf in $(find -name Makefile -o -name Makefile.include -o -name install.sh); do
@@ -104,7 +116,14 @@ let
             sed -i "$mf" -e 's|/usr/bin/||g ; s|/bin/||g ; s|/sbin/||g'
         done
         sed -i Makefile -e 's|= depmod|= ${buildPackages.kmod}/bin/depmod|'
-        sed -i scripts/ld-version.sh -e "s|/usr/bin/awk|${buildPackages.gawk}/bin/awk|"
+
+        # Don't include a (random) NT_GNU_BUILD_ID, to make the build more deterministic.
+        # This way kernels can be bit-by-bit reproducible depending on settings
+        # (e.g. MODULE_SIG and SECURITY_LOCKDOWN_LSM need to be disabled).
+        # See also https://kernelnewbies.org/BuildId
+        sed -i Makefile -e 's|--build-id=[^ ]*|--build-id=none|'
+
+        patchShebangs scripts
       '';
 
       postPatch = ''
@@ -154,9 +173,11 @@ let
 
       buildFlags = [
         "KBUILD_BUILD_VERSION=1-NixOS"
-        platform.kernelTarget
+        kernelConf.target
         "vmlinux"  # for "perf" and things like that
-      ] ++ optional isModular "modules";
+      ]
+      ++ optional isModular "modules"
+      ++ extraMakeFlags;
 
       installFlags = [
         "INSTALLKERNEL=${installkernel}"
@@ -169,16 +190,16 @@ let
       '';
 
       # Some image types need special install targets (e.g. uImage is installed with make uinstall)
-      installTargets = [ (
-        if platform ? kernelInstallTarget then platform.kernelInstallTarget
-        else if platform.kernelTarget == "uImage" then "uinstall"
-        else if platform.kernelTarget == "zImage" || platform.kernelTarget == "Image.gz" then "zinstall"
-        else "install"
-      ) ];
+      installTargets = [
+        (kernelConf.installTarget or (
+          /**/ if kernelConf.target == "uImage" then "uinstall"
+          else if kernelConf.target == "zImage" || kernelConf.target == "Image.gz" then "zinstall"
+          else "install"))
+      ];
 
       postInstall = (optionalString installsFirmware ''
         mkdir -p $out/lib/firmware
-      '') + (if (platform ? kernelDTB && platform.kernelDTB) then ''
+      '') + (if (kernelConf.DTB or false) then ''
         make $makeFlags "''${makeFlagsArray[@]}" dtbs dtbs_install INSTALL_DTBS_PATH=$out/dtbs
       '' else "") + (if isModular then ''
         mkdir -p $dev
@@ -234,10 +255,10 @@ let
         rm -fR drivers
 
         # Keep all headers
-        find .  -type f -name '*.h' -print0 | xargs -0 chmod u-w
+        find .  -type f -name '*.h' -print0 | xargs -0 -r chmod u-w
 
         # Keep linker scripts (they are required for out-of-tree modules on aarch64)
-        find .  -type f -name '*.lds' -print0 | xargs -0 chmod u-w
+        find .  -type f -name '*.lds' -print0 | xargs -0 -r chmod u-w
 
         # Keep root and arch-specific Makefiles
         chmod u-w Makefile
@@ -247,7 +268,7 @@ let
         chmod u-w -R scripts
 
         # Delete everything not kept
-        find . -type f -perm -u=w -print0 | xargs -0 rm
+        find . -type f -perm -u=w -print0 | xargs -0 -r rm
 
         # Delete empty directories
         find -empty -type d -delete
@@ -266,9 +287,9 @@ let
           "The Linux kernel" +
           (if kernelPatches == [] then "" else
             " (with patches: "
-            + stdenv.lib.concatStringsSep ", " (map (x: x.name) kernelPatches)
+            + lib.concatStringsSep ", " (map (x: x.name) kernelPatches)
             + ")");
-        license = stdenv.lib.licenses.gpl2;
+        license = lib.licenses.gpl2Only;
         homepage = "https://www.kernel.org/";
         repositories.git = "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git";
         maintainers = [
@@ -280,24 +301,23 @@ let
     };
 in
 
-assert (stdenv.lib.versionAtLeast version "4.14" && stdenv.lib.versionOlder version "5.8") -> libelf != null;
-assert stdenv.lib.versionAtLeast version "4.15" -> utillinuxMinimal != null;
-assert stdenv.lib.versionAtLeast version "5.8" -> elfutils != null;
+assert (lib.versionAtLeast version "4.14" && lib.versionOlder version "5.8") -> libelf != null;
+assert lib.versionAtLeast version "5.8" -> elfutils != null;
 
-stdenv.mkDerivation ((drvAttrs config stdenv.hostPlatform.platform kernelPatches configfile) // {
+stdenv.mkDerivation ((drvAttrs config stdenv.hostPlatform.linux-kernel kernelPatches configfile) // {
   pname = "linux";
   inherit version;
 
   enableParallelBuilding = true;
 
   depsBuildBuild = [ buildPackages.stdenv.cc ];
-  nativeBuildInputs = [ perl bc nettools openssl rsync gmp libmpc mpfr ]
-      ++ optional  (stdenv.hostPlatform.platform.kernelTarget == "uImage") buildPackages.ubootTools
-      ++ optional  (stdenv.lib.versionAtLeast version "4.14" && stdenv.lib.versionOlder version "5.8") libelf
-      ++ optional  (stdenv.lib.versionAtLeast version "4.15") utillinuxMinimal
-      ++ optionals (stdenv.lib.versionAtLeast version "4.16") [ bison flex ]
-      ++ optional  (stdenv.lib.versionAtLeast version "5.2")  cpio
-      ++ optional  (stdenv.lib.versionAtLeast version "5.8")  elfutils
+  nativeBuildInputs = [ perl bc nettools openssl rsync gmp libmpc mpfr gawk zstd python3Minimal ]
+      ++ optional  (stdenv.hostPlatform.linux-kernel.target == "uImage") buildPackages.ubootTools
+      ++ optional  (lib.versionAtLeast version "4.14" && lib.versionOlder version "5.8") libelf
+      # Removed util-linuxMinimal since it should not be a dependency.
+      ++ optionals (lib.versionAtLeast version "4.16") [ bison flex ]
+      ++ optional  (lib.versionAtLeast version "5.2")  cpio
+      ++ optional  (lib.versionAtLeast version "5.8")  elfutils
       ;
 
   hardeningDisable = [ "bindnow" "format" "fortify" "stackprotector" "pic" "pie" ];
@@ -306,10 +326,10 @@ stdenv.mkDerivation ((drvAttrs config stdenv.hostPlatform.platform kernelPatches
   makeFlags = commonMakeFlags ++ [
     "CC=${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc"
     "HOSTCC=${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}cc"
-    "ARCH=${stdenv.hostPlatform.platform.kernelArch}"
-  ] ++ stdenv.lib.optional (stdenv.hostPlatform != stdenv.buildPlatform) [
+    "ARCH=${stdenv.hostPlatform.linuxArch}"
+  ] ++ lib.optional (stdenv.hostPlatform != stdenv.buildPlatform) [
     "CROSS_COMPILE=${stdenv.cc.targetPrefix}"
-  ];
+  ] ++ extraMakeFlags;
 
-  karch = stdenv.hostPlatform.platform.kernelArch;
+  karch = stdenv.hostPlatform.linuxArch;
 })
diff --git a/pkgs/os-specific/linux/kernel/mptcp-config.nix b/pkgs/os-specific/linux/kernel/mptcp-config.nix
index 9752e63d9f9..59b11167ac2 100644
--- a/pkgs/os-specific/linux/kernel/mptcp-config.nix
+++ b/pkgs/os-specific/linux/kernel/mptcp-config.nix
@@ -1,5 +1,5 @@
-{ stdenv }:
-with stdenv.lib.kernel;
+{ lib }:
+with lib.kernel;
 {
     # DRM_AMDGPU = yes;
 
diff --git a/pkgs/os-specific/linux/kernel/patches.nix b/pkgs/os-specific/linux/kernel/patches.nix
index 678cec34b70..f41cedca0f6 100644
--- a/pkgs/os-specific/linux/kernel/patches.nix
+++ b/pkgs/os-specific/linux/kernel/patches.nix
@@ -1,6 +1,19 @@
 { lib, fetchpatch, fetchurl }:
 
 {
+  ath_regd_optional = rec {
+    name = "ath_regd_optional";
+    patch = fetchpatch {
+      name = name + ".patch";
+      url = "https://github.com/openwrt/openwrt/raw/ed2015c38617ed6624471e77f27fbb0c58c8c660/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch";
+      sha256 = "1ssDXSweHhF+pMZyd6kSrzeW60eb6MO6tlf0il17RC0=";
+      postFetch = ''
+        sed -i 's/CPTCFG_/CONFIG_/g' $out
+        sed -i '/--- a\/local-symbols/,$d' $out
+      '';
+    };
+  };
+
   bridge_stp_helper =
     { name = "bridge-stp-helper";
       patch = ./bridge-stp-helper.patch;
@@ -33,15 +46,11 @@
 
   cpu-cgroup-v2 = import ./cpu-cgroup-v2-patches;
 
-  tag_hardened = {
-    name = "tag-hardened";
-    patch = ./hardened/tag-hardened.patch;
-  };
-
   hardened = let
     mkPatch = kernelVersion: src: {
       name = lib.removeSuffix ".patch" src.name;
-      patch = fetchurl src;
+      patch = fetchurl (lib.filterAttrs (k: v: k != "extra") src);
+      extra = src.extra;
     };
     patches = builtins.fromJSON (builtins.readFile ./hardened/patches.json);
   in lib.mapAttrs mkPatch patches;
@@ -76,6 +85,18 @@
     };
   };
 
+  # Adapted for Linux 5.4 from:
+  # https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=04896832c94aae4842100cafb8d3a73e1bed3a45
+  rtl8761b_support =
+    { name = "rtl8761b-support";
+      patch = ./rtl8761b-support.patch;
+    };
+
+  export-rt-sched-migrate = {
+    name = "export-rt-sched-migrate";
+    patch = ./export-rt-sched-migrate.patch;
+  };
+
   # patches from https://lkml.org/lkml/2019/7/15/1748
   mac_nvme_t2 = rec {
     name = "mac_nvme_t2";
diff --git a/pkgs/os-specific/linux/kernel/perf.nix b/pkgs/os-specific/linux/kernel/perf.nix
index a3558244297..b58bca352e6 100644
--- a/pkgs/os-specific/linux/kernel/perf.nix
+++ b/pkgs/os-specific/linux/kernel/perf.nix
@@ -1,12 +1,14 @@
 { lib, stdenv, kernel, elfutils, python2, python3, perl, newt, slang, asciidoc, xmlto, makeWrapper
-, docbook_xsl, docbook_xml_dtd_45, libxslt, flex, bison, pkgconfig, libunwind, binutils
+, docbook_xsl, docbook_xml_dtd_45, libxslt, flex, bison, pkg-config, libunwind, binutils
 , libiberty, audit, libbfd, libopcodes, openssl, systemtap, numactl
-, zlib, withGtk ? false, gtk2 ? null
+, zlib
+, withGtk ? false, gtk2
+, withZstd ? true, zstd
+, withLibcap ? true, libcap
 }:
 
 with lib;
 
-assert withGtk -> gtk2 != null;
 assert versionAtLeast kernel.version "3.12";
 
 stdenv.mkDerivation {
@@ -36,13 +38,15 @@ stdenv.mkDerivation {
   # perf refers both to newt and slang
   nativeBuildInputs = [
     asciidoc xmlto docbook_xsl docbook_xml_dtd_45 libxslt
-    flex bison libiberty audit makeWrapper pkgconfig python3
+    flex bison libiberty audit makeWrapper pkg-config python3
   ];
   buildInputs = [
     elfutils newt slang libunwind libbfd zlib openssl systemtap.stapBuild numactl
     libopcodes python3 perl
-  ] ++ stdenv.lib.optional withGtk gtk2
-    ++ (if (versionAtLeast kernel.version "4.19") then [ python3 ] else [ python2 ]);
+  ] ++ lib.optional withGtk gtk2
+    ++ (if (versionAtLeast kernel.version "4.19") then [ python3 ] else [ python2 ])
+    ++ lib.optional withZstd zstd
+    ++ lib.optional withLibcap libcap;
 
   # Note: we don't add elfutils to buildInputs, since it provides a
   # bad `ld' and other stuff.
@@ -55,7 +59,7 @@ stdenv.mkDerivation {
   ];
 
   postPatch = ''
-    patchShebangs scripts/bpf_helpers_doc.py
+    patchShebangs scripts
   '';
 
   doCheck = false; # requires "sparse"
@@ -72,7 +76,8 @@ stdenv.mkDerivation {
   meta = {
     homepage = "https://perf.wiki.kernel.org/";
     description = "Linux tools to profile with performance counters";
-    maintainers = with stdenv.lib.maintainers; [viric];
-    platforms = with stdenv.lib.platforms; linux;
+    maintainers = with lib.maintainers; [viric];
+    platforms = with lib.platforms; linux;
+    broken = kernel.kernelOlder "5";
   };
 }
diff --git a/pkgs/os-specific/linux/kernel/rtl8761b-support.patch b/pkgs/os-specific/linux/kernel/rtl8761b-support.patch
new file mode 100644
index 00000000000..b6d80d5bc8d
--- /dev/null
+++ b/pkgs/os-specific/linux/kernel/rtl8761b-support.patch
@@ -0,0 +1,33 @@
+diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c
+index 67f4bc21e7c5..3a9afc905f24 100644
+--- a/drivers/bluetooth/btrtl.c
++++ b/drivers/bluetooth/btrtl.c
+@@ -130,12 +130,19 @@  static const struct id_table ic_id_table[] = {
+ 	  .cfg_name = "rtl_bt/rtl8821c_config" },
+
+ 	/* 8761A */
+-	{ IC_MATCH_FL_LMPSUBV, RTL_ROM_LMP_8761A, 0x0,
++	{ IC_INFO(RTL_ROM_LMP_8761A, 0xa),
+ 	  .config_needed = false,
+ 	  .has_rom_version = true,
+ 	  .fw_name  = "rtl_bt/rtl8761a_fw.bin",
+ 	  .cfg_name = "rtl_bt/rtl8761a_config" },
+
++	/* 8761B */
++	{ IC_INFO(RTL_ROM_LMP_8761A, 0xb),
++	  .config_needed = false,
++	  .has_rom_version = true,
++	  .fw_name  = "rtl_bt/rtl8761b_fw.bin",
++	  .cfg_name = "rtl_bt/rtl8761b_config" },
++
+	/* 8822C with USB interface */
+	{ IC_INFO(RTL_ROM_LMP_8822B, 0xc),
+	  .config_needed = false,
+@@ -251,6 +258,7 @@  static int rtlbt_parse_firmware(struct hci_dev *hdev,
+ 		{ RTL_ROM_LMP_8723B, 9 },	/* 8723D */
+ 		{ RTL_ROM_LMP_8821A, 10 },	/* 8821C */
+ 		{ RTL_ROM_LMP_8822B, 13 },	/* 8822C */
++		{ RTL_ROM_LMP_8761A, 14 },	/* 8761B */
+ 	};
+
+ 	min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3;
diff --git a/pkgs/os-specific/linux/kernel/update-rt.sh b/pkgs/os-specific/linux/kernel/update-rt.sh
new file mode 100755
index 00000000000..ccb01793342
--- /dev/null
+++ b/pkgs/os-specific/linux/kernel/update-rt.sh
@@ -0,0 +1,79 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+# To update all rt kernels run: ./update-rt.sh
+
+# To update just one ./linux-rt-5.X.nix run: ./update-rt.sh ./linux-rt-5.X.nix
+
+# To add a new kernel branch 5.Y run: ./update-rt.sh ./linux-rt-5.Y.nix
+# (with nonexistent .nix file) and update all-packages.nix.
+
+# To commit run with: env COMMIT=1
+
+mirror=https://kernel.org/pub/linux/kernel
+
+main() {
+    if [ $# -ge 1 ]; then
+        update-if-needed "$1"
+    else
+        update-all-if-needed
+    fi
+}
+
+update-all-if-needed() {
+    for f in "$(dirname "$0")"/linux-rt-*.nix; do
+        update-if-needed "$f"
+    done
+}
+
+file-version() {
+    file="$1" # e.g. ./linux-rt-5.4.nix
+    if [ -e "$file" ]; then
+        grep ' version = ' "$file" | grep -o '[0-9].[^"]*'
+    fi
+}
+
+latest-rt-version() {
+    branch="$1" # e.g. 5.4
+    curl -sL "$mirror/projects/rt/$branch/sha256sums.asc" |
+        sed -ne '/.patch.xz/ { s/.*patch-\(.*\).patch.xz/\1/p}' |
+        grep -v '\-rc' |
+        tail -n 1
+}
+
+update-if-needed() {
+    file="$1" # e.g. ./linux-rt-5.4.nix (created if does not exist)
+    branch=$(basename "$file" .nix) # e.g. linux-rt-5.4
+    branch=${branch#linux-rt-} # e.g. 5.4
+    cur=$(file-version "$file") # e.g. 5.4.59-rt36 or empty
+    new=$(latest-rt-version "$branch") # e.g. 5.4.61-rt37
+    kversion=${new%-*} # e.g. 5.4.61
+    major=${branch%.*} # e.g 5
+    nixattr="linux-rt_${branch/./_}"
+    if [ "$new" = "$cur" ]; then
+        echo "$nixattr: $cur (up-to-date)"
+        return
+    fi
+    khash=$(nix-prefetch-url "$mirror/v${major}.x/linux-${kversion}.tar.xz")
+    phash=$(nix-prefetch-url "$mirror/projects/rt/${branch}/older/patch-${new}.patch.xz")
+    if [ "$cur" ]; then
+        msg="$nixattr: $cur -> $new"
+    else
+        msg="$nixattr: init at $new"
+        prev=$(ls -v "$(dirname "$0")"/linux-rt-*.nix | tail -1)
+        cp "$prev" "$file"
+        cur=$(file-version "$file")
+    fi
+    echo "$msg"
+    sed -i "$file" \
+        -e "s/$cur/$new/" \
+        -e "s|kernel/v[0-9]*|kernel/v$major|" \
+        -e "1,/.patch.xz/ s/sha256 = .*/sha256 = \"$khash\";/" \
+        -e "1,/.patch.xz/! s/sha256 = .*/sha256 = \"$phash\";/"
+    if [ "${COMMIT:-}" ]; then
+        git add "$file"
+        git commit -m "$msg"
+    fi
+}
+
+return 2>/dev/null || main "$@"
diff --git a/pkgs/os-specific/linux/kernel/update.sh b/pkgs/os-specific/linux/kernel/update.sh
index 55fdce06c97..560edced36e 100755
--- a/pkgs/os-specific/linux/kernel/update.sh
+++ b/pkgs/os-specific/linux/kernel/update.sh
@@ -58,6 +58,9 @@ ls $NIXPKGS/pkgs/os-specific/linux/kernel | while read FILE; do
   echo "Updated $OLDVER -> $V"
 done
 
+# Update linux-rt
+COMMIT=1 $NIXPKGS/pkgs/os-specific/linux/kernel/update-rt.sh
+
 # Update linux-libre
 COMMIT=1 $NIXPKGS/pkgs/os-specific/linux/kernel/update-libre.sh