aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLibravatar sommerfeld <sommerfeld@sommerfeld.dev>2026-05-29 11:18:14 +0100
committerLibravatar sommerfeld <sommerfeld@sommerfeld.dev>2026-05-29 11:18:14 +0100
commite2a7a2fdb9ba66e777ec1a8c0d3c9301cc21bdab (patch)
tree6db225142679c13ff43bed3ed1e29054aeb9cb8d
parent3be68c032c864fa98ed85e54ea5af19976c55ed7 (diff)
downloaddotfiles-e2a7a2fdb9ba66e777ec1a8c0d3c9301cc21bdab.tar.gz
dotfiles-e2a7a2fdb9ba66e777ec1a8c0d3c9301cc21bdab.tar.bz2
dotfiles-e2a7a2fdb9ba66e777ec1a8c0d3c9301cc21bdab.zip
feat(suspend): hardened-only init_on_free=0 + hang-detection cmdline
Split the hardened UKI cmdline off the shared etc/kernel/cmdline.tmpl so we can carry workarounds without poking the stock linux build. Daily-driving linux-hardened on this hardware has reliably hung on resume from S3: black screen, blinking caps-lock + power LED, only the power button helps. The kernel journal stops at 'PM: suspend entry (deep)' with nothing after, so the freeze is below the level where logs can flush — characteristic of a hard hang inside a device driver's suspend/resume callback rather than a userspace bug. linux-hardened defaults init_on_free=1, which zeroes pages on free. On Intel + iwlwifi/i915/nvme stacks this routinely surfaces latent UAFs as suspend hangs that are invisible on stock linux. Drop that knob to 0 for the hardened cmdline as the working hypothesis. Add nmi_watchdog=panic, softlockup_panic=1, panic=10 so if the next attempt still wedges, a stuck CPU self-panics and auto-reboots within ~10s, giving us a 'journalctl -b -1 -k' trace to look at instead of having to force-power-off blindly. Stock linux is untouched.
-rw-r--r--.chezmoiignore1
-rw-r--r--.gitignore1
-rw-r--r--etc/kernel/cmdline-linux-hardened.tmpl1
-rw-r--r--etc/mkinitcpio.d/linux-hardened.preset8
4 files changed, 9 insertions, 2 deletions
diff --git a/.chezmoiignore b/.chezmoiignore
index 99af635..ae7912d 100644
--- a/.chezmoiignore
+++ b/.chezmoiignore
@@ -2,6 +2,7 @@ KEYBINDS.md
README.md
bootstrap.sh
migrate-podman-to-btrfs.sh
+diagnose-suspend.sh
meta/
systemd-units/
etc/
diff --git a/.gitignore b/.gitignore
index 9a33068..e8c1d56 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@
node_modules/
*.swp
/migrate-podman-to-btrfs.sh
+/diagnose-suspend.sh
diff --git a/etc/kernel/cmdline-linux-hardened.tmpl b/etc/kernel/cmdline-linux-hardened.tmpl
new file mode 100644
index 0000000..d2e2973
--- /dev/null
+++ b/etc/kernel/cmdline-linux-hardened.tmpl
@@ -0,0 +1 @@
+rd.luks.name={{ output "lsblk" "-dno" "UUID" (printf "/dev/%s" .luksRootPartition) | trim }}=root root=/dev/mapper/root rw quiet init_on_free=0 nmi_watchdog=panic softlockup_panic=1 panic=10
diff --git a/etc/mkinitcpio.d/linux-hardened.preset b/etc/mkinitcpio.d/linux-hardened.preset
index 92da91c..960a24a 100644
--- a/etc/mkinitcpio.d/linux-hardened.preset
+++ b/etc/mkinitcpio.d/linux-hardened.preset
@@ -1,7 +1,10 @@
# mkinitcpio preset for the 'linux-hardened' kernel. Produces a UKI at
# /boot/EFI/Linux/arch-linux-hardened.efi alongside the stock linux UKI.
-# Shares etc/kernel/cmdline.tmpl (same LUKS root, no kernel-specific
-# cmdline knobs). Register the EFI entry once with efibootmgr:
+# Uses its own cmdline file (etc/kernel/cmdline-linux-hardened.tmpl)
+# to carry workarounds for hardened-specific suspend/resume hangs on
+# this hardware (init_on_free=0 + hang-detection knobs). The stock
+# linux UKI keeps the minimal etc/kernel/cmdline.tmpl. Register the
+# EFI entry once with efibootmgr:
#
# sudo efibootmgr --create --disk /dev/nvme0n1 --part 1 \
# --label 'Arch Hardened' --loader '\EFI\Linux\arch-linux-hardened.efi'
@@ -10,6 +13,7 @@
#ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-linux-hardened"
+ALL_cmdline="/etc/kernel/cmdline-linux-hardened"
PRESETS=('default' 'fallback')