diff --git a/nixos/modules/profiles/hardened.nix b/nixos/modules/profiles/hardened.nix
index 53aa4bae2624..a588943fe710 100644
--- a/nixos/modules/profiles/hardened.nix
+++ b/nixos/modules/profiles/hardened.nix
@@ -22,6 +22,8 @@ with lib;
security.protectKernelImage = mkDefault true;
+ security.allowSimultaneousMultithreading = mkDefault false;
+
security.virtualization.flushL1DataCache = mkDefault "always";
security.apparmor.enable = mkDefault true;
diff --git a/nixos/modules/security/misc.nix b/nixos/modules/security/misc.nix
index 735362729bfd..4506a67487d4 100644
--- a/nixos/modules/security/misc.nix
+++ b/nixos/modules/security/misc.nix
@@ -31,12 +31,38 @@ with lib;
'';
};
+ security.allowSimultaneousMultithreading = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether to allow SMT/hyperthreading. Disabling SMT means that only
+ physical CPU cores will be usable at runtime, potentially at
+ significant performance cost.
+
+
+
+ The primary motivation for disabling SMT is to mitigate the risk of
+ leaking data between threads running on the same CPU core (due to
+ e.g., shared caches). This attack vector is unproven.
+
+
+
+ Disabling SMT is a supplement to the L1 data cache flushing mitigation
+ (see )
+ versus malicious VM guests (SMT could "bring back" previously flushed
+ data).
+
+
+ '';
+ };
+
security.virtualization.flushL1DataCache = mkOption {
type = types.nullOr (types.enum [ "never" "cond" "always" ]);
default = null;
description = ''
Whether the hypervisor should flush the L1 data cache before
entering guests.
+ See also .
@@ -88,6 +114,10 @@ with lib;
boot.kernel.sysctl."kernel.kexec_load_disabled" = mkDefault true;
})
+ (mkIf (!config.security.allowSimultaneousMultithreading) {
+ boot.kernelParams = [ "nosmt" ];
+ })
+
(mkIf (config.security.virtualization.flushL1DataCache != null) {
boot.kernelParams = [ "kvm-intel.vmentry_l1d_flush=${config.security.virtualization.flushL1DataCache}" ];
})