Disabling SMT on CoreOS Container Linux

Recent Intel CPU vulnerabilities (L1TF and MDS) cannot be fully mitigated in software without disabling Simultaneous Multi-Threading. This can have a substantial performance impact and is only necessary for certain workloads, so for compatibility reasons, SMT is enabled by default.

SMT should be disabled on affected Intel processors under the following circumstances:

  1. A bare-metal host runs untrusted virtual machines, and other arrangements have not been made for mitigation.
  2. A bare-metal host runs untrusted code outside a virtual machine.

SMT can be conditionally disabled by passing mitigations=auto,nosmt on the kernel command line. This will disable SMT only if required for mitigating a vulnerability. This approach has two caveats:

  1. It does not protect against unknown vulnerabilities in SMT.
  2. It allows future Container Linux updates to disable SMT if needed to mitigate new vulnerabilities.

Alternatively, SMT can be unconditionally disabled by passing nosmt on the kernel command line. This provides the most protection and avoids possible behavior changes on upgrades, at the cost of a potentially unnecessary reduction in performance.

For typical use cases, we recommend enabling the mitigations=auto,nosmt command-line option.

Configuring new machines

The following Container Linux config performs two tasks:

  1. Adds mitigations=auto,nosmt to the kernel command line. This affects the second and subsequent boots of the machine, but not the first boot.
  2. On the first boot, disables SMT at runtime if the system has an Intel processor. This is sufficient to protect against currently-known SMT vulnerabilities until the system is rebooted. After reboot, SMT will be re-enabled if the processor is not actually vulnerable.
This is the human-readable config file. This should not be immediately passed to Container Linux. Learn more.
# This config is meant to be consumed by the config transpiler, which will
# generate the corresponding Ignition config. Do not pass this config directly
# to instances of Container Linux.

# Add kernel command-line argument to automatically disable SMT on CPUs
# where it is vulnerable.  This will affect the second and subsequent
# boots of the machine, but not the first boot.
storage:
  filesystems:
    - name: OEM
      mount:
        device: /dev/disk/by-label/OEM
        format: ext4
  files:
    - filesystem: OEM
      path: /grub.cfg
      append: true
      mode: 0644
      contents:
        inline: |
          # Disable SMT on CPUs affected by MDS or similar vulnerabilities
          set linux_append="$linux_append mitigations=auto,nosmt"

# On the first boot only, disable SMT at runtime if it is enabled and
# the system has an Intel CPU.  L1TF and MDS vulnerabilities are limited
# to Intel CPUs.
systemd:
  units:
    - name: disable-smt-firstboot.service
      enabled: true
      contents: |
        [Unit]
        Description=Disable SMT on first boot on Intel CPUs to mitigate MDS
        DefaultDependencies=no
        Before=sysinit.target shutdown.target
        Conflicts=shutdown.target
        ConditionFirstBoot=true

        [Service]
        Type=oneshot
        ExecStart=/bin/bash -c 'active="$(cat /sys/devices/system/cpu/smt/active)" && if [[ "$active" != 0 ]] && grep -q "vendor_id.*GenuineIntel" /proc/cpuinfo; then echo "Disabling SMT." && echo off > /sys/devices/system/cpu/smt/control; fi'

        [Install]
        WantedBy=sysinit.target
This is the raw machine configuration, which is not intended for editing. Learn more. Validate the config here.
{
  "ignition": {
    "config": {},
    "timeouts": {},
    "version": "2.1.0"
  },
  "networkd": {},
  "passwd": {},
  "storage": {
    "files": [
      {
        "filesystem": "OEM",
        "group": {},
        "path": "/grub.cfg",
        "user": {},
        "contents": {
          "source": "data:,%23%20Disable%20SMT%20on%20CPUs%20affected%20by%20MDS%20or%20similar%20vulnerabilities%0Aset%20linux_append%3D%22%24linux_append%20mitigations%3Dauto%2Cnosmt%22%0A",
          "verification": {}
        },
        "mode": 420
      }
    ],
    "filesystems": [
      {
        "mount": {
          "device": "/dev/disk/by-label/OEM",
          "format": "ext4"
        },
        "name": "OEM"
      }
    ]
  },
  "systemd": {
    "units": [
      {
        "contents": "[Unit]\nDescription=Disable SMT on first boot on Intel CPUs to mitigate MDS\nDefaultDependencies=no\nBefore=sysinit.target shutdown.target\nConflicts=shutdown.target\nConditionFirstBoot=true\n\n[Service]\nType=oneshot\nExecStart=/bin/bash -c 'active=\"$(cat /sys/devices/system/cpu/smt/active)\" \u0026\u0026 if [[ \"$active\" != 0 ]] \u0026\u0026 grep -q \"vendor_id.*GenuineIntel\" /proc/cpuinfo; then echo \"Disabling SMT.\" \u0026\u0026 echo off \u003e /sys/devices/system/cpu/smt/control; fi'\n\n[Install]\nWantedBy=sysinit.target",
        "enabled": true,
        "name": "disable-smt-firstboot.service"
      }
    ]
  }
}

Configuring existing machines

To add mitigations=auto,nosmt to the kernel command line on an existing system, add the following line to /usr/share/oem/grub.cfg:

set linux_append="$linux_append mitigations=auto,nosmt"

For example, using SSH:

ssh core@node01 'sudo sh -c "echo \"set linux_append=\\\"\\\$linux_append mitigations=auto,nosmt\\\"\" >> /usr/share/oem/grub.cfg && systemctl reboot"'

If you use locksmith for reboot coordination, replace systemctl reboot with locksmithctl send-need-reboot.