Linux Documentation
 help / color / mirror / Atom feed
* [RFC PATCH 1/5] mm: zswap: decompress into a folio subpage
From: fujunjie @ 2026-05-08 20:20 UTC (permalink / raw)
  To: Andrew Morton, Chris Li, Kairui Song, Johannes Weiner, Nhat Pham,
	Yosry Ahmed
  Cc: linux-mm, linux-kernel, linux-doc, Jonathan Corbet,
	David Hildenbrand, Ryan Roberts, Barry Song, Baolin Wang,
	Chengming Zhou, Baoquan He, Lorenzo Stoakes
In-Reply-To: <tencent_8B437BE4F586C162950BF71954316C1EDB05@qq.com>

zswap_decompress() always writes to offset 0 of the target folio. That
is sufficient while zswap only loads order-0 folios, but large folio
swapin needs to fill each base page from its own zswap entry.

Pass the base-page index to zswap_decompress() and use it for the kmap
and scatterlist output offsets. Existing callers pass index 0, so this
is a preparatory change with no intended behavior change.

Signed-off-by: fujunjie <fujunjie1@qq.com>
---
 mm/zswap.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/mm/zswap.c b/mm/zswap.c
index 4b5149173b0e..afe38dfc5a29 100644
--- a/mm/zswap.c
+++ b/mm/zswap.c
@@ -921,12 +921,14 @@ static bool zswap_compress(struct page *page, struct zswap_entry *entry,
 	return comp_ret == 0 && alloc_ret == 0;
 }
 
-static bool zswap_decompress(struct zswap_entry *entry, struct folio *folio)
+static bool zswap_decompress(struct zswap_entry *entry, struct folio *folio,
+			     unsigned long index)
 {
 	struct zswap_pool *pool = entry->pool;
 	struct scatterlist input[2]; /* zsmalloc returns an SG list 1-2 entries */
 	struct scatterlist output;
 	struct crypto_acomp_ctx *acomp_ctx;
+	size_t offset = index * PAGE_SIZE;
 	int ret = 0, dlen;
 
 	acomp_ctx = raw_cpu_ptr(pool->acomp_ctx);
@@ -939,14 +941,14 @@ static bool zswap_decompress(struct zswap_entry *entry, struct folio *folio)
 
 		WARN_ON_ONCE(input->length != PAGE_SIZE);
 
-		dst = kmap_local_folio(folio, 0);
+		dst = kmap_local_folio(folio, offset);
 		memcpy_from_sglist(dst, input, 0, PAGE_SIZE);
 		dlen = PAGE_SIZE;
 		kunmap_local(dst);
 		flush_dcache_folio(folio);
 	} else {
 		sg_init_table(&output, 1);
-		sg_set_folio(&output, folio, PAGE_SIZE, 0);
+		sg_set_folio(&output, folio, PAGE_SIZE, offset);
 		acomp_request_set_params(acomp_ctx->req, input, &output,
 					 entry->length, PAGE_SIZE);
 		ret = crypto_acomp_decompress(acomp_ctx->req);
@@ -1034,7 +1036,7 @@ static int zswap_writeback_entry(struct zswap_entry *entry,
 		goto out;
 	}
 
-	if (!zswap_decompress(entry, folio)) {
+	if (!zswap_decompress(entry, folio, 0)) {
 		ret = -EIO;
 		goto out;
 	}
@@ -1611,7 +1613,7 @@ int zswap_load(struct folio *folio)
 	if (!entry)
 		return -ENOENT;
 
-	if (!zswap_decompress(entry, folio)) {
+	if (!zswap_decompress(entry, folio, 0)) {
 		folio_unlock(folio);
 		return -EIO;
 	}
-- 
2.34.1


^ permalink raw reply related

* [RFC PATCH 0/5] mm: support zswap-backed anonymous large folio swapin
From: fujunjie @ 2026-05-08 20:18 UTC (permalink / raw)
  To: Andrew Morton, Chris Li, Kairui Song, Johannes Weiner, Nhat Pham,
	Yosry Ahmed
  Cc: linux-mm, linux-kernel, linux-doc, Jonathan Corbet,
	David Hildenbrand, Ryan Roberts, Barry Song, Baolin Wang,
	Chengming Zhou, Baoquan He, Lorenzo Stoakes

Hi,

This RFC explores anonymous large folio swapin when a contiguous swap
range is backed consistently by zswap.

Large folio swapout to zswap is already supported by storing each base
page in the folio as a separate zswap entry. The anonymous synchronous
swapin path has remained order-0 once zswap has ever been enabled:
zswap_load() rejected large folios, and alloc_swap_folio() avoided large
folio allocation to protect against mixed backend ranges.

This RFC keeps the scope intentionally conservative. It does not try to
read one large folio from mixed zswap and disk backends, and it does not
change shmem swapin. Shmem still has its existing zswap fallback and is
left for later discussion. For anonymous swapin, the backend rule is made
explicit:

- a range fully absent from zswap can keep using the disk backend
- a range fully present in zswap can be decompressed into a large folio
- a mixed zswap/non-zswap range falls back to order-0 swapin

The series adds a zswap range query helper, teaches zswap_load() to
decompress all-zswap large folios one base page at a time, accounts mTHP
swpin for zswap-loaded large folios, retries synchronous large-folio
insertion races with order-0 swapin, and removes the anonymous
zswap-never-enabled restriction once mixed ranges are filtered.

I tested the series with a full bzImage build using CONFIG_ZSWAP=y,
CONFIG_ZRAM=y, CONFIG_MEMCG=y and CONFIG_THP_SWAP=y.

The QEMU/KVM runs covered both the fully-zswap path and the mixed-backend
fallback path. In the all-zswap run, a 512MiB anonymous mapping was faulted
as 8192 64KiB groups, reclaimed into zswap, and faulted back. Reclaim
reported mthp64_zswpout=8192 and zswpout=131072. Refault then reported
mthp64_swpin=8192 and zswpin=131072, and pagemap/kpageflags showed 8192
order-4 THP groups in the mapping.

In the mixed-backend run, the workload used a 64MiB anonymous mapping
split into 1024 64KiB groups. After shrinker debugfs wrote back exactly
one zswap base-page entry, refault left 1023 order-4 THP groups and one
order-0 mixed group. The kernel stats matched that shape:
mthp64_swpin=1023, zswpin=16383 and zswpwb=1.

CONFIG_SHRINKER_DEBUG is only a test aid for making that one zswap
writeback deterministic; it is not required by the implementation.

Nhat Pham's active Virtual Swap Space series is adjacent work. It moves
swap cache and zswap entry state into a virtual swap descriptor, and lists
mixed backing THP swapin as a future use case. This RFC is independent and
works with the current swap/zswap infrastructure, but may need rebasing if
VSS lands first.

Feedback would be especially helpful on:

1. whether it makes sense to support all-zswap large folio swapin first,
   while keeping mixed zswap/disk ranges on the order-0 fallback path
2. whether a follow-up for mixed zswap/disk large folio swapin would be
   useful after this RFC

Thanks.

---

fujunjie (5):
  mm: zswap: decompress into a folio subpage
  mm: zswap: add a zswap entry batch helper
  mm: zswap: load fully stored large folios
  mm: swap: fall back to order-0 after large swapin races
  mm: swap: allow zswap-backed large folio swapin

 Documentation/admin-guide/mm/transhuge.rst |   4 +-
 include/linux/zswap.h                      |   9 ++
 mm/memory.c                                |  67 ++++++++-----
 mm/swap_state.c                            |  23 +++--
 mm/zswap.c                                 | 111 ++++++++++++++++-----
 5 files changed, 154 insertions(+), 60 deletions(-)


base-commit: 917719c412c48687d4a176965d1fa35320ec457c
-- 
2.34.1


^ permalink raw reply

* [PATCH v2] killswitch: add per-function short-circuit mitigation primitive
From: Sasha Levin @ 2026-05-08 19:57 UTC (permalink / raw)
  To: corbet, akpm
  Cc: skhan, linux-doc, linux-kernel, linux-kselftest, gregkh,
	Sasha Levin

When a kernel (security) issue goes public, fleets stay exposed until a patched
kernel is built, distributed, and rebooted into.

For many such issues the simplest mitigation is to stop calling the buggy
function. Killswitch provides that. An admin writes:

    echo "engage af_alg_sendmsg -1" \
        > /sys/kernel/security/killswitch/control

After this, af_alg_sendmsg() returns -EPERM on every call without
running its body. The mitigation takes effect immediately, and is dropped on
the next reboot -- by which point a patched kernel is hopefully in place.

A lot of recent kernel issues sit in code paths most installs only have enabled
to support a relative minority of users: AF_ALG, ksmbd, nf_tables, vsock, ax25,
and friends.

For most users, the cost of "this socket family stops working for the day" is
much smaller than the cost of running a known vulnerable kernel until the fix
land.

Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Changes since v1:
  - Add LOCKDOWN_KILLSWITCH (Jon)
  - Convert ks_attr.refcnt from refcount_t to kref. (Greg)
  - Document why ks_attr.retval is atomic_long_t. (Greg)

 Documentation/admin-guide/index.rst           |   1 +
 Documentation/admin-guide/killswitch.rst      | 159 ++++
 Documentation/admin-guide/tainted-kernels.rst |   8 +
 MAINTAINERS                                   |  11 +
 include/linux/killswitch.h                    |  19 +
 include/linux/panic.h                         |   3 +-
 include/linux/security.h                      |   1 +
 init/Kconfig                                  |   2 +
 kernel/Kconfig.killswitch                     |  31 +
 kernel/Makefile                               |   1 +
 kernel/killswitch.c                           | 858 ++++++++++++++++++
 kernel/panic.c                                |   1 +
 lib/Kconfig.debug                             |  13 +
 lib/Makefile                                  |   1 +
 lib/test_killswitch.c                         |  85 ++
 security/security.c                           |   1 +
 tools/testing/selftests/Makefile              |   1 +
 tools/testing/selftests/killswitch/.gitignore |   1 +
 tools/testing/selftests/killswitch/Makefile   |   8 +
 .../selftests/killswitch/cve_31431_test.c     | 162 ++++
 .../selftests/killswitch/killswitch_test.sh   | 147 +++
 21 files changed, 1513 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/admin-guide/killswitch.rst
 create mode 100644 include/linux/killswitch.h
 create mode 100644 kernel/Kconfig.killswitch
 create mode 100644 kernel/killswitch.c
 create mode 100644 lib/test_killswitch.c
 create mode 100644 tools/testing/selftests/killswitch/.gitignore
 create mode 100644 tools/testing/selftests/killswitch/Makefile
 create mode 100644 tools/testing/selftests/killswitch/cve_31431_test.c
 create mode 100755 tools/testing/selftests/killswitch/killswitch_test.sh

diff --git a/Documentation/admin-guide/index.rst b/Documentation/admin-guide/index.rst
index cd28dfe91b060..ca37dd70f108d 100644
--- a/Documentation/admin-guide/index.rst
+++ b/Documentation/admin-guide/index.rst
@@ -70,6 +70,7 @@ problems and bugs in particular.
    bug-hunting
    bug-bisect
    tainted-kernels
+   killswitch
    ramoops
    dynamic-debug-howto
    init
diff --git a/Documentation/admin-guide/killswitch.rst b/Documentation/admin-guide/killswitch.rst
new file mode 100644
index 0000000000000..cb967ec348fdc
--- /dev/null
+++ b/Documentation/admin-guide/killswitch.rst
@@ -0,0 +1,159 @@
+.. SPDX-License-Identifier: GPL-2.0
+..
+.. Copyright (C) 2026 Sasha Levin <sashal@kernel.org>
+
+============
+Killswitch
+============
+
+Killswitch lets a privileged operator make a chosen kernel function
+return a fixed value without executing its body, as a temporary
+mitigation for a security bug while a real fix is being prepared.
+
+The function returns the operator-supplied value and nothing else
+runs in its place. There is no allowlist, no return-type check; if
+the kprobe layer accepts the symbol, killswitch engages it. Once
+engaged, the change is in effect on every CPU until ``disengage`` is
+written or the system reboots.
+
+Configuration
+=============
+
+``CONFIG_KILLSWITCH``
+  Enables the feature. Depends on ``SECURITYFS``, ``KPROBES`` (with
+  ftrace support), and ``FUNCTION_ERROR_INJECTION``.
+
+The interface
+=============
+
+::
+
+    /sys/kernel/security/killswitch/
+        engaged                 RO  currently-engaged functions
+        control                 WO  command sink
+        taint                   RO  0 or 1
+        fn/<name>/              per-function directory, created on engage
+            retval              RW  return value
+            hits                RO  per-cpu summed call count
+
+Three commands are accepted by ``control``::
+
+    engage <symbol> <retval>
+    disengage <symbol>
+    disengage_all
+
+Each engage and disengage emits a single ``KERN_WARNING`` line to
+dmesg with the symbol, retval, hit count (on disengage), and the
+operator's identity (uid/auid/sessionid/comm, or ``source=cmdline``).
+
+Engagement is rejected when:
+
+* the symbol is unknown, in a non-traceable section, on the kprobe
+  blacklist, or otherwise refused by ``register_kprobe`` (the error
+  from the kprobe layer is logged and returned to userspace);
+* the symbol is already engaged (``-EBUSY``);
+* the operator does not hold ``CAP_SYS_ADMIN``.
+
+Whatever value the operator writes is what the function returns.
+Writing the wrong type or wrong value lands in the caller as-is.
+
+Boot parameter
+==============
+
+``killswitch=fn1=<val>,fn2=<val>,...``
+
+Parsed early; engagements are applied at the end of kernel init
+once the kprobe subsystem is up. Parse failures emit a warning and
+skip the offending entry; they never panic.
+
+Useful for fleet rollout: when an issue drops, ship the mitigation
+in the bootloader / PXE config and roll the fleet through reboots
+while the real fix is being prepared.
+
+Tainting
+========
+
+The first successful engagement (runtime or boot-time) sets
+``TAINT_KILLSWITCH`` (bit 20, char ``H``). The taint persists across
+``disengage`` until reboot, so an oops on a killswitch-modified
+kernel is identifiable from the banner: ``Tainted: ... H`` tells a
+maintainer to consult ``engaged`` before further triage.
+
+Module unload
+=============
+
+If a module containing an engaged target is unloaded, killswitch
+auto-disengages the entry and emits a ``KERN_WARNING`` so the loss
+of mitigation is visible. Reloading the module does not silently
+re-arm the killswitch; the operator re-engages explicitly.
+
+Choosing the right target
+=========================
+
+A function that *looks* skippable may be relied on by callers for a
+side effect (a lock the caller releases, a refcount the caller
+drops, a scatterlist the caller consumes). The rule of thumb:
+
+  Pick the **highest-level** entry point that contains the bug.
+
+That gives callers no chance to dereference half-initialised state
+from a function whose body was skipped. Two illustrative examples
+from ``crypto/af_alg.c``:
+
+Anti-pattern: ``af_alg_count_tsgl``
+-----------------------------------
+
+``af_alg_count_tsgl()`` returns ``unsigned int`` (the number of TX
+SG entries). Engaging it with retval ``0`` causes the caller in
+``algif_aead.c`` to allocate a 1-entry scatterlist (its
+``if (!entries) entries = 1`` guard) and then walk the *real* TX
+SGL into that undersized destination via ``af_alg_pull_tsgl``,
+producing out-of-bounds writes. **Killswitching here introduces a
+worse bug than the one being mitigated.**
+
+Anti-pattern: ``af_alg_pull_tsgl``
+----------------------------------
+
+``af_alg_pull_tsgl()`` returns ``void``, so any retval is accepted.
+But its caller depends on the per-request SGL being filled in.
+Skipping the body leaves the per-request SGL with NULL pages; the
+next-stage ``memcpy_sglist`` dereferences them and the kernel
+oopses.
+
+Correct pattern: ``af_alg_sendmsg``
+-----------------------------------
+
+``af_alg_sendmsg()`` is the highest-level entry into the AF_ALG
+send path. Engaging it with retval ``-EPERM`` causes every send
+attempt to return -EPERM to userspace; no caller ever sees
+half-initialised state, and any AF_ALG-reachable bug downstream of
+``sendmsg`` is unreachable until the killswitch is disengaged.
+
+The canonical pattern: pick a syscall-handler-shaped function whose
+return value already encodes "this operation didn't happen", and
+let userspace handle the error as it would any other failed
+syscall.
+
+Safety notes
+============
+
+* In-flight calls during ``write()`` to ``control`` may run either
+  the original body or the override. The override is ``return X``,
+  which has no preconditions to violate.
+* SMP visibility comes from ``text_poke_bp()``. ``write()`` to
+  ``control`` returns only after every CPU sees the new path.
+* The ftrace ops unregister waits for in-flight pre-handlers, so
+  freeing the engagement attribute on disengage is safe.
+* Inline functions, freed ``__init`` symbols, and anything compiled
+  away cannot be killswitched. ``register_kprobe`` rejects them
+  with whatever error the kprobe layer chooses.
+
+Diagnostics
+===========
+
+Per-call hits are aggregated in a per-cpu counter readable at
+``/sys/kernel/security/killswitch/fn/<name>/hits``. Per-hit logging
+is not provided to avoid log storms on hot paths.
+
+A ``KILLSWITCH`` entry appears in the kernel taint vector once any
+engagement succeeds (also visible as ``H`` in the oops banner).
diff --git a/Documentation/admin-guide/tainted-kernels.rst b/Documentation/admin-guide/tainted-kernels.rst
index 9ead927a37c0f..71a6e3364eddc 100644
--- a/Documentation/admin-guide/tainted-kernels.rst
+++ b/Documentation/admin-guide/tainted-kernels.rst
@@ -102,6 +102,7 @@ Bit  Log  Number  Reason that got the kernel tainted
  17  _/T  131072  kernel was built with the struct randomization plugin
  18  _/N  262144  an in-kernel test has been run
  19  _/J  524288  userspace used a mutating debug operation in fwctl
+ 20  _/H 1048576  killswitch override engaged (function short-circuited)
 ===  ===  ======  ========================================================
 
 Note: The character ``_`` is representing a blank in this table to make reading
@@ -189,3 +190,10 @@ More detailed explanation for tainting
  19) ``J`` if userspace opened /dev/fwctl/* and performed a FWTCL_RPC_DEBUG_WRITE
      to use the devices debugging features. Device debugging features could
      cause the device to malfunction in undefined ways.
+
+ 20) ``H`` if the killswitch primitive (see
+     Documentation/admin-guide/killswitch.rst) has been engaged on at least
+     one function. The kernel is no longer running its source: at least one
+     function has been short-circuited to return a fixed value. The taint
+     persists across ``disengage`` until the next reboot — once the running
+     image has been modified, oops triage must reflect that.
diff --git a/MAINTAINERS b/MAINTAINERS
index 882214b0e7db5..61851ef1d9b1c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14347,6 +14347,17 @@ F:	lib/Kconfig.kmsan
 F:	mm/kmsan/
 F:	scripts/Makefile.kmsan
 
+KILLSWITCH (function short-circuit mitigation)
+M:	Sasha Levin <sashal@kernel.org>
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+F:	Documentation/admin-guide/killswitch.rst
+F:	include/linux/killswitch.h
+F:	kernel/Kconfig.killswitch
+F:	kernel/killswitch.c
+F:	lib/test_killswitch.c
+F:	tools/testing/selftests/killswitch/
+
 KPROBES
 M:	Naveen N Rao <naveen@kernel.org>
 M:	"David S. Miller" <davem@davemloft.net>
diff --git a/include/linux/killswitch.h b/include/linux/killswitch.h
new file mode 100644
index 0000000000000..c18515bec09f1
--- /dev/null
+++ b/include/linux/killswitch.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2026 Sasha Levin <sashal@kernel.org>
+ */
+#ifndef _LINUX_KILLSWITCH_H
+#define _LINUX_KILLSWITCH_H
+
+#ifdef CONFIG_KILLSWITCH
+int killswitch_engage(const char *symbol, long retval);
+int killswitch_disengage(const char *symbol);
+bool killswitch_is_engaged(const char *symbol);
+#else
+static inline int killswitch_engage(const char *symbol, long retval)
+{ return -ENOSYS; }
+static inline int killswitch_disengage(const char *symbol) { return -ENOSYS; }
+static inline bool killswitch_is_engaged(const char *symbol) { return false; }
+#endif
+
+#endif /* _LINUX_KILLSWITCH_H */
diff --git a/include/linux/panic.h b/include/linux/panic.h
index f1dd417e54b29..6699261a61f13 100644
--- a/include/linux/panic.h
+++ b/include/linux/panic.h
@@ -88,7 +88,8 @@ static inline void set_arch_panic_timeout(int timeout, int arch_default_timeout)
 #define TAINT_RANDSTRUCT		17
 #define TAINT_TEST			18
 #define TAINT_FWCTL			19
-#define TAINT_FLAGS_COUNT		20
+#define TAINT_KILLSWITCH		20
+#define TAINT_FLAGS_COUNT		21
 #define TAINT_FLAGS_MAX			((1UL << TAINT_FLAGS_COUNT) - 1)
 
 struct taint_flag {
diff --git a/include/linux/security.h b/include/linux/security.h
index 41d7367cf4036..038027c33ba1a 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -146,6 +146,7 @@ enum lockdown_reason {
 	LOCKDOWN_DBG_WRITE_KERNEL,
 	LOCKDOWN_RTAS_ERROR_INJECTION,
 	LOCKDOWN_XEN_USER_ACTIONS,
+	LOCKDOWN_KILLSWITCH,
 	LOCKDOWN_INTEGRITY_MAX,
 	LOCKDOWN_KCORE,
 	LOCKDOWN_KPROBES,
diff --git a/init/Kconfig b/init/Kconfig
index 2937c4d308aec..5368dd4b5c65b 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -2278,6 +2278,8 @@ config ASN1
 
 source "kernel/Kconfig.locks"
 
+source "kernel/Kconfig.killswitch"
+
 config ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
 	bool
 
diff --git a/kernel/Kconfig.killswitch b/kernel/Kconfig.killswitch
new file mode 100644
index 0000000000000..067d41087e8da
--- /dev/null
+++ b/kernel/Kconfig.killswitch
@@ -0,0 +1,31 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Killswitch: per-function short-circuit mitigation primitive.
+#
+# Copyright (C) 2026 Sasha Levin <sashal@kernel.org>
+#
+
+config KILLSWITCH
+	bool "Killswitch: short-circuit a kernel function as a CVE mitigation"
+	depends on SECURITYFS
+	depends on KPROBES && HAVE_KPROBES_ON_FTRACE
+	depends on HAVE_FUNCTION_ERROR_INJECTION
+	select FUNCTION_ERROR_INJECTION
+	help
+	  Provide an admin-facing mechanism to make a chosen kernel function
+	  return a fixed value without executing its body, as a temporary
+	  mitigation for a security bug before a real fix is available.
+
+	  Operators write "engage <symbol> <retval> [reason]" to
+	  /sys/kernel/security/killswitch/control. The function entry is
+	  redirected via a kprobe whose pre-handler sets the chosen return
+	  value and short-circuits the call. There is no allowlist,
+	  denylist, or return-type validation: if the kprobe layer accepts
+	  the symbol the engagement proceeds, otherwise its error is
+	  returned to userspace.
+
+	  This is *not* livepatch: there is no replacement implementation,
+	  the function simply returns the chosen value. Engaging a killswitch
+	  taints the kernel (TAINT_KILLSWITCH, 'H'). Requires CAP_SYS_ADMIN.
+
+	  If unsure, say N.
diff --git a/kernel/Makefile b/kernel/Makefile
index 6785982013dce..b3e408d9f275e 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -100,6 +100,7 @@ obj-$(CONFIG_GCOV_KERNEL) += gcov/
 obj-$(CONFIG_KCOV) += kcov.o
 obj-$(CONFIG_KPROBES) += kprobes.o
 obj-$(CONFIG_FAIL_FUNCTION) += fail_function.o
+obj-$(CONFIG_KILLSWITCH) += killswitch.o
 obj-$(CONFIG_KGDB) += debug/
 obj-$(CONFIG_DETECT_HUNG_TASK) += hung_task.o
 obj-$(CONFIG_LOCKUP_DETECTOR) += watchdog.o
diff --git a/kernel/killswitch.c b/kernel/killswitch.c
new file mode 100644
index 0000000000000..50993923898d3
--- /dev/null
+++ b/kernel/killswitch.c
@@ -0,0 +1,858 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Per-function short-circuit mitigation.
+ *
+ * Copyright (C) 2026 Sasha Levin <sashal@kernel.org>
+ *
+ * Engaging a killswitch installs a kprobe at the function's entry
+ * whose pre-handler sets the return register and skips the body via
+ * override_function_with_return().  Operator interface lives at
+ * /sys/kernel/security/killswitch/.
+ */
+
+#include <linux/audit.h>
+#include <linux/capability.h>
+#include <linux/cred.h>
+#include <linux/ctype.h>
+#include <linux/error-injection.h>
+#include <linux/init.h>
+#include <linux/killswitch.h>
+#include <linux/kprobes.h>
+#include <linux/kref.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/notifier.h>
+#include <linux/panic.h>
+#include <linux/percpu.h>
+#include <linux/printk.h>
+#include <linux/sched.h>
+#include <linux/security.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
+#include <linux/uidgid.h>
+
+struct ks_attr {
+	struct list_head	list;
+	struct kprobe		kp;
+	/* atomic so a writer racing an in-flight call can't tear the long. */
+	atomic_long_t		retval;
+	/* false once disengaged; per-fn file ops then return -EIDRM. */
+	bool			engaged;
+	unsigned long __percpu	*hits;
+	struct dentry		*dir;
+	/* engaged_list holds one ref; each open per-fn fd holds one. */
+	struct kref		refcnt;
+};
+
+static DEFINE_MUTEX(ks_lock);
+static LIST_HEAD(ks_engaged_list);
+static struct dentry *ks_root_dir;
+static struct dentry *ks_fn_dir;	/* parent for per-fn directories */
+
+/* ------------------------------------------------------------------ *
+ * Pre-handler: the actual override                                   *
+ * ------------------------------------------------------------------ */
+
+static int ks_kprobe_pre_handler(struct kprobe *kp, struct pt_regs *regs)
+{
+	struct ks_attr *attr = container_of(kp, struct ks_attr, kp);
+
+	this_cpu_inc(*attr->hits);
+	regs_set_return_value(regs, (unsigned long)atomic_long_read(&attr->retval));
+	override_function_with_return(regs);
+	return 1;
+}
+NOKPROBE_SYMBOL(ks_kprobe_pre_handler);
+
+/* Defined non-NULL so the kprobe layer keeps the IPMODIFY ops. */
+static void ks_kprobe_post_handler(struct kprobe *kp, struct pt_regs *regs,
+				   unsigned long flags)
+{
+}
+
+/* ------------------------------------------------------------------ *
+ * Attribute lifecycle                                                *
+ * ------------------------------------------------------------------ */
+
+static struct ks_attr *ks_attr_lookup(const char *symbol)
+{
+	struct ks_attr *attr;
+
+	list_for_each_entry(attr, &ks_engaged_list, list)
+		if (!strcmp(attr->kp.symbol_name, symbol))
+			return attr;
+	return NULL;
+}
+
+static unsigned long ks_attr_hits(const struct ks_attr *attr)
+{
+	unsigned long total = 0;
+	int cpu;
+
+	for_each_possible_cpu(cpu)
+		total += *per_cpu_ptr(attr->hits, cpu);
+	return total;
+}
+
+static void ks_attr_destroy(struct ks_attr *attr)
+{
+	if (!attr)
+		return;
+	free_percpu(attr->hits);
+	kfree(attr->kp.symbol_name);
+	kfree(attr);
+}
+
+static void ks_attr_kref_release(struct kref *kref)
+{
+	ks_attr_destroy(container_of(kref, struct ks_attr, refcnt));
+}
+
+static void ks_attr_get(struct ks_attr *attr)
+{
+	kref_get(&attr->refcnt);
+}
+
+static void ks_attr_put(struct ks_attr *attr)
+{
+	kref_put(&attr->refcnt, ks_attr_kref_release);
+}
+
+static struct ks_attr *ks_attr_alloc(const char *symbol)
+{
+	struct ks_attr *attr;
+
+	attr = kzalloc(sizeof(*attr), GFP_KERNEL);
+	if (!attr)
+		return NULL;
+
+	attr->kp.symbol_name = kstrdup(symbol, GFP_KERNEL);
+	if (!attr->kp.symbol_name)
+		goto err;
+
+	attr->hits = alloc_percpu(unsigned long);
+	if (!attr->hits)
+		goto err;
+
+	attr->kp.pre_handler = ks_kprobe_pre_handler;
+	attr->kp.post_handler = ks_kprobe_post_handler;
+	INIT_LIST_HEAD(&attr->list);
+	kref_init(&attr->refcnt);
+	return attr;
+
+err:
+	ks_attr_destroy(attr);
+	return NULL;
+}
+
+/* ------------------------------------------------------------------ *
+ * Securityfs: per-fn attribute files                                 *
+ * ------------------------------------------------------------------ */
+
+/*
+ * Look up by symbol name (the parent dentry's basename) under
+ * ks_lock and confirm attr->dir is the file's parent dentry.  This
+ * binds the fd to the engagement it was opened against and avoids
+ * dereferencing inode->i_private, which a racing disengage may have
+ * freed.  d_parent is stable for the open's lifetime via the file's
+ * dentry reference.
+ */
+static int ks_attr_open(struct inode *inode, struct file *file)
+{
+	struct dentry *parent = file->f_path.dentry->d_parent;
+	const char *name = parent->d_name.name;
+	struct ks_attr *attr;
+
+	mutex_lock(&ks_lock);
+	attr = ks_attr_lookup(name);
+	if (attr && attr->dir == parent)
+		ks_attr_get(attr);
+	else
+		attr = NULL;
+	mutex_unlock(&ks_lock);
+	if (!attr)
+		return -ENOENT;
+	file->private_data = attr;
+	return 0;
+}
+
+static int ks_attr_release(struct inode *inode, struct file *file)
+{
+	ks_attr_put(file->private_data);
+	file->private_data = NULL;
+	return 0;
+}
+
+/* Caller must hold ks_lock. */
+static int ks_attr_check_live(const struct ks_attr *attr)
+{
+	return attr->engaged ? 0 : -EIDRM;
+}
+
+static ssize_t ks_retval_read(struct file *file, char __user *ubuf,
+			      size_t count, loff_t *ppos)
+{
+	struct ks_attr *attr = file->private_data;
+	char buf[32];
+	long val;
+	int ret, len;
+
+	mutex_lock(&ks_lock);
+	ret = ks_attr_check_live(attr);
+	val = atomic_long_read(&attr->retval);
+	mutex_unlock(&ks_lock);
+	if (ret)
+		return ret;
+	len = scnprintf(buf, sizeof(buf), "%ld\n", val);
+	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
+}
+
+static ssize_t ks_retval_write(struct file *file, const char __user *ubuf,
+			       size_t count, loff_t *ppos)
+{
+	struct ks_attr *attr = file->private_data;
+	char buf[32];
+	long val;
+	int ret;
+
+	if (count >= sizeof(buf))
+		return -EINVAL;
+	if (copy_from_user(buf, ubuf, count))
+		return -EFAULT;
+	buf[count] = '\0';
+	strim(buf);
+
+	ret = kstrtol(buf, 0, &val);
+	if (ret)
+		return ret;
+
+	mutex_lock(&ks_lock);
+	ret = ks_attr_check_live(attr);
+	if (!ret)
+		atomic_long_set(&attr->retval, val);
+	mutex_unlock(&ks_lock);
+
+	return ret ? ret : count;
+}
+
+static const struct file_operations ks_retval_fops = {
+	.open		= ks_attr_open,
+	.release	= ks_attr_release,
+	.read		= ks_retval_read,
+	.write	= ks_retval_write,
+	.llseek	= default_llseek,
+};
+
+static ssize_t ks_hits_read(struct file *file, char __user *ubuf,
+			    size_t count, loff_t *ppos)
+{
+	struct ks_attr *attr = file->private_data;
+	char buf[32];
+	unsigned long hits;
+	int ret, len;
+
+	mutex_lock(&ks_lock);
+	ret = ks_attr_check_live(attr);
+	hits = ks_attr_hits(attr);
+	mutex_unlock(&ks_lock);
+	if (ret)
+		return ret;
+	len = scnprintf(buf, sizeof(buf), "%lu\n", hits);
+	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
+}
+
+static const struct file_operations ks_hits_fops = {
+	.open		= ks_attr_open,
+	.release	= ks_attr_release,
+	.read		= ks_hits_read,
+	.llseek		= default_llseek,
+};
+
+static int ks_create_attr_dir(struct ks_attr *attr)
+{
+	struct dentry *d;
+
+	attr->dir = securityfs_create_dir(attr->kp.symbol_name, ks_fn_dir);
+	if (IS_ERR(attr->dir))
+		return PTR_ERR(attr->dir);
+
+	/* ks_attr_open looks the attr up by name; i_private is unused. */
+	d = securityfs_create_file("retval", 0600, attr->dir,
+				   NULL, &ks_retval_fops);
+	if (IS_ERR(d))
+		goto err;
+	d = securityfs_create_file("hits", 0400, attr->dir,
+				   NULL, &ks_hits_fops);
+	if (IS_ERR(d))
+		goto err;
+	return 0;
+err:
+	securityfs_remove(attr->dir);
+	attr->dir = NULL;
+	return PTR_ERR(d);
+}
+
+/* ------------------------------------------------------------------ *
+ * Engage / disengage                                                 *
+ * ------------------------------------------------------------------ */
+
+static int __ks_engage(const char *symbol, long retval, bool from_cmdline)
+{
+	struct ks_attr *attr;
+	int ret;
+
+	if (!symbol || !*symbol)
+		return -EINVAL;
+
+	if (!from_cmdline) {
+		ret = security_locked_down(LOCKDOWN_KILLSWITCH);
+		if (ret)
+			return ret;
+	}
+
+	mutex_lock(&ks_lock);
+
+	if (ks_attr_lookup(symbol)) {
+		ret = -EBUSY;
+		goto out_unlock;
+	}
+
+	attr = ks_attr_alloc(symbol);
+	if (!attr) {
+		ret = -ENOMEM;
+		goto out_unlock;
+	}
+
+	atomic_long_set(&attr->retval, retval);
+
+	ret = register_kprobe(&attr->kp);
+	if (ret) {
+		pr_warn("killswitch: register_kprobe(%s) failed: %d\n",
+			symbol, ret);
+		ks_attr_put(attr);
+		goto out_unlock;
+	}
+
+	ret = ks_create_attr_dir(attr);
+	if (ret) {
+		unregister_kprobe(&attr->kp);
+		ks_attr_put(attr);
+		goto out_unlock;
+	}
+
+	list_add_tail(&attr->list, &ks_engaged_list);
+	attr->engaged = true;
+	add_taint(TAINT_KILLSWITCH, LOCKDEP_STILL_OK);
+
+	if (from_cmdline) {
+		pr_warn("killswitch: engage %s=%ld source=cmdline\n",
+			symbol, retval);
+	} else {
+		pr_warn("killswitch: engage %s=%ld uid=%u auid=%u ses=%u comm=%s\n",
+			symbol, retval,
+			from_kuid(&init_user_ns, current_uid()),
+			from_kuid(&init_user_ns, audit_get_loginuid(current)),
+			audit_get_sessionid(current),
+			current->comm);
+	}
+	ret = 0;
+
+out_unlock:
+	mutex_unlock(&ks_lock);
+	return ret;
+}
+
+int killswitch_engage(const char *symbol, long retval)
+{
+	return __ks_engage(symbol, retval, false);
+}
+
+static int __ks_disengage(const char *symbol)
+{
+	struct ks_attr *attr;
+	unsigned long hits;
+	int ret = 0;
+
+	mutex_lock(&ks_lock);
+	attr = ks_attr_lookup(symbol);
+	if (!attr) {
+		ret = -ENOENT;
+		goto out_unlock;
+	}
+
+	unregister_kprobe(&attr->kp);
+	attr->engaged = false;
+	list_del(&attr->list);
+	hits = ks_attr_hits(attr);
+	securityfs_remove(attr->dir);
+
+	pr_warn("killswitch: disengage %s hits=%lu uid=%u auid=%u ses=%u comm=%s\n",
+		symbol, hits,
+		from_kuid(&init_user_ns, current_uid()),
+		from_kuid(&init_user_ns, audit_get_loginuid(current)),
+		audit_get_sessionid(current),
+		current->comm);
+
+	/* unregister_kprobe() already waited out in-flight pre-handlers. */
+	ks_attr_put(attr);
+
+out_unlock:
+	mutex_unlock(&ks_lock);
+	return ret;
+}
+
+int killswitch_disengage(const char *symbol)
+{
+	return __ks_disengage(symbol);
+}
+
+bool killswitch_is_engaged(const char *symbol)
+{
+	bool engaged;
+
+	mutex_lock(&ks_lock);
+	engaged = ks_attr_lookup(symbol) != NULL;
+	mutex_unlock(&ks_lock);
+	return engaged;
+}
+
+static void ks_disengage_all_locked(void)
+{
+	struct ks_attr *attr, *n;
+
+	list_for_each_entry_safe(attr, n, &ks_engaged_list, list) {
+		unregister_kprobe(&attr->kp);
+		attr->engaged = false;
+		list_del(&attr->list);
+		securityfs_remove(attr->dir);
+		pr_warn("killswitch: disengage %s hits=%lu (disengage_all)\n",
+			attr->kp.symbol_name, ks_attr_hits(attr));
+		ks_attr_put(attr);
+	}
+}
+
+/* ------------------------------------------------------------------ *
+ * Module unload: drop engagements on functions in the going module   *
+ * ------------------------------------------------------------------ */
+
+static int ks_module_notify(struct notifier_block *nb, unsigned long action,
+			    void *data)
+{
+	struct module *mod = data;
+	struct ks_attr *attr, *n;
+
+	if (action != MODULE_STATE_GOING)
+		return NOTIFY_DONE;
+
+	mutex_lock(&ks_lock);
+	list_for_each_entry_safe(attr, n, &ks_engaged_list, list) {
+		if (!attr->kp.addr ||
+		    __module_address((unsigned long)attr->kp.addr) != mod)
+			continue;
+
+		pr_warn("killswitch: %s mitigation lost: module %s unloading; re-engage after reload if still needed\n",
+			attr->kp.symbol_name, mod->name);
+		unregister_kprobe(&attr->kp);
+		attr->engaged = false;
+		list_del(&attr->list);
+		securityfs_remove(attr->dir);
+		ks_attr_put(attr);
+	}
+	mutex_unlock(&ks_lock);
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block ks_module_nb = {
+	.notifier_call = ks_module_notify,
+};
+
+/* ------------------------------------------------------------------ *
+ * Top-level securityfs files: control / engaged / taint              *
+ * ------------------------------------------------------------------ */
+
+static int ks_engaged_show(struct seq_file *m, void *v)
+{
+	struct ks_attr *attr;
+
+	mutex_lock(&ks_lock);
+	list_for_each_entry(attr, &ks_engaged_list, list) {
+		seq_printf(m, "%s retval=%ld hits=%lu\n",
+			   attr->kp.symbol_name,
+			   atomic_long_read(&attr->retval),
+			   ks_attr_hits(attr));
+	}
+	mutex_unlock(&ks_lock);
+	return 0;
+}
+
+static int ks_engaged_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, ks_engaged_show, NULL);
+}
+
+static const struct file_operations ks_engaged_fops = {
+	.open		= ks_engaged_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static ssize_t ks_taint_read(struct file *file, char __user *ubuf,
+			     size_t count, loff_t *ppos)
+{
+	char buf[4];
+	int len;
+
+	len = scnprintf(buf, sizeof(buf), "%d\n",
+			test_taint(TAINT_KILLSWITCH) ? 1 : 0);
+	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
+}
+
+static const struct file_operations ks_taint_fops = {
+	.open	= simple_open,
+	.read	= ks_taint_read,
+	.llseek	= default_llseek,
+};
+
+/*
+ * control: parse one of:
+ *   engage <symbol> <retval>
+ *   disengage <symbol>
+ *   disengage_all
+ */
+static ssize_t ks_control_write(struct file *file, const char __user *ubuf,
+				size_t count, loff_t *ppos)
+{
+	char *buf, *cur, *verb, *sym, *retstr;
+	long retval = 0;
+	int ret;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (count == 0 || count > 4096)
+		return -EINVAL;
+
+	buf = memdup_user_nul(ubuf, count);
+	if (IS_ERR(buf))
+		return PTR_ERR(buf);
+
+	cur = strim(buf);
+	verb = strsep(&cur, " \t\n");
+	if (!verb || !*verb) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (!strcmp(verb, "disengage_all")) {
+		mutex_lock(&ks_lock);
+		ks_disengage_all_locked();
+		mutex_unlock(&ks_lock);
+		ret = count;
+		goto out;
+	}
+
+	sym = strsep(&cur, " \t\n");
+	if (!sym || !*sym) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (!strcmp(verb, "disengage")) {
+		ret = __ks_disengage(sym);
+		ret = ret ? ret : count;
+		goto out;
+	}
+
+	if (strcmp(verb, "engage")) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	retstr = strsep(&cur, " \t\n");
+	if (!retstr || !*retstr) {
+		ret = -EINVAL;
+		goto out;
+	}
+	if (kstrtol(retstr, 0, &retval)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = killswitch_engage(sym, retval);
+	if (!ret)
+		ret = count;
+
+out:
+	kfree(buf);
+	return ret;
+}
+
+static const struct file_operations ks_control_fops = {
+	.open	= simple_open,
+	.write	= ks_control_write,
+	.llseek	= noop_llseek,
+};
+
+/* ------------------------------------------------------------------ *
+ * Boot parameter:                                                    *
+ *   killswitch=fn1=-1:reason,fn2=0,fn3=void                          *
+ * ------------------------------------------------------------------ */
+
+#define KS_BOOT_BUF 1024
+static char ks_boot_buf[KS_BOOT_BUF] __initdata;
+static bool ks_boot_present __initdata;
+
+static int __init ks_boot_setup(char *str)
+{
+	if (!str)
+		return 0;
+	strscpy(ks_boot_buf, str, sizeof(ks_boot_buf));
+	ks_boot_present = true;
+	return 1;
+}
+__setup("killswitch=", ks_boot_setup);
+
+static void __init ks_apply_boot_params(void)
+{
+	char *cur, *tok;
+	long retval;
+
+	if (!ks_boot_present)
+		return;
+
+	cur = ks_boot_buf;
+	while ((tok = strsep(&cur, ",")) != NULL) {
+		char *eq, *sym, *retstr;
+
+		if (!*tok)
+			continue;
+		eq = strchr(tok, '=');
+		if (!eq) {
+			pr_warn("killswitch: cmdline missing '=': %s\n", tok);
+			continue;
+		}
+		*eq++ = '\0';
+		sym = tok;
+		retstr = eq;
+
+		if (kstrtol(retstr, 0, &retval)) {
+			pr_warn("killswitch: cmdline bad retval %s=%s\n",
+				sym, retstr);
+			continue;
+		}
+
+		if (__ks_engage(sym, retval, true))
+			pr_warn("killswitch: cmdline engage %s failed\n", sym);
+	}
+}
+
+/* ------------------------------------------------------------------ *
+ * Init                                                               *
+ * ------------------------------------------------------------------ */
+
+static int __init killswitch_init(void)
+{
+	struct dentry *d;
+
+	ks_root_dir = securityfs_create_dir("killswitch", NULL);
+	if (IS_ERR(ks_root_dir))
+		return PTR_ERR(ks_root_dir);
+
+	d = securityfs_create_file("control", 0200, ks_root_dir,
+				   NULL, &ks_control_fops);
+	if (IS_ERR(d))
+		goto err;
+	d = securityfs_create_file("engaged", 0444, ks_root_dir,
+				   NULL, &ks_engaged_fops);
+	if (IS_ERR(d))
+		goto err;
+	d = securityfs_create_file("taint", 0444, ks_root_dir,
+				   NULL, &ks_taint_fops);
+	if (IS_ERR(d))
+		goto err;
+
+	ks_fn_dir = securityfs_create_dir("fn", ks_root_dir);
+	if (IS_ERR(ks_fn_dir)) {
+		d = ks_fn_dir;
+		goto err;
+	}
+
+	register_module_notifier(&ks_module_nb);
+	ks_apply_boot_params();
+
+	pr_info("killswitch: ready (sysfs at /sys/kernel/security/killswitch/)\n");
+	return 0;
+
+err:
+	securityfs_remove(ks_root_dir);
+	return PTR_ERR(d);
+}
+late_initcall(killswitch_init);
+
+/* ------------------------------------------------------------------ *
+ * KUnit tests                                                        *
+ * ------------------------------------------------------------------ */
+
+#if IS_ENABLED(CONFIG_KUNIT)
+#include <kunit/test.h>
+
+/* Non-static so kallsyms resolves them without CONFIG_KALLSYMS_ALL. */
+int ks_kunit_target_int(int x);
+void *ks_kunit_target_ptr(int x);
+
+/* noipa keeps the call out-of-line and uneliminated. */
+__attribute__((__noipa__)) int ks_kunit_target_int(int x)
+{
+	return x + 1;
+}
+
+__attribute__((__noipa__)) void *ks_kunit_target_ptr(int x)
+{
+	return ERR_PTR(-EIO);
+}
+
+static int ks_kunit_init(struct kunit *test)
+{
+	if (security_locked_down(LOCKDOWN_KILLSWITCH))
+		kunit_skip(test, "integrity lockdown blocks killswitch_engage()");
+	return 0;
+}
+
+static int ks_kunit_init_lockdown(struct kunit *test)
+{
+	if (!security_locked_down(LOCKDOWN_KILLSWITCH))
+		kunit_skip(test, "requires lockdown=integrity");
+	return 0;
+}
+
+static void ks_disengage_quiet(const char *sym)
+{
+	if (killswitch_is_engaged(sym))
+		killswitch_disengage(sym);
+}
+
+static void ks_test_engage_int(struct kunit *test)
+{
+	int ret;
+
+	ret = killswitch_engage("ks_kunit_target_int", -EPERM);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+	KUNIT_EXPECT_EQ(test, ks_kunit_target_int(7), -EPERM);
+	KUNIT_EXPECT_EQ(test, killswitch_disengage("ks_kunit_target_int"), 0);
+	KUNIT_EXPECT_EQ(test, ks_kunit_target_int(7), 8);
+}
+
+static void ks_test_double_engage(struct kunit *test)
+{
+	KUNIT_ASSERT_EQ(test,
+		killswitch_engage("ks_kunit_target_int", 0), 0);
+	KUNIT_EXPECT_EQ(test,
+		killswitch_engage("ks_kunit_target_int", 0), -EBUSY);
+	ks_disengage_quiet("ks_kunit_target_int");
+}
+
+static void ks_test_disengage_unknown(struct kunit *test)
+{
+	KUNIT_EXPECT_EQ(test,
+		killswitch_disengage("ks_kunit_target_int"), -ENOENT);
+}
+
+static void ks_test_pointer_target(struct kunit *test)
+{
+	long retval = (long)(unsigned long)ERR_PTR(-EACCES);
+
+	KUNIT_ASSERT_EQ(test,
+		killswitch_engage("ks_kunit_target_ptr", retval), 0);
+	KUNIT_EXPECT_TRUE(test, IS_ERR(ks_kunit_target_ptr(0)));
+	KUNIT_EXPECT_EQ(test, PTR_ERR(ks_kunit_target_ptr(0)), -EACCES);
+	ks_disengage_quiet("ks_kunit_target_ptr");
+}
+
+static void ks_test_taint_set(struct kunit *test)
+{
+	KUNIT_ASSERT_EQ(test,
+		killswitch_engage("ks_kunit_target_int", 0), 0);
+	KUNIT_EXPECT_TRUE(test, test_taint(TAINT_KILLSWITCH));
+	ks_disengage_quiet("ks_kunit_target_int");
+	/* taint must persist even after disengage */
+	KUNIT_EXPECT_TRUE(test, test_taint(TAINT_KILLSWITCH));
+}
+
+static void ks_test_hits_counter(struct kunit *test)
+{
+	struct ks_attr *attr;
+	int i;
+
+	KUNIT_ASSERT_EQ(test,
+		killswitch_engage("ks_kunit_target_int", 0), 0);
+
+	for (i = 0; i < 17; i++)
+		(void)ks_kunit_target_int(i);
+
+	mutex_lock(&ks_lock);
+	attr = ks_attr_lookup("ks_kunit_target_int");
+	KUNIT_EXPECT_NOT_NULL(test, attr);
+	if (attr)
+		KUNIT_EXPECT_EQ(test, ks_attr_hits(attr), 17UL);
+	mutex_unlock(&ks_lock);
+
+	ks_disengage_quiet("ks_kunit_target_int");
+}
+
+static struct kunit_case ks_kunit_cases[] = {
+	KUNIT_CASE(ks_test_engage_int),
+	KUNIT_CASE(ks_test_double_engage),
+	KUNIT_CASE(ks_test_disengage_unknown),
+	KUNIT_CASE(ks_test_pointer_target),
+	KUNIT_CASE(ks_test_taint_set),
+	KUNIT_CASE(ks_test_hits_counter),
+	{}
+};
+
+static struct kunit_suite ks_kunit_suite = {
+	.name = "killswitch",
+	.init = ks_kunit_init,
+	.test_cases = ks_kunit_cases,
+};
+
+/*
+ * Lockdown suite. Skipped unless the kernel was booted with
+ * lockdown=integrity (or higher). Run together with
+ * killswitch=ks_kunit_target_int=... on the same cmdline to also
+ * exercise the cmdline-bypass and disengage-under-lockdown paths.
+ */
+static void ks_test_lockdown_runtime_engage(struct kunit *test)
+{
+	KUNIT_EXPECT_EQ(test,
+		killswitch_engage("ks_kunit_target_int", 0), -EPERM);
+}
+
+static void ks_test_lockdown_cmdline_disengage(struct kunit *test)
+{
+	if (!killswitch_is_engaged("ks_kunit_target_int"))
+		kunit_skip(test,
+			   "requires killswitch=ks_kunit_target_int=... on cmdline");
+	KUNIT_EXPECT_EQ(test,
+		killswitch_disengage("ks_kunit_target_int"), 0);
+}
+
+static struct kunit_case ks_kunit_lockdown_cases[] = {
+	KUNIT_CASE(ks_test_lockdown_runtime_engage),
+	KUNIT_CASE(ks_test_lockdown_cmdline_disengage),
+	{}
+};
+
+static struct kunit_suite ks_kunit_lockdown_suite = {
+	.name = "killswitch_lockdown",
+	.init = ks_kunit_init_lockdown,
+	.test_cases = ks_kunit_lockdown_cases,
+};
+
+kunit_test_suites(&ks_kunit_suite, &ks_kunit_lockdown_suite);
+
+#endif /* CONFIG_KUNIT */
+
diff --git a/kernel/panic.c b/kernel/panic.c
index 20feada5319d4..8ee174c7b7dd0 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -825,6 +825,7 @@ const struct taint_flag taint_flags[TAINT_FLAGS_COUNT] = {
 	TAINT_FLAG(RANDSTRUCT,			'T', ' '),
 	TAINT_FLAG(TEST,			'N', ' '),
 	TAINT_FLAG(FWCTL,			'J', ' '),
+	TAINT_FLAG(KILLSWITCH,			'H', ' '),
 };
 
 #undef TAINT_FLAG
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 8ff5adcfe1e0a..5770639c7b0ea 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -3349,6 +3349,19 @@ config TEST_HMM
 
 	  If unsure, say N.
 
+config TEST_KILLSWITCH
+	tristate "Test module for the killswitch mitigation primitive"
+	depends on KILLSWITCH && DEBUG_FS
+	depends on m
+	help
+	  Build a module that exposes a deliberately-vulnerable function
+	  ks_test_vuln() and a debugfs trigger /sys/kernel/debug/test_killswitch/fire.
+	  The killswitch selftest in tools/testing/selftests/killswitch/
+	  uses this to confirm engaging a killswitch suppresses the BUG()
+	  the function would otherwise hit.
+
+	  If unsure, say N.
+
 config TEST_FREE_PAGES
 	tristate "Test freeing pages"
 	help
diff --git a/lib/Makefile b/lib/Makefile
index f33a24bf1c19a..d763225340674 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -100,6 +100,7 @@ obj-$(CONFIG_TEST_MEMCAT_P) += test_memcat_p.o
 obj-$(CONFIG_TEST_OBJAGG) += test_objagg.o
 obj-$(CONFIG_TEST_MEMINIT) += test_meminit.o
 obj-$(CONFIG_TEST_LOCKUP) += test_lockup.o
+obj-$(CONFIG_TEST_KILLSWITCH) += test_killswitch.o
 obj-$(CONFIG_TEST_HMM) += test_hmm.o
 obj-$(CONFIG_TEST_FREE_PAGES) += test_free_pages.o
 obj-$(CONFIG_TEST_REF_TRACKER) += test_ref_tracker.o
diff --git a/lib/test_killswitch.c b/lib/test_killswitch.c
new file mode 100644
index 0000000000000..cc2584ad652ff
--- /dev/null
+++ b/lib/test_killswitch.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Test target for the killswitch selftest.  ks_test_vuln() returns
+ * -EBADMSG on a magic input, standing in for "the buggy path runs
+ * and produces a bad outcome".  Engaging killswitch on this function
+ * with retval 0 is the mitigation.
+ *
+ * Copyright (C) 2026 Sasha Levin <sashal@kernel.org>
+ */
+
+#include <linux/debugfs.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+
+#define KS_TEST_MAGIC	0xC0FFEEL
+
+int ks_test_vuln(long magic);
+
+/*
+ * Returns -EBADMSG on the magic input -- stands in for "the buggy
+ * path runs and produces a bad outcome".  Engaging a killswitch on
+ * this function with retval 0 represents the mitigation: even on
+ * the magic input, callers see success because the body never runs.
+ *
+ * noipa prevents inlining/IPA so the call actually reaches the
+ * kprobe-instrumented entry point.
+ */
+noinline int ks_test_vuln(long magic)
+{
+	if (magic == KS_TEST_MAGIC)
+		return -EBADMSG;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ks_test_vuln);
+
+static struct dentry *ks_test_dir;
+
+static ssize_t ks_test_fire_write(struct file *file, const char __user *ubuf,
+				  size_t count, loff_t *ppos)
+{
+	char buf[32];
+	long magic;
+	int ret;
+
+	if (count == 0 || count >= sizeof(buf))
+		return -EINVAL;
+	if (copy_from_user(buf, ubuf, count))
+		return -EFAULT;
+	buf[count] = '\0';
+
+	ret = kstrtol(strim(buf), 0, &magic);
+	if (ret)
+		return ret;
+
+	ret = ks_test_vuln(magic);
+	return ret ? ret : count;
+}
+
+static const struct file_operations ks_test_fire_fops = {
+	.write	= ks_test_fire_write,
+	.open	= simple_open,
+	.llseek	= noop_llseek,
+};
+
+static int __init test_killswitch_init(void)
+{
+	ks_test_dir = debugfs_create_dir("test_killswitch", NULL);
+	debugfs_create_file("fire", 0200, ks_test_dir, NULL,
+			    &ks_test_fire_fops);
+	pr_info("test_killswitch: loaded (magic=0x%lx)\n", KS_TEST_MAGIC);
+	return 0;
+}
+module_init(test_killswitch_init);
+
+static void __exit test_killswitch_exit(void)
+{
+	debugfs_remove_recursive(ks_test_dir);
+}
+module_exit(test_killswitch_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Deliberately-vulnerable target for killswitch selftest");
diff --git a/security/security.c b/security/security.c
index 4e999f0236516..bf700abc911a9 100644
--- a/security/security.c
+++ b/security/security.c
@@ -62,6 +62,7 @@ const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX + 1] = {
 	[LOCKDOWN_DBG_WRITE_KERNEL] = "use of kgdb/kdb to write kernel RAM",
 	[LOCKDOWN_RTAS_ERROR_INJECTION] = "RTAS error injection",
 	[LOCKDOWN_XEN_USER_ACTIONS] = "Xen guest user action",
+	[LOCKDOWN_KILLSWITCH] = "engaging a killswitch",
 	[LOCKDOWN_INTEGRITY_MAX] = "integrity",
 	[LOCKDOWN_KCORE] = "/proc/kcore access",
 	[LOCKDOWN_KPROBES] = "use of kprobes",
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 6e59b8f63e416..04c3f8c5ff229 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -53,6 +53,7 @@ TARGETS += ipc
 TARGETS += ir
 TARGETS += kcmp
 TARGETS += kexec
+TARGETS += killswitch
 TARGETS += kselftest_harness
 TARGETS += kvm
 TARGETS += landlock
diff --git a/tools/testing/selftests/killswitch/.gitignore b/tools/testing/selftests/killswitch/.gitignore
new file mode 100644
index 0000000000000..cbf204ce18615
--- /dev/null
+++ b/tools/testing/selftests/killswitch/.gitignore
@@ -0,0 +1 @@
+cve_31431_test
diff --git a/tools/testing/selftests/killswitch/Makefile b/tools/testing/selftests/killswitch/Makefile
new file mode 100644
index 0000000000000..daf5d001e66c8
--- /dev/null
+++ b/tools/testing/selftests/killswitch/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (C) 2026 Sasha Levin <sashal@kernel.org>
+TEST_GEN_PROGS := cve_31431_test
+TEST_PROGS := killswitch_test.sh
+
+CFLAGS += -O2 -g -std=gnu99 -Wall $(KHDR_INCLUDES)
+
+include ../lib.mk
diff --git a/tools/testing/selftests/killswitch/cve_31431_test.c b/tools/testing/selftests/killswitch/cve_31431_test.c
new file mode 100644
index 0000000000000..1ff817c51d881
--- /dev/null
+++ b/tools/testing/selftests/killswitch/cve_31431_test.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AF_ALG AEAD round-trip prober.  The killswitch selftest uses this
+ * to demonstrate that engaging a killswitch on af_alg_sendmsg
+ * neuters AF_ALG operations (sendmsg returns -EPERM), mitigating
+ * any AF_ALG-reachable bug whose exploit primitive runs from the
+ * send path.
+ *
+ * Exit codes:
+ *   0  AEAD round-trip succeeded (function intact)
+ *   1  AEAD round-trip refused (mitigation engaged)
+ *   2  setup error (no AF_ALG, missing aead/gcm(aes), etc.) -> SKIP
+ *
+ * Copyright (C) 2026 Sasha Levin <sashal@kernel.org>
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <linux/if_alg.h>
+
+#define KEY_LEN		16
+#define IV_LEN		12
+#define AAD_LEN		16
+#define PT_LEN		64
+#define TAG_LEN		16
+#define EXPECTED_LEN	(AAD_LEN + PT_LEN + TAG_LEN)
+
+#ifndef AF_ALG
+#define AF_ALG		38
+#endif
+#ifndef SOL_ALG
+#define SOL_ALG		279
+#endif
+
+int main(void)
+{
+	struct sockaddr_alg sa = {
+		.salg_family = AF_ALG,
+		.salg_type   = "aead",
+		.salg_name   = "gcm(aes)",
+	};
+	unsigned char key[KEY_LEN] = { 0 };
+	unsigned char iv[IV_LEN]   = { 0 };
+	unsigned char buf[1024]    = { 0 };
+	struct msghdr msg = { 0 };
+	struct iovec iov;
+	struct cmsghdr *cmsg;
+	struct af_alg_iv *aiv;
+	char cbuf[256] = { 0 };
+	int *p_op, *p_assoclen;
+	int sk, opfd;
+	ssize_t n;
+
+	sk = socket(AF_ALG, SOCK_SEQPACKET, 0);
+	if (sk < 0) {
+		fprintf(stderr, "AF_ALG socket: %s -- skip\n", strerror(errno));
+		return 2;
+	}
+	if (bind(sk, (struct sockaddr *)&sa, sizeof(sa))) {
+		fprintf(stderr, "bind aead/gcm(aes): %s -- skip\n",
+			strerror(errno));
+		close(sk);
+		return 2;
+	}
+	if (setsockopt(sk, SOL_ALG, ALG_SET_KEY, key, KEY_LEN)) {
+		fprintf(stderr, "ALG_SET_KEY: %s -- skip\n", strerror(errno));
+		close(sk);
+		return 2;
+	}
+	if (setsockopt(sk, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL, TAG_LEN)) {
+		fprintf(stderr, "ALG_SET_AEAD_AUTHSIZE: %s -- skip\n",
+			strerror(errno));
+		close(sk);
+		return 2;
+	}
+
+	opfd = accept(sk, NULL, 0);
+	if (opfd < 0) {
+		fprintf(stderr, "accept: %s -- skip\n", strerror(errno));
+		close(sk);
+		return 2;
+	}
+
+	/* control message: ENCRYPT op + IV + assoclen */
+	msg.msg_control    = cbuf;
+	msg.msg_controllen = CMSG_SPACE(sizeof(int))
+			   + CMSG_SPACE(sizeof(*aiv) + IV_LEN)
+			   + CMSG_SPACE(sizeof(int));
+
+	cmsg = CMSG_FIRSTHDR(&msg);
+	cmsg->cmsg_level = SOL_ALG;
+	cmsg->cmsg_type  = ALG_SET_OP;
+	cmsg->cmsg_len   = CMSG_LEN(sizeof(int));
+	p_op = (int *)CMSG_DATA(cmsg);
+	*p_op = ALG_OP_ENCRYPT;
+
+	cmsg = CMSG_NXTHDR(&msg, cmsg);
+	cmsg->cmsg_level = SOL_ALG;
+	cmsg->cmsg_type  = ALG_SET_IV;
+	cmsg->cmsg_len   = CMSG_LEN(sizeof(*aiv) + IV_LEN);
+	aiv = (struct af_alg_iv *)CMSG_DATA(cmsg);
+	aiv->ivlen = IV_LEN;
+	memcpy(aiv->iv, iv, IV_LEN);
+
+	cmsg = CMSG_NXTHDR(&msg, cmsg);
+	cmsg->cmsg_level = SOL_ALG;
+	cmsg->cmsg_type  = ALG_SET_AEAD_ASSOCLEN;
+	cmsg->cmsg_len   = CMSG_LEN(sizeof(int));
+	p_assoclen = (int *)CMSG_DATA(cmsg);
+	*p_assoclen = AAD_LEN;
+
+	/* AAD || plaintext */
+	memset(buf, 0xaa, AAD_LEN);
+	memset(buf + AAD_LEN, 0x55, PT_LEN);
+	iov.iov_base = buf;
+	iov.iov_len  = AAD_LEN + PT_LEN;
+	msg.msg_iov    = &iov;
+	msg.msg_iovlen = 1;
+
+	n = sendmsg(opfd, &msg, 0);
+	if (n < 0) {
+		/*
+		 * sendmsg refused: this is exactly the killswitch
+		 * af_alg_sendmsg=-EPERM mitigation outcome.  Distinct
+		 * exit code from setup failure so the test script can
+		 * tell them apart.
+		 */
+		fprintf(stderr, "sendmsg: %s -- mitigation engaged?\n",
+			strerror(errno));
+		close(opfd); close(sk);
+		return 1;
+	}
+
+	/* recv: AAD echoed, plus ciphertext + tag */
+	memset(buf, 0, sizeof(buf));
+	n = read(opfd, buf, EXPECTED_LEN);
+	close(opfd); close(sk);
+
+	if (n == 0) {
+		printf("AEAD returned 0 bytes -- killswitch mitigation engaged\n");
+		return 1;
+	}
+	if (n != EXPECTED_LEN) {
+		fprintf(stderr,
+			"AEAD short read: got %zd, expected %d -- mitigated?\n",
+			n, EXPECTED_LEN);
+		return 1;
+	}
+
+	/* sanity: ciphertext (after AAD) shouldn't equal the plaintext bytes */
+	if (memcmp(buf + AAD_LEN, buf + AAD_LEN + 1, PT_LEN - 1) == 0) {
+		fprintf(stderr, "AEAD output looks unencrypted\n");
+		return 2;
+	}
+
+	printf("AEAD round-trip OK (%zd bytes)\n", n);
+	return 0;
+}
diff --git a/tools/testing/selftests/killswitch/killswitch_test.sh b/tools/testing/selftests/killswitch/killswitch_test.sh
new file mode 100755
index 0000000000000..7bfb821ce437f
--- /dev/null
+++ b/tools/testing/selftests/killswitch/killswitch_test.sh
@@ -0,0 +1,147 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# End-to-end killswitch selftest.  Drives the test_killswitch module
+# through an engage/disengage cycle and confirms each transition
+# behaves as expected.  Also runs the AF_ALG mitigation proof.
+#
+# Requirements (see Documentation/admin-guide/killswitch.rst):
+#   - CONFIG_KILLSWITCH=y
+#   - CONFIG_TEST_KILLSWITCH=m
+#   - run as root (CAP_SYS_ADMIN)
+#
+# Copyright (C) 2026 Sasha Levin <sashal@kernel.org>
+#
+
+set -u
+
+KS=/sys/kernel/security/killswitch
+TRIG=/sys/kernel/debug/test_killswitch/fire
+
+NOMOD=0
+SKIP_RC=4
+N=0
+FAIL=0
+
+ksft_pass() { N=$((N+1));    echo "ok $N - $*"; }
+ksft_fail() { N=$((N+1)); FAIL=$((FAIL+1)); echo "not ok $N - $*"; }
+ksft_skip() { echo "ok 1 - SKIP $*"; echo "1..1"; exit $SKIP_RC; }
+
+[[ $EUID -eq 0 ]] || ksft_skip "must be root"
+[[ -d $KS    ]] || ksft_skip "$KS not present (CONFIG_KILLSWITCH disabled?)"
+
+if ! modprobe test_killswitch 2>/dev/null; then
+	NOMOD=1
+fi
+[[ -e $TRIG ]] || ksft_skip "$TRIG missing (test_killswitch.ko not installed?)"
+
+cleanup() {
+	echo "disengage_all" > $KS/control 2>/dev/null || true
+	[[ $NOMOD -eq 0 ]] && rmmod test_killswitch 2>/dev/null || true
+}
+trap cleanup EXIT
+
+# --- pre-engage: bad path runs, write fails with EBADMSG ---
+if echo 0xC0FFEE > $TRIG 2>/dev/null; then
+	ksft_fail "pre-engage: write should have failed (-EBADMSG)"
+else
+	[[ $? -ne 0 ]] && ksft_pass "pre-engage: bad path returns error" \
+	             || ksft_fail "pre-engage: unexpected outcome"
+fi
+
+# --- engage ---
+echo "engage ks_test_vuln 0 ksft" > $KS/control
+grep -q "^ks_test_vuln" $KS/engaged \
+	&& ksft_pass "engage: ks_test_vuln in engaged list" \
+	|| ksft_fail "engage: missing from engaged list"
+
+[[ $(cat $KS/taint) == 1 ]] \
+	&& ksft_pass "engage: taint set" \
+	|| ksft_fail "engage: taint not set"
+
+[[ -d $KS/fn/ks_test_vuln ]] \
+	&& ksft_pass "engage: per-fn dir created" \
+	|| ksft_fail "engage: per-fn dir missing"
+
+# --- post-engage: BUG suppressed; write returns successfully ---
+if echo 0xC0FFEE > $TRIG 2>/dev/null; then
+	ksft_pass "post-engage: BUG suppressed, write succeeded"
+else
+	ksft_fail "post-engage: write should succeed"
+fi
+
+[[ $(cat $KS/fn/ks_test_vuln/hits) -ge 1 ]] \
+	&& ksft_pass "post-engage: hits counter incremented" \
+	|| ksft_fail "post-engage: hits counter did not move"
+
+# --- retval rewrite is a plain write (no validation) ---
+echo 7 > $KS/fn/ks_test_vuln/retval
+[[ $(cat $KS/fn/ks_test_vuln/retval) == 7 ]] \
+	&& ksft_pass "retval rewrite round-trips" \
+	|| ksft_fail "retval rewrite failed"
+
+# --- engage on a kprobe-rejected function fails ---
+# warn_thunk_thunk is in /sys/kernel/debug/kprobes/blacklist;
+# register_kprobe() refuses it.
+KP_REJECT=warn_thunk_thunk
+if echo "engage $KP_REJECT 0 ksft" > $KS/control 2>/dev/null; then
+	ksft_fail "register_kprobe should have rejected $KP_REJECT"
+	echo "disengage $KP_REJECT" > $KS/control
+else
+	ksft_pass "register_kprobe refuses blacklisted target"
+fi
+
+# --- disengage ---
+echo "disengage ks_test_vuln" > $KS/control
+[[ -z "$(cat $KS/engaged)" ]] \
+	&& ksft_pass "disengage: engaged list empty" \
+	|| ksft_fail "disengage: engaged list not empty"
+
+[[ ! -d $KS/fn/ks_test_vuln ]] \
+	&& ksft_pass "disengage: per-fn dir removed" \
+	|| ksft_fail "disengage: per-fn dir still present"
+
+[[ $(cat $KS/taint) == 1 ]] \
+	&& ksft_pass "disengage: taint persists" \
+	|| ksft_fail "disengage: taint should persist"
+
+# --- post-disengage: bad path active again ---
+if echo 0xC0FFEE > $TRIG 2>/dev/null; then
+	ksft_fail "post-disengage: write should fail again"
+else
+	ksft_pass "post-disengage: bad path active again"
+fi
+
+# ---- CVE-2026-31431 mitigation proof (AF_ALG aead via af_alg_sendmsg) ----
+# Skip the whole block if AF_ALG / AEAD machinery isn't compiled in.
+if [[ -x $(dirname "$0")/cve_31431_test ]]; then
+	CVE=$(dirname "$0")/cve_31431_test
+	$CVE >/dev/null 2>&1 && PRE=$? || PRE=$?
+	if [[ $PRE -eq 0 ]]; then
+		ksft_pass "cve-31431: pre-engage AEAD round-trip OK"
+
+		echo "engage af_alg_sendmsg -1 CVE-2026-31431" > $KS/control
+		$CVE >/dev/null 2>&1 && POST=$? || POST=$?
+		if [[ $POST -eq 1 ]]; then
+			ksft_pass "cve-31431: post-engage AEAD refused (mitigated)"
+		else
+			ksft_fail "cve-31431: post-engage exit=$POST (expected 1)"
+		fi
+
+		HITS=$(cat $KS/fn/af_alg_sendmsg/hits 2>/dev/null || echo 0)
+		[[ $HITS -ge 1 ]] && ksft_pass "cve-31431: hits=$HITS recorded" \
+			|| ksft_fail "cve-31431: hits not recorded"
+
+		echo "disengage af_alg_sendmsg" > $KS/control
+		$CVE >/dev/null 2>&1 && POST2=$? || POST2=$?
+		[[ $POST2 -eq 0 ]] && ksft_pass "cve-31431: post-disengage restored" \
+			|| ksft_fail "cve-31431: post-disengage exit=$POST2"
+	elif [[ $PRE -eq 2 ]]; then
+		echo "# SKIP cve-31431 (AF_ALG/AEAD not available)"
+	else
+		ksft_fail "cve-31431: pre-engage exit=$PRE"
+	fi
+fi
+
+echo "1..$N"
+exit $((FAIL > 0))
-- 
2.53.0


^ permalink raw reply related

* Re: [PATCH 2/5] docs: fix repeated word 'that' across documentation
From: David Howells @ 2026-05-08 19:43 UTC (permalink / raw)
  To: Adrien Reynard
  Cc: Paul E. McKenney, Frederic Weisbecker, Neeraj Upadhyay,
	Joel Fernandes, Josh Triplett, Boqun Feng, Uladzislau Rezki,
	Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Zqiang,
	Jonathan Corbet, Shuah Khan, Greg Kroah-Hartman,
	Rafael J. Wysocki, Danilo Krummrich, David Howells,
	Paulo Alcantara, Masami Hiramatsu,
	open list:READ-COPY UPDATE (RCU), open list:DOCUMENTATION,
	open list, open list:DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS,
	open list:FILESYSTEMS [NETFS LIBRARY],
	open list:FILESYSTEMS [NETFS LIBRARY], open list:TRACING
In-Reply-To: <20260508163759.16231-1-reynard.adrien.08@gmail.com>

Adrien Reynard <reynard.adrien.08@gmail.com> wrote:

> -  three states, we know that that CPU has exited any previous RCU

This is arguably correct.  The two 'that' words are functionally different.
If you look at another language, say Hungarian, they are different words
(e.g. 'hogy' vs 'az').

David


^ permalink raw reply

* Re: [PATCH v1 00/10] platform/x86: msi-wmi-platform: Add fan curves/platform profile/tdp/battery limiting
From: Derek J. Clark @ 2026-05-08 18:41 UTC (permalink / raw)
  To: lkml
  Cc: W_Armin, corbet, hdegoede, ilpo.jarvinen, jdelvare, kuurtb,
	linux-doc, linux-hwmon, linux-kernel, linux, platform-driver-x86
In-Reply-To: <20250511204427.327558-1-lkml@antheas.dev>

>This draft patch series brings into parity the msi-wmi-platform driver with
>the MSI Center M Windows application for the MSI Claw (all models).
>Unfortunately, MSI Center M and this interface do not have a discovery API,
>necessitating the introduction of a quirk system.
>
>While this patch series is fully functional and tested, there are still
>some issues that need to be addressed:
>  - Armin notes we need to disable fan curve support by default and quirk
>    it as well, as it is not supported on all models. However, the way
>    PWM enable ops work, this makes it a bit difficult, so I would like
>    some suggestions on how to rework this.
>  - It turns out that to fully disable the fan curve, we have to restore
>    the default fan values. This is also what is done on the OEM software.
>    For this, the last patch in the series is used, which is a bit dirty.
>
>Sleep was tested with all values being preserved during S0iX (platform
>profile, fan curve, PL1/PL2), so we do not need suspend/resume hooks, at
>least for the Claw devices.
>
>For PL1/PL2, we use firmware-attributes. So for that I +cc Kurt since if
>his new high level interface is merged beforehand, we can use that instead.
>

Hi Antheas,

It seems this series is stalled for 3 days shy of a year now. I have an
interest in getting this across the finish line. Will you be continuing
development? If not, I will take what you've started here and finish out
the remaining nits, keeping your original attribution of course.

Cheers,
Derek

>Antheas Kapenekakis (8):
>  platform/x86: msi-wmi-platform: Add unlocked msi_wmi_platform_query
>  platform/x86: msi-wmi-platform: Add quirk system
>  platform/x86: msi-wmi-platform: Add platform profile through shift
>    mode
>  platform/x86: msi-wmi-platform: Add PL1/PL2 support via firmware
>    attributes
>  platform/x86: msi-wmi-platform: Add charge_threshold support
>  platform/x86: msi-wmi-platform: Drop excess fans in dual fan devices
>  platform/x86: msi-wmi-platform: Update header text
>  platform/x86: msi-wmi-platform: Restore fan curves on PWM disable and
>    unload
>
>Armin Wolf (2):
>  platform/x86: msi-wmi-platform: Use input buffer for returning result
>  platform/x86: msi-wmi-platform: Add support for fan control
>
> .../wmi/devices/msi-wmi-platform.rst          |   26 +
> drivers/platform/x86/Kconfig                  |    3 +
> drivers/platform/x86/msi-wmi-platform.c       | 1181 ++++++++++++++++-
> 3 files changed, 1156 insertions(+), 54 deletions(-)
>
>
>base-commit: 62b1dcf2e7af3dc2879d1a39bf6823c99486a8c2

^ permalink raw reply

* Re: [PATCH v7 10/10] ipe: Add BPF program load policy enforcement via Hornet integration
From: Fan Wu @ 2026-05-08 18:40 UTC (permalink / raw)
  To: Blaise Boscaccy
  Cc: Jonathan Corbet, Paul Moore, James Morris, Serge E. Hallyn,
	Mickaël Salaün, Günther Noack,
	Dr. David Alan Gilbert, Andrew Morton, James.Bottomley, dhowells,
	Fan Wu, Ryan Foster, Randy Dunlap, linux-security-module,
	linux-doc, linux-kernel, bpf, Song Liu
In-Reply-To: <20260507191416.2984054-11-bboscaccy@linux.microsoft.com>

On Thu, May 7, 2026 at 12:15 PM Blaise Boscaccy
<bboscaccy@linux.microsoft.com> wrote:
>
> Add support for the bpf_prog_load_post_integrity LSM hook, enabling IPE
> to make policy decisions about BPF program loading based on integrity
> verdicts provided by the Hornet LSM.
>
> New policy operation:
>   op=BPF_PROG_LOAD - Matches BPF program load events
>
> New policy properties:
>   bpf_signature=NONE      - No Verdict
>   bpf_signature=OK        - Program signature and map hashes verified
>   bpf_signature=UNSIGNED  - No signature provided
>   bpf_signature=PARTIALSIG - Signature OK but no map hash data
>   bpf_signature=UNKNOWNKEY - The keyring requested by the user is invalid
>   bpf_signature=UNEXPECTED - An unexpected hash value was encountered
>   bpf_signature=FAULT      - System error during verification
>   bpf_signature=BADSIG    - Signature or map hash verification failed
>   bpf_keyring=BUILTIN     - Program was signed using a builtin keyring
>   bpf_keyring=SECONDARY   - Program was signed using the secondary keyring
>   bpf_keyring=PLATFORM    - Program was signed using the platform keyring
>   bpf_kernel=TRUE         - Program originated from kernelspace
>   bpf_kernel=FALSE        - Program originated from userspace
>
> These properties map directly to the lsm_integrity_verdict enum values
> provided by the Hornet LSM through security_bpf_prog_load_post_integrity.
>
> The feature is gated on CONFIG_IPE_PROP_BPF_SIGNATURE which depends on
> CONFIG_SECURITY_HORNET.
>
> Signed-off-by: Blaise Boscaccy <bboscaccy@linux.microsoft.com>

Acked-by: Fan Wu <wufan@kernel.org>

^ permalink raw reply

* Re: [PATCH v4 1/2] usb: xhci-pci: add AMD Promontory 21 PCI glue
From: Jihong Min @ 2026-05-08 18:39 UTC (permalink / raw)
  To: Guenter Roeck, Mario Limonciello, Jihong Min, Greg Kroah-Hartman,
	Mathias Nyman
  Cc: Jonathan Corbet, Shuah Khan, Basavaraj Natikar, linux-usb,
	linux-hwmon, linux-doc, linux-pci, linux-kernel
In-Reply-To: <053b019e-9c6a-4eb3-aa69-0c07cd6e7f12@roeck-us.net>

> How about "default USB_XHCI_PCI" ?
>
> Guenter
That makes sense. I changed USB_XHCI_PCI_PROM21 to use

   default USB_XHCI_PCI

locally.

Sincerely,
Jihong Min


^ permalink raw reply

* Re: [PATCH 1/3] Documentation/gpu: limit main toctree depth to 2
From: Randy Dunlap @ 2026-05-08 18:37 UTC (permalink / raw)
  To: Jani Nikula, dri-devel, linux-doc
In-Reply-To: <cddd2d11c104132801510e3ab4e4b9ef3ea9cb6d.1778238671.git.jani.nikula@intel.com>



On 5/8/26 4:12 AM, Jani Nikula wrote:
> The main GPU documentation toctree has no limit to the toctree depth,
> which means the main GPU index page recursively includes all the
> headings in all of GPU documentation in the single table of
> contents. This makes getting any kind of overview of the documentation
> really difficult.
> 
> Limit the main toctree depth to 2 i.e. show at most two levels of
> headings.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Acked-by: Randy Dunlap <rdunlap@infradead.org>
Tested-by: Randy Dunlap <rdunlap@infradead.org>

> ---
>  Documentation/gpu/index.rst | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/gpu/index.rst b/Documentation/gpu/index.rst
> index 5d708a106b3f..65bf3b26e4f4 100644
> --- a/Documentation/gpu/index.rst
> +++ b/Documentation/gpu/index.rst
> @@ -3,6 +3,7 @@ GPU Driver Developer's Guide
>  ============================
>  
>  .. toctree::
> +   :maxdepth: 2
>  
>     introduction
>     drm-internals

-- 
~Randy

^ permalink raw reply

* Re: [PATCH 2/3] Documentation/gpu: add some tables of contents to large documents
From: Randy Dunlap @ 2026-05-08 18:37 UTC (permalink / raw)
  To: Jani Nikula, dri-devel, linux-doc
In-Reply-To: <e3f9357c0e8198cc48e69e2a3b8ca072c7ab92ca.1778238671.git.jani.nikula@intel.com>



On 5/8/26 4:12 AM, Jani Nikula wrote:
> Some of the GPU documentation pages are quite long, with various levels
> of details. Add document internal tables of contents to the larger
> documents to make them easier to navigate.
> 
> The index.rst in the sub-directories have toctrees, which provide
> similar overviews.
> 
> Fix one missing newline at the end of drm-uapi.rst while at it,
> primarily because rst should have it, and secondarily because my editor
> rst mode refuses to save the file without it.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Acked-by: Randy Dunlap <rdunlap@infradead.org>
Tested-by: Randy Dunlap <rdunlap@infradead.org>

> ---
>  Documentation/gpu/driver-uapi.rst     | 2 ++
>  Documentation/gpu/drm-internals.rst   | 2 ++
>  Documentation/gpu/drm-kms-helpers.rst | 2 ++
>  Documentation/gpu/drm-kms.rst         | 2 ++
>  Documentation/gpu/drm-mm.rst          | 2 ++
>  Documentation/gpu/drm-ras.rst         | 2 ++
>  Documentation/gpu/drm-uapi.rst        | 4 +++-
>  Documentation/gpu/drm-usage-stats.rst | 2 ++
>  Documentation/gpu/introduction.rst    | 2 ++
>  9 files changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/gpu/driver-uapi.rst b/Documentation/gpu/driver-uapi.rst
> index 1f15a8ca1265..627fc68c7a21 100644
> --- a/Documentation/gpu/driver-uapi.rst
> +++ b/Documentation/gpu/driver-uapi.rst
> @@ -2,6 +2,8 @@
>  DRM Driver uAPI
>  ===============
>  
> +.. contents::
> +
>  drm/i915 uAPI
>  =============
>  
> diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst
> index 94f93fd3b8a0..a3ce25a36f1d 100644
> --- a/Documentation/gpu/drm-internals.rst
> +++ b/Documentation/gpu/drm-internals.rst
> @@ -18,6 +18,8 @@ event handling, memory management, output management, framebuffer
>  management, command submission & fencing, suspend/resume support, and
>  DMA services.
>  
> +.. contents::
> +
>  Driver Initialization
>  =====================
>  
> diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst
> index b4a9e5ae81f6..80453dda33b8 100644
> --- a/Documentation/gpu/drm-kms-helpers.rst
> +++ b/Documentation/gpu/drm-kms-helpers.rst
> @@ -33,6 +33,8 @@ There are a few areas these helpers can grouped into:
>    pipeline: Planes, handling rectangles for visibility checking and scissoring,
>    flip queues and assorted bits.
>  
> +.. contents::
> +
>  Modeset Helper Reference for Common Vtables
>  ===========================================
>  
> diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
> index fbe0583eb84c..d22817fdf9aa 100644
> --- a/Documentation/gpu/drm-kms.rst
> +++ b/Documentation/gpu/drm-kms.rst
> @@ -15,6 +15,8 @@ be setup by initializing the following fields.
>  -  struct drm_mode_config_funcs \*funcs;
>     Mode setting functions.
>  
> +.. contents::
> +
>  Overview
>  ========
>  
> diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst
> index 32fb506db05b..2dea94f77d52 100644
> --- a/Documentation/gpu/drm-mm.rst
> +++ b/Documentation/gpu/drm-mm.rst
> @@ -25,6 +25,8 @@ share it. GEM has simpler initialization and execution requirements than
>  TTM, but has no video RAM management capabilities and is thus limited to
>  UMA devices.
>  
> +.. contents::
> +
>  The Translation Table Manager (TTM)
>  ===================================
>  
> diff --git a/Documentation/gpu/drm-ras.rst b/Documentation/gpu/drm-ras.rst
> index 4636e68f5678..83c21853b74b 100644
> --- a/Documentation/gpu/drm-ras.rst
> +++ b/Documentation/gpu/drm-ras.rst
> @@ -24,6 +24,8 @@ Key Goals:
>    nodes for different IP blocks, sub-blocks, or other logical subdivisions
>    as applicable.
>  
> +.. contents::
> +
>  Nodes
>  =====
>  
> diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst
> index 32206ce62931..2c2f939322fb 100644
> --- a/Documentation/gpu/drm-uapi.rst
> +++ b/Documentation/gpu/drm-uapi.rst
> @@ -16,6 +16,8 @@ management, and output management.
>  Cover generic ioctls and sysfs layout here. We only need high-level
>  info, since man pages should cover the rest.
>  
> +.. contents::
> +
>  libdrm Device Lookup
>  ====================
>  
> @@ -765,4 +767,4 @@ Stable uAPI events
>  From ``drivers/gpu/drm/scheduler/gpu_scheduler_trace.h``
>  
>  .. kernel-doc::  drivers/gpu/drm/scheduler/gpu_scheduler_trace.h
> -   :doc: uAPI trace events
> \ No newline at end of file
> +   :doc: uAPI trace events
> diff --git a/Documentation/gpu/drm-usage-stats.rst b/Documentation/gpu/drm-usage-stats.rst
> index 24d3012ca7a6..70b7cfcc194f 100644
> --- a/Documentation/gpu/drm-usage-stats.rst
> +++ b/Documentation/gpu/drm-usage-stats.rst
> @@ -16,6 +16,8 @@ output is split between common and driver specific parts. Having said that,
>  wherever possible effort should still be made to standardise as much as
>  possible.
>  
> +.. contents::
> +
>  File format specification
>  =========================
>  
> diff --git a/Documentation/gpu/introduction.rst b/Documentation/gpu/introduction.rst
> index d8f519693fc2..64074ac22d9b 100644
> --- a/Documentation/gpu/introduction.rst
> +++ b/Documentation/gpu/introduction.rst
> @@ -16,6 +16,8 @@ found in current kernels.
>  
>  [Insert diagram of typical DRM stack here]
>  
> +.. contents::
> +
>  Style Guidelines
>  ================
>  

-- 
~Randy

^ permalink raw reply

* Re: [PATCH 3/3] Documentation/gpu/rfc: fix toctree
From: Randy Dunlap @ 2026-05-08 18:36 UTC (permalink / raw)
  To: Jani Nikula, dri-devel, linux-doc
In-Reply-To: <c9678a78749a71cf86941f37116232dbc7c23b5f.1778238671.git.jani.nikula@intel.com>



On 5/8/26 4:12 AM, Jani Nikula wrote:
> Just one toctree is enough. The .rst suffixes are superfluous in the
> toctree. Fix indent. Add missing newline at the end of the file.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Acked-by: Randy Dunlap <rdunlap@infradead.org>
Tested-by: Randy Dunlap <rdunlap@infradead.org>

> ---
>  Documentation/gpu/rfc/index.rst | 26 ++++++--------------------
>  1 file changed, 6 insertions(+), 20 deletions(-)
> 
> diff --git a/Documentation/gpu/rfc/index.rst b/Documentation/gpu/rfc/index.rst
> index ef19b0ba2a3e..26a7ebe6fb44 100644
> --- a/Documentation/gpu/rfc/index.rst
> +++ b/Documentation/gpu/rfc/index.rst
> @@ -18,23 +18,9 @@ host such documentation:
>  
>  .. toctree::
>  
> -    gpusvm.rst
> -
> -.. toctree::
> -
> -    i915_gem_lmem.rst
> -
> -.. toctree::
> -
> -    i915_scheduler.rst
> -
> -.. toctree::
> -
> -    i915_small_bar.rst
> -
> -.. toctree::
> -
> -    i915_vm_bind.rst
> -
> -.. toctree::
> -    color_pipeline.rst
> \ No newline at end of file
> +   gpusvm
> +   i915_gem_lmem
> +   i915_scheduler
> +   i915_small_bar
> +   i915_vm_bind
> +   color_pipeline

-- 
~Randy

^ permalink raw reply

* Re: [PATCH 4/5] docs: fix repeated prepositions across documentation
From: David Laight @ 2026-05-08 18:28 UTC (permalink / raw)
  To: Adrien Reynard
  Cc: Andrey Ryabinin, Alexander Potapenko, Andrey Konovalov,
	Dmitry Vyukov, Vincenzo Frascino, Jonathan Corbet, Shuah Khan,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Richard Weinberger, Anton Ivanov, Johannes Berg,
	open list:KASAN, open list:DOCUMENTATION PROCESS,
	open list:DOCUMENTATION, open list,
	open list:NETWORKING [GENERAL], open list:USER-MODE LINUX (UML)
In-Reply-To: <20260508163804.16267-1-reynard.adrien.08@gmail.com>

On Fri,  8 May 2026 18:38:03 +0200
Adrien Reynard <reynard.adrien.08@gmail.com> wrote:

Nope, all these are correct as is.
I'm not looking at any more.

> Signed-off-by: Adrien Reynard <reynard.adrien.08@gmail.com>
> ---
>  Documentation/dev-tools/kasan.rst                   | 2 +-
>  Documentation/networking/switchdev.rst              | 2 +-
>  Documentation/virt/uml/user_mode_linux_howto_v2.rst | 2 +-
>  3 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/dev-tools/kasan.rst b/Documentation/dev-tools/kasan.rst
> index 4968b2aa60c8..3a8bd40ad905 100644
> --- a/Documentation/dev-tools/kasan.rst
> +++ b/Documentation/dev-tools/kasan.rst
> @@ -392,7 +392,7 @@ reserved to tag freed memory regions.
>  If the hardware does not support MTE (pre ARMv8.5), Hardware Tag-Based KASAN
>  will not be enabled. In this case, all KASAN boot parameters are ignored.
>  
> -Note that enabling CONFIG_KASAN_HW_TAGS always results in in-kernel TBI being
> +Note that enabling CONFIG_KASAN_HW_TAGS always results in-kernel TBI being
>  enabled. Even when ``kasan.mode=off`` is provided or when the hardware does not
>  support MTE (but supports TBI).
>  
> diff --git a/Documentation/networking/switchdev.rst b/Documentation/networking/switchdev.rst
> index 2966b7122f05..948bce44ca9b 100644
> --- a/Documentation/networking/switchdev.rst
> +++ b/Documentation/networking/switchdev.rst
> @@ -162,7 +162,7 @@ The switchdev driver can know a particular port's position in the topology by
>  monitoring NETDEV_CHANGEUPPER notifications.  For example, a port moved into a
>  bond will see its upper master change.  If that bond is moved into a bridge,
>  the bond's upper master will change.  And so on.  The driver will track such
> -movements to know what position a port is in in the overall topology by
> +movements to know what position a port is in the overall topology by
>  registering for netdevice events and acting on NETDEV_CHANGEUPPER.
>  
>  L2 Forwarding Offload
> diff --git a/Documentation/virt/uml/user_mode_linux_howto_v2.rst b/Documentation/virt/uml/user_mode_linux_howto_v2.rst
> index c37e8e594d12..7b08738c30aa 100644
> --- a/Documentation/virt/uml/user_mode_linux_howto_v2.rst
> +++ b/Documentation/virt/uml/user_mode_linux_howto_v2.rst
> @@ -1092,7 +1092,7 @@ be formatted as plain text.
>  
>  Developing always goes hand in hand with debugging. First of all,
>  you can always run UML under gdb and there will be a whole section
> -later on on how to do that. That, however, is not the only way to
> +later on how to do that. That, however, is not the only way to
>  debug a Linux kernel. Quite often adding tracing statements and/or
>  using UML specific approaches such as ptracing the UML kernel process
>  are significantly more informative.


^ permalink raw reply

* Re: [PATCH 2/5] docs: fix repeated word 'that' across documentation
From: David Laight @ 2026-05-08 18:26 UTC (permalink / raw)
  To: Shuah Khan
  Cc: Adrien Reynard, Paul E. McKenney, Frederic Weisbecker,
	Neeraj Upadhyay, Joel Fernandes, Josh Triplett, Boqun Feng,
	Uladzislau Rezki, Steven Rostedt, Mathieu Desnoyers,
	Lai Jiangshan, Zqiang, Jonathan Corbet, Greg Kroah-Hartman,
	Rafael J. Wysocki, Danilo Krummrich, David Howells,
	Paulo Alcantara, Masami Hiramatsu,
	open list:READ-COPY UPDATE (RCU), open list:DOCUMENTATION,
	open list, open list:DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS,
	open list:FILESYSTEMS [NETFS LIBRARY],
	open list:FILESYSTEMS [NETFS LIBRARY], open list:TRACING
In-Reply-To: <1501caea-8cff-4968-aca6-e8d4b20e0e80@linuxfoundation.org>

On Fri, 8 May 2026 11:15:28 -0600
Shuah Khan <skhan@linuxfoundation.org> wrote:

> On 5/8/26 10:37, Adrien Reynard wrote:
> 
> Missing commit log in all your patches - I don't patch 1/5 in
> my Inbox.
> 
> > Signed-off-by: Adrien Reynard <reynard.adrien.08@gmail.com>
> > ---
> >   Documentation/RCU/rcu.rst                          | 2 +-
> >   Documentation/driver-api/driver-model/overview.rst | 2 +-
> >   Documentation/filesystems/netfs_library.rst        | 2 +-
> >   Documentation/trace/histogram-design.rst           | 2 +-
> >   Documentation/trace/histogram.rst                  | 2 +-
> >   5 files changed, 5 insertions(+), 5 deletions(-)
> > 
> > diff --git a/Documentation/RCU/rcu.rst b/Documentation/RCU/rcu.rst
> > index bf6617b330a7..320ad3292b75 100644
> > --- a/Documentation/RCU/rcu.rst
> > +++ b/Documentation/RCU/rcu.rst
> > @@ -32,7 +32,7 @@ Frequently Asked Questions
> >     Just as with spinlocks, RCU readers are not permitted to
> >     block, switch to user-mode execution, or enter the idle loop.
> >     Therefore, as soon as a CPU is seen passing through any of these
> > -  three states, we know that that CPU has exited any previous RCU
> > +  three states, we know that CPU has exited any previous RCU  
> 
> The original intent might have been to say, "that cpu", so adding
> the missing comma after the first "that" or change "that" to "the"
> would make sense.
...

I don't think adding a comma would be correct.
The clause splits as 'we know that' 'that CPU' and the repeated 'that'
is absolutely correct.
Maybe 'that CPU' could be replaced by 'it'; but it can be difficult to
work out what back references like 'it' refer to.

You can re-order it, as (say):
	Therefore we know that as soon as a CPU is seen passing through any of these
	three states it has exited any previous RCU read-side critical sections.

But just because some grammar book says you shouldn't have repeated words
doesn't mean there aren't exceptions.

The sign writer was doing a new sign for the 'Pig and Whistle'.
Unfortunately the gaps between Pig and and and and and Whistle
ended up visibly different.

-- David



^ permalink raw reply

* Re: [PATCH 2/3] Documentation/gpu: use === for Intel display section heading underlines
From: Randy Dunlap @ 2026-05-08 18:22 UTC (permalink / raw)
  To: Jani Nikula, intel-gfx, intel-xe, dri-devel, linux-doc
  Cc: rodrigo.vivi, Matthew Brost, Thomas Hellström,
	joonas.lahtinen, tursulin
In-Reply-To: <f49968792220ca3ff24efde813550850340d092e.1778235406.git.jani.nikula@intel.com>



On 5/8/26 3:20 AM, Jani Nikula wrote:
> Prefer to use === instead of --- for top level section heading
> underlines to allow using the latter for sub-headings later.
> 
> While at it, fix the underline lenghts where needed.

                                 lengths

> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

 
Acked-by: Randy Dunlap <rdunlap@infradead.org>
Tested-by: Randy Dunlap <rdunlap@infradead.org>

-- 
~Randy

^ permalink raw reply

* Re: [PATCH 1/3] Documentation/gpu: add dedicated documentation for Intel display
From: Randy Dunlap @ 2026-05-08 18:22 UTC (permalink / raw)
  To: Jani Nikula, intel-gfx, intel-xe, dri-devel, linux-doc
  Cc: rodrigo.vivi, Matthew Brost, Thomas Hellström,
	joonas.lahtinen, tursulin
In-Reply-To: <21bfa7777eb0926eadd309d4c6f5c9cf48405cf0.1778235406.git.jani.nikula@intel.com>



On 5/8/26 3:20 AM, Jani Nikula wrote:
> diff --git a/Documentation/gpu/intel-display/index.rst b/Documentation/gpu/intel-display/index.rst
> new file mode 100644
> index 000000000000..8d40363b8f90
> --- /dev/null
> +++ b/Documentation/gpu/intel-display/index.rst
> @@ -0,0 +1,40 @@
> +.. SPDX-License-Identifier: MIT
> +.. Copyright © 2026 Intel Corporation
> +
> +.. _drm/intel-display:
> +
> +====================
> +Intel Display Driver
> +====================
> +
> +The Intel display driver provides the display, or :ref:`drm-kms`, support for
> +both the :ref:`drm/xe <drm/xe>` and :ref:`drm/i915 <drm/i915>` Intel GPU
> +drivers.
> +
> +The source code currently resides under ``drivers/gpu/drm/i915/display`` due to
> +historical reasons, and it's compiled separately into both drm/xe and drm/i915
> +kernel modules.
> +
> +The drm/xe and drm/i915 drivers are the "core" or "parent" drivers for display,
> +as they initialize and own the drm device, and pass that on to the display
> +driver. The display driver isn't an independent driver in that sense.
> +
> +.. toctree::
> +   :maxdepth: 1
> +   :caption: Detailed display topics
> +
> +   async-flip
> +   audio
> +   cdclk
> +   dmc
> +   dpio
> +   dpll
> +   drrs
> +   dsb
> +   fbc
> +   fifo-underrun
> +   frontbuffer
> +   hotplug
> +   plane
> +   psr
> +   vbt

Is this in almost-alphabetical order or just random?  :)

Tested-by: Randy Dunlap <rdunlap@infradead.org>

-- 
~Randy

^ permalink raw reply

* Re: [PATCH v4 1/2] usb: xhci-pci: add AMD Promontory 21 PCI glue
From: Guenter Roeck @ 2026-05-08 18:15 UTC (permalink / raw)
  To: Jihong Min, Mario Limonciello, Jihong Min, Greg Kroah-Hartman,
	Mathias Nyman
  Cc: Jonathan Corbet, Shuah Khan, Basavaraj Natikar, linux-usb,
	linux-hwmon, linux-doc, linux-pci, linux-kernel
In-Reply-To: <2657e1b7-126d-4c4b-8027-012a6d3ffee3@icloud.com>

On 5/8/26 11:11, Jihong Min wrote:
>>> Something else I was thinking about while reviewing this series.
>>>
>>> Promontory 21 is only on AMD platforms and AMD platforms are only x86. I think the Kconfig should be conditional on AMD CPU support being enabled and X86 architecture so that we don't bloat other architectures with dead code that will never run.
> One related Kconfig question: would it be acceptable to make
> USB_XHCI_PCI_PROM21 default y with the X86 && CPU_SUP_AMD dependency?
> 
> This would only default-enable the PROM21 xHCI PCI glue. The hwmon driver
> would still be controlled separately by SENSORS_PROM21_XHCI and would remain
> opt-in, so the undocumented temperature register polling would not be enabled
> by default.
> 
> The concern is that, without default y, distribution configs may miss the
> PROM21 PCI glue and then SENSORS_PROM21_XHCI can not bind even if the hwmon
> driver itself is enabled or available as a module.
> 
> Would you prefer this, or should USB_XHCI_PCI_PROM21 remain explicitly enabled
> by distributions?
> 

How about "default USB_XHCI_PCI" ?

Guenter


^ permalink raw reply

* Re: [PATCH v4 1/2] usb: xhci-pci: add AMD Promontory 21 PCI glue
From: Jihong Min @ 2026-05-08 18:11 UTC (permalink / raw)
  To: Mario Limonciello, Jihong Min, Greg Kroah-Hartman, Mathias Nyman
  Cc: Guenter Roeck, Jonathan Corbet, Shuah Khan, Basavaraj Natikar,
	linux-usb, linux-hwmon, linux-doc, linux-pci, linux-kernel
In-Reply-To: <b8372128-c922-4b62-91c5-46f848180bc5@icloud.com>

>> Something else I was thinking about while reviewing this series.
>>
>> Promontory 21 is only on AMD platforms and AMD platforms are only 
>> x86. I think the Kconfig should be conditional on AMD CPU support 
>> being enabled and X86 architecture so that we don't bloat other 
>> architectures with dead code that will never run.
One related Kconfig question: would it be acceptable to make
USB_XHCI_PCI_PROM21 default y with the X86 && CPU_SUP_AMD dependency?

This would only default-enable the PROM21 xHCI PCI glue. The hwmon driver
would still be controlled separately by SENSORS_PROM21_XHCI and would remain
opt-in, so the undocumented temperature register polling would not be 
enabled
by default.

The concern is that, without default y, distribution configs may miss the
PROM21 PCI glue and then SENSORS_PROM21_XHCI can not bind even if the hwmon
driver itself is enabled or available as a module.

Would you prefer this, or should USB_XHCI_PCI_PROM21 remain explicitly 
enabled
by distributions?

Sincerely,
Jihong Min


^ permalink raw reply

* Re: [RFC net-next 0/4] devlink: Add boot-time defaults
From: Jiri Pirko @ 2026-05-08 18:07 UTC (permalink / raw)
  To: Mark Bloch
  Cc: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
	David S. Miller, Jonathan Corbet, Shuah Khan, Simon Horman,
	Saeed Mahameed, Leon Romanovsky, Tariq Toukan, Andrew Morton,
	Borislav Petkov (AMD), Randy Dunlap, Dave Hansen,
	Christian Brauner, Petr Mladek, Peter Zijlstra (Intel),
	Thomas Gleixner, Pawan Gupta, Dapeng Mi, Kees Cook, Marco Elver,
	Eric Biggers, Li RongQing, Paul E. McKenney, linux-doc,
	linux-kernel, netdev, linux-rdma
In-Reply-To: <b6a9b568-dd09-4414-be57-6b9cd282a43c@nvidia.com>

Fri, May 08, 2026 at 07:59:04PM +0200, mbloch@nvidia.com wrote:
>
>
>On 07/05/2026 14:03, Jiri Pirko wrote:
>> Wed, May 06, 2026 at 07:35:10PM +0200, mbloch@nvidia.com wrote:
>>>
>>>
>>> On 06/05/2026 18:22, Jiri Pirko wrote:
>>>> Wed, May 06, 2026 at 02:37:35PM +0200, mbloch@nvidia.com wrote:
>>>>> This series adds a devlink= kernel command line parameter for applying
>>>>> selected devlink settings during device initialization.
>>>>>
>>>>> Following a discussion with Jakub[1], I am sending this RFC to get the
>>>>> conversation moving. I started from Jakub's example/request and extended
>>>>> it to cover requirements from production systems and configurations that
>>>>> customers use.
>>>>>
>>>>> One important caveat is that the parsing logic in this RFC was written
>>>>> with AI assistance. I am also not sure whether the resulting syntax and
>>>>> parser are too complex for a kernel command line interface. This is part
>>>>> of why I am sending it as an RFC: to understand what direction and level
>>>>> of complexity would be acceptable to people.
>>>>>
>>>>> The implementation is intended to support the following properties:
>>>>>
>>>>> - A system may have multiple devlink devices that usually need the same
>>>>>  configuration. For a configuration such as eswitch mode switchdev, a
>>>>>  user should be able to specify multiple devices to which that
>>>>>  configuration applies.
>>>>>
>>>>> - There may be ordering dependencies between options. For example, in
>>>>>  mlx5, flow_steering_mode should be set before moving to switchdev.
>>>>>  With this in mind, defaults are applied per device in the left-to-right
>>>>>  order in which they appear on the command line.
>>>>>
>>>>> The intent is to let deployments set devlink defaults before normal
>>>>> userspace orchestration runs, while still using devlink concepts and
>>>>
>>>> "defaults before normal userspace orchestrarion". I read it as config
>>>> before config, which eventually could be skipped.
>>>>
>>>>
>>>>> driver callbacks rather than adding driver-specific module parameters.
>>>>> A default is scoped to one or more devlink handles, for example:
>>>>>
>>>>>  devlink=[pci/0000:08:00.0]:esw:mode:switchdev
>>>>>  devlink=[pci/0000:08:00.0]:param:flow_steering_mode:smfs
>>>>>  devlink=[pci/0000:08:00.0,pci/0000:08:00.1]:param:flow_steering_mode:hmfs,[pci/0000:08:00.0,pci/0000:08:00.1]:esw:mode:switchdev
>>>>
>>>> I don't like this. What you do, you are basically introducing user
>>>> configuration tool on kernel cmdline.
>>>>
>>>> The same you would achieve with a proper userspace tool/daemon.
>>>> I did try to come up with it and push it here:
>>>> https://github.com/systemd/systemd/pull/37393
>>>> That didn't get merged for unknown reason, but the idea is sound. You
>>>> provide configuration files for devlink object and systemd-devlinkd
>>>> will apply when they appear. Wouldn't this help your case?
>>>
>>> I agree that systemd-devlinkd is the right shape for normal
>>> devlink configuration, and it could probably replace the udev/devlink
>>> plumbing we use today.
>>>
>>> The case I am trying to cover is earlier than that.
>>>
>>> On BlueField/ECPF/DPU systems, the host PF driver cannot always finish
>>> probing independently of the ECPF side. When the ECPF is the eswitch
>>> manager, the host PF is kept in initializing state until the ECPF eswitch
>>> side is set up and mlx5 enables the external host PF HCA. That happens as
>>> part of moving the ECPF to switchdev.
>>>
>>> Today userspace observes the ECPF instance and then switches the
>>> mode through devlink, usually via udev or similar plumbing. That still
>>> leaves a window where the ECPF has probed, userspace has not applied the
>>> mode yet, and the host PF is waiting. With many ECPFs this becomes visible
>>> in host PF probe/boot time. A daemon reacting to the devlink object
>>> appearing can make the userspace side cleaner, but it still runs after the
>>> device has appeared and after userspace scheduling/uevent handling.
>>>
>>> Long term, for these DPU deployments, we would like mlx5 to initialize
>>> directly in switchdev. I am hesitant to make that unconditional because it
>>> changes existing behavior and there is no early opt-out before probe. The
>>> cmdline parameter was meant as an explicit opt-in middle step: ask the
>>> driver to apply the same devlink operation during init, before this path
>>> depends on userspace.
>>>
>>> We previously tried to address this with an mlx5 module parameter. By
>>> design, that was too coarse: it applied to all mlx5 devices handled by the
>>> module. That makes it usable only for narrow DPU-only configurations. The
>>> devlink-handle based cmdline syntax was intended to keep the opt-in scoped
>>> to the specific devices that need this early switchdev transition.
>> 
>> The switchdev mode was introduced at roughly the time CX4 was out. What
>> stopped us from making it default for CX4+ ?
>> 
>> Introducing this horrible plumbing only bacause we were not able to
>> change the default sounds so absurd.
>> 
>> Can we write the default mode as a bit in ASIC NV memory perhaps? Simple
>> devlink cmode permanent param to write it, the driver can read this bit
>> during init to decide the init flow path?
>
>I don't think switchdev by default should mean CX4+ in general. If we get
>there, I would expect it to be limited to the DPU/BlueField/ECPF case, where
>the host PF probe path can depend on the ECPF reaching switchdev. Changing the
>default for regular host NIC deployments feels like a much larger compatibility
>change.

We can't travel throught time, but if from CX5 onwards the default would
be switchdev, nobody would feel broken in terms of compatibility. That
is my point. Having "legacy" as default is simply wrong for never NIC
generations. That is why it is called "legacy" and it should have been
rotten through and out since CX4 times.


>
>For the ASIC/NV bit: maybe technically possible, but it feels like the wrong
>layer. This is boot/deployment policy, not a persistent hardware property, and
>storing it in NV memory would make the state persist across kernels/hosts in a
>surprising way.

Well, as any other nv config, it persists across kernels/hosts. Think
about it as "unbreak-my-not-legacy-device" bit.


>
>I do agree the RFC probably went too far by making a generic devlink cmdline
>configuration language. Maybe the smaller thing to discuss is only:
>
>devlink=[pci/...]:esw:mode:{legacy|switchdev|switchdev_inactive}
>
>No runtime params, no ordering between different operations, just early eswitch
>mode for explicitly selected handles.

FWIW, I'm still against this.


>
>@Jakub, I know you wanted something more generic/extensible, but maybe the
>generic case belongs in the devlinkd/systemd direction Jiri pointed at, while
>the kernel cmdline handles only this early boot eswitch mode case.
>
>Mark

^ permalink raw reply

* Re: [PATCH v9 00/22] Enable FRED with KVM VMX
From: Maciej Wieczor-Retman @ 2026-05-08 18:06 UTC (permalink / raw)
  To: David Woodhouse
  Cc: Andrew Cooper, Xin Li, linux-kernel, kvm, linux-doc,
	Saenz Julienne, Nicolas, pbonzini, seanjc, corbet, tglx, mingo,
	bp, dave.hansen, x86, hpa, luto, peterz, chao.gao, hch,
	sohil.mehta
In-Reply-To: <9de74d88b3c1a2693a4758c023e97826d561c133.camel@infradead.org>

On 2026-05-08 at 15:46:41 +0100, David Woodhouse wrote:
>On Fri, 2026-05-08 at 16:25 +0200, Maciej Wieczor-Retman wrote:
>> 
>> Just tested it and now it works fine :)
>
>Great, thanks. Including the __attribute__((used)) part?

Yeah, I didn't have to modify anything aside from commenting out the ICEBP part
for the test to pass.

>> (aside from the ICEBP thing of course but that's on the kernel side)
>
>Well yes, that was kind of the point in generating the selftest.
>
>I don't have access to hardware right now, but I can do test driven
>development by proxy... :)

Anytime :b

-- 
Kind regards
Maciej Wieczór-Retman

^ permalink raw reply

* Re: [v6 00/10] Reintroduce Hornet LSM
From: Blaise Boscaccy @ 2026-05-08 18:03 UTC (permalink / raw)
  To: Paul Moore
  Cc: Jonathan Corbet, James Morris, Serge E. Hallyn,
	Mickaël Salaün, Günther Noack,
	Dr. David Alan Gilbert, Andrew Morton, James.Bottomley, dhowells,
	Fan Wu, Ryan Foster, Randy Dunlap, linux-security-module,
	linux-doc, linux-kernel, bpf, Song Liu
In-Reply-To: <CAHC9VhScmOoCtoFtccJ6x_cTdwvKCBfUyg=1p-kuAGmo=FdgwA@mail.gmail.com>

Paul Moore <paul@paul-moore.com> writes:

> On Wed, Apr 29, 2026 at 3:14 PM Blaise Boscaccy
> <bboscaccy@linux.microsoft.com> wrote:
>>
>> This patch series introduces the next iteration of the Hornet LSM.
>> Hornet’s goal is to provide a secure and extensible in-kernel
>> signature verification mechanism for eBPF programs.
>
> I see that Fan identified a few issues that need resolution, but I
> just wanted to make sure you've read the expectations for a new LSM.
> To be clear, I think you've ticked all the boxes, and there is a
> MAINTAINERS entry with your name attached, but I just wanted to make
> sure you're okay with maintaining Hornet.  I like Hornet, I think it's
> a nice and fairly clever solution, but the last thing I need is a new
> LSM to maintain :)
>

Yes, I'm good with maintaining Hornet. Thanks Paul

-blaise

> https://github.com/LinuxSecurityModule/kernel#new-lsms
>
> --
> paul-moore.com

^ permalink raw reply

* Re: [RFC net-next 0/4] devlink: Add boot-time defaults
From: Mark Bloch @ 2026-05-08 17:59 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
	David S. Miller, Jonathan Corbet, Shuah Khan, Simon Horman,
	Saeed Mahameed, Leon Romanovsky, Tariq Toukan, Andrew Morton,
	Borislav Petkov (AMD), Randy Dunlap, Dave Hansen,
	Christian Brauner, Petr Mladek, Peter Zijlstra (Intel),
	Thomas Gleixner, Pawan Gupta, Dapeng Mi, Kees Cook, Marco Elver,
	Eric Biggers, Li RongQing, Paul E. McKenney, linux-doc,
	linux-kernel, netdev, linux-rdma
In-Reply-To: <afxvzOjqw-vxUAED@FV6GYCPJ69>



On 07/05/2026 14:03, Jiri Pirko wrote:
> Wed, May 06, 2026 at 07:35:10PM +0200, mbloch@nvidia.com wrote:
>>
>>
>> On 06/05/2026 18:22, Jiri Pirko wrote:
>>> Wed, May 06, 2026 at 02:37:35PM +0200, mbloch@nvidia.com wrote:
>>>> This series adds a devlink= kernel command line parameter for applying
>>>> selected devlink settings during device initialization.
>>>>
>>>> Following a discussion with Jakub[1], I am sending this RFC to get the
>>>> conversation moving. I started from Jakub's example/request and extended
>>>> it to cover requirements from production systems and configurations that
>>>> customers use.
>>>>
>>>> One important caveat is that the parsing logic in this RFC was written
>>>> with AI assistance. I am also not sure whether the resulting syntax and
>>>> parser are too complex for a kernel command line interface. This is part
>>>> of why I am sending it as an RFC: to understand what direction and level
>>>> of complexity would be acceptable to people.
>>>>
>>>> The implementation is intended to support the following properties:
>>>>
>>>> - A system may have multiple devlink devices that usually need the same
>>>>  configuration. For a configuration such as eswitch mode switchdev, a
>>>>  user should be able to specify multiple devices to which that
>>>>  configuration applies.
>>>>
>>>> - There may be ordering dependencies between options. For example, in
>>>>  mlx5, flow_steering_mode should be set before moving to switchdev.
>>>>  With this in mind, defaults are applied per device in the left-to-right
>>>>  order in which they appear on the command line.
>>>>
>>>> The intent is to let deployments set devlink defaults before normal
>>>> userspace orchestration runs, while still using devlink concepts and
>>>
>>> "defaults before normal userspace orchestrarion". I read it as config
>>> before config, which eventually could be skipped.
>>>
>>>
>>>> driver callbacks rather than adding driver-specific module parameters.
>>>> A default is scoped to one or more devlink handles, for example:
>>>>
>>>>  devlink=[pci/0000:08:00.0]:esw:mode:switchdev
>>>>  devlink=[pci/0000:08:00.0]:param:flow_steering_mode:smfs
>>>>  devlink=[pci/0000:08:00.0,pci/0000:08:00.1]:param:flow_steering_mode:hmfs,[pci/0000:08:00.0,pci/0000:08:00.1]:esw:mode:switchdev
>>>
>>> I don't like this. What you do, you are basically introducing user
>>> configuration tool on kernel cmdline.
>>>
>>> The same you would achieve with a proper userspace tool/daemon.
>>> I did try to come up with it and push it here:
>>> https://github.com/systemd/systemd/pull/37393
>>> That didn't get merged for unknown reason, but the idea is sound. You
>>> provide configuration files for devlink object and systemd-devlinkd
>>> will apply when they appear. Wouldn't this help your case?
>>
>> I agree that systemd-devlinkd is the right shape for normal
>> devlink configuration, and it could probably replace the udev/devlink
>> plumbing we use today.
>>
>> The case I am trying to cover is earlier than that.
>>
>> On BlueField/ECPF/DPU systems, the host PF driver cannot always finish
>> probing independently of the ECPF side. When the ECPF is the eswitch
>> manager, the host PF is kept in initializing state until the ECPF eswitch
>> side is set up and mlx5 enables the external host PF HCA. That happens as
>> part of moving the ECPF to switchdev.
>>
>> Today userspace observes the ECPF instance and then switches the
>> mode through devlink, usually via udev or similar plumbing. That still
>> leaves a window where the ECPF has probed, userspace has not applied the
>> mode yet, and the host PF is waiting. With many ECPFs this becomes visible
>> in host PF probe/boot time. A daemon reacting to the devlink object
>> appearing can make the userspace side cleaner, but it still runs after the
>> device has appeared and after userspace scheduling/uevent handling.
>>
>> Long term, for these DPU deployments, we would like mlx5 to initialize
>> directly in switchdev. I am hesitant to make that unconditional because it
>> changes existing behavior and there is no early opt-out before probe. The
>> cmdline parameter was meant as an explicit opt-in middle step: ask the
>> driver to apply the same devlink operation during init, before this path
>> depends on userspace.
>>
>> We previously tried to address this with an mlx5 module parameter. By
>> design, that was too coarse: it applied to all mlx5 devices handled by the
>> module. That makes it usable only for narrow DPU-only configurations. The
>> devlink-handle based cmdline syntax was intended to keep the opt-in scoped
>> to the specific devices that need this early switchdev transition.
> 
> The switchdev mode was introduced at roughly the time CX4 was out. What
> stopped us from making it default for CX4+ ?
> 
> Introducing this horrible plumbing only bacause we were not able to
> change the default sounds so absurd.
> 
> Can we write the default mode as a bit in ASIC NV memory perhaps? Simple
> devlink cmode permanent param to write it, the driver can read this bit
> during init to decide the init flow path?

I don't think switchdev by default should mean CX4+ in general. If we get
there, I would expect it to be limited to the DPU/BlueField/ECPF case, where
the host PF probe path can depend on the ECPF reaching switchdev. Changing the
default for regular host NIC deployments feels like a much larger compatibility
change.

For the ASIC/NV bit: maybe technically possible, but it feels like the wrong
layer. This is boot/deployment policy, not a persistent hardware property, and
storing it in NV memory would make the state persist across kernels/hosts in a
surprising way.

I do agree the RFC probably went too far by making a generic devlink cmdline
configuration language. Maybe the smaller thing to discuss is only:

devlink=[pci/...]:esw:mode:{legacy|switchdev|switchdev_inactive}

No runtime params, no ordering between different operations, just early eswitch
mode for explicitly selected handles.

@Jakub, I know you wanted something more generic/extensible, but maybe the
generic case belongs in the devlinkd/systemd direction Jiri pointed at, while
the kernel cmdline handles only this early boot eswitch mode case.

Mark

^ permalink raw reply

* Re: [PATCH 2/5] docs: fix repeated word 'that' across documentation
From: Paul E. McKenney @ 2026-05-08 17:52 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: Shuah Khan, Adrien Reynard, Frederic Weisbecker, Neeraj Upadhyay,
	Joel Fernandes, Josh Triplett, Boqun Feng, Uladzislau Rezki,
	Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Zqiang,
	Jonathan Corbet, Greg Kroah-Hartman, Rafael J. Wysocki,
	Danilo Krummrich, David Howells, Paulo Alcantara,
	Masami Hiramatsu, open list:READ-COPY UPDATE (RCU),
	open list:DOCUMENTATION, open list,
	open list:DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS,
	open list:FILESYSTEMS [NETFS LIBRARY],
	open list:FILESYSTEMS [NETFS LIBRARY], open list:TRACING
In-Reply-To: <5f68ac30-21ac-494b-a140-2307e236f0a2@infradead.org>

On Fri, May 08, 2026 at 10:40:49AM -0700, Randy Dunlap wrote:
> 
> 
> On 5/8/26 10:15 AM, Shuah Khan wrote:
> > On 5/8/26 10:37, Adrien Reynard wrote:
> > 
> > Missing commit log in all your patches - I don't patch 1/5 in
> > my Inbox.
> > 
> >> Signed-off-by: Adrien Reynard <reynard.adrien.08@gmail.com>
> >> ---
> >>   Documentation/RCU/rcu.rst                          | 2 +-
> >>   Documentation/driver-api/driver-model/overview.rst | 2 +-
> >>   Documentation/filesystems/netfs_library.rst        | 2 +-
> >>   Documentation/trace/histogram-design.rst           | 2 +-
> >>   Documentation/trace/histogram.rst                  | 2 +-
> >>   5 files changed, 5 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/Documentation/RCU/rcu.rst b/Documentation/RCU/rcu.rst
> >> index bf6617b330a7..320ad3292b75 100644
> >> --- a/Documentation/RCU/rcu.rst
> >> +++ b/Documentation/RCU/rcu.rst
> >> @@ -32,7 +32,7 @@ Frequently Asked Questions
> >>     Just as with spinlocks, RCU readers are not permitted to
> >>     block, switch to user-mode execution, or enter the idle loop.
> >>     Therefore, as soon as a CPU is seen passing through any of these
> >> -  three states, we know that that CPU has exited any previous RCU
> >> +  three states, we know that CPU has exited any previous RCU
> > 
> > The original intent might have been to say, "that cpu", so adding
> > the missing comma after the first "that" or change "that" to "the"
> > would make sense.
> 
> Not a comma, please.
> I don't see a problem with "that that," but "that the" could also be OK.

This CPU was already mentioned.  So if for whatever reason we cannnot
stomach "that that", then "that this" would be better than "that the".

I suppose that false positives from simple grammar checkers might be
sufficient reason, but in this brave new world of LLMs, shouldn't we
be hoping for better?  ;-)

						Thanx, Paul

> >>     read-side critical sections.  So, if we remove an item from a
> >>     linked list, and then wait until all CPUs have switched context,
> >>     executed in user mode, or executed in the idle loop, we can
> 
> 
> -- 
> ~Randy
> 

^ permalink raw reply

* Re: [PATCH v4 1/2] usb: xhci-pci: add AMD Promontory 21 PCI glue
From: Jihong Min @ 2026-05-08 17:48 UTC (permalink / raw)
  To: Mario Limonciello, Jihong Min, Greg Kroah-Hartman, Mathias Nyman
  Cc: Guenter Roeck, Jonathan Corbet, Shuah Khan, Basavaraj Natikar,
	linux-usb, linux-hwmon, linux-doc, linux-pci, linux-kernel
In-Reply-To: <966c9e07-10e6-4abe-9cb5-77b974f31302@amd.com>

> Something else I was thinking about while reviewing this series.
>
> Promontory 21 is only on AMD platforms and AMD platforms are only x86. 
> I think the Kconfig should be conditional on AMD CPU support being 
> enabled and X86 architecture so that we don't bloat other 
> architectures with dead code that will never run.
Agreed. PROM21 is AMD x86 platform-specific, so I will add X86 and
CPU_SUP_AMD dependencies to USB_XHCI_PCI_PROM21 for v5.

Sincerely,
Jihong Min

^ permalink raw reply

* Re: [PATCH 4/5] docs: fix repeated prepositions across documentation
From: Randy Dunlap @ 2026-05-08 17:44 UTC (permalink / raw)
  To: Shuah Khan, Adrien Reynard, Andrey Ryabinin, Alexander Potapenko,
	Andrey Konovalov, Dmitry Vyukov, Vincenzo Frascino,
	Jonathan Corbet, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Richard Weinberger, Anton Ivanov,
	Johannes Berg, open list:KASAN, open list:DOCUMENTATION PROCESS,
	open list:DOCUMENTATION, open list,
	open list:NETWORKING [GENERAL], open list:USER-MODE LINUX (UML)
In-Reply-To: <2b771350-0562-4cb1-b9b3-cc3ce59b1a63@linuxfoundation.org>



On 5/8/26 10:23 AM, Shuah Khan wrote:
> On 5/8/26 10:38, Adrien Reynard wrote:
> 
> Missing commit log
> 
>> Signed-off-by: Adrien Reynard <reynard.adrien.08@gmail.com>
>> ---
>>   Documentation/dev-tools/kasan.rst                   | 2 +-
>>   Documentation/networking/switchdev.rst              | 2 +-
>>   Documentation/virt/uml/user_mode_linux_howto_v2.rst | 2 +-
>>   3 files changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/Documentation/dev-tools/kasan.rst b/Documentation/dev-tools/kasan.rst
>> index 4968b2aa60c8..3a8bd40ad905 100644
>> --- a/Documentation/dev-tools/kasan.rst
>> +++ b/Documentation/dev-tools/kasan.rst
>> @@ -392,7 +392,7 @@ reserved to tag freed memory regions.
>>   If the hardware does not support MTE (pre ARMv8.5), Hardware Tag-Based KASAN
>>   will not be enabled. In this case, all KASAN boot parameters are ignored.
>>   -Note that enabling CONFIG_KASAN_HW_TAGS always results in in-kernel TBI being
>> +Note that enabling CONFIG_KASAN_HW_TAGS always results in-kernel TBI being
> 
> This is correct the way it is - no need to change this. "results in in-kernel"

ack.

>>   enabled. Even when ``kasan.mode=off`` is provided or when the hardware does not
>>   support MTE (but supports TBI).
>>   diff --git a/Documentation/networking/switchdev.rst b/Documentation/networking/switchdev.rst
>> index 2966b7122f05..948bce44ca9b 100644
>> --- a/Documentation/networking/switchdev.rst
>> +++ b/Documentation/networking/switchdev.rst
>> @@ -162,7 +162,7 @@ The switchdev driver can know a particular port's position in the topology by
>>   monitoring NETDEV_CHANGEUPPER notifications.  For example, a port moved into a
>>   bond will see its upper master change.  If that bond is moved into a bridge,
>>   the bond's upper master will change.  And so on.  The driver will track such
>> -movements to know what position a port is in in the overall topology by
>> +movements to know what position a port is in the overall topology by
> 
> This looks fine.

Change not needed.

>>   registering for netdevice events and acting on NETDEV_CHANGEUPPER.
>>     L2 Forwarding Offload
>> diff --git a/Documentation/virt/uml/user_mode_linux_howto_v2.rst b/Documentation/virt/uml/user_mode_linux_howto_v2.rst
>> index c37e8e594d12..7b08738c30aa 100644
>> --- a/Documentation/virt/uml/user_mode_linux_howto_v2.rst
>> +++ b/Documentation/virt/uml/user_mode_linux_howto_v2.rst
>> @@ -1092,7 +1092,7 @@ be formatted as plain text.
>>     Developing always goes hand in hand with debugging. First of all,
>>   you can always run UML under gdb and there will be a whole section
>> -later on on how to do that. That, however, is not the only way to
>> +later on how to do that. That, however, is not the only way to
> 
> This change is not needed. If at all add a comma after "later" to make
> a distinction between the use two back to back "on"s
> 
>  "later on,"

We disagree. :)
This change LGTM.

-- 
~Randy


^ permalink raw reply

* Re: [PATCH v4 1/2] usb: xhci-pci: add AMD Promontory 21 PCI glue
From: Mario Limonciello @ 2026-05-08 17:42 UTC (permalink / raw)
  To: Jihong Min, Jihong Min, Greg Kroah-Hartman, Mathias Nyman
  Cc: Guenter Roeck, Jonathan Corbet, Shuah Khan, Basavaraj Natikar,
	linux-usb, linux-hwmon, linux-doc, linux-pci, linux-kernel
In-Reply-To: <0d518d40-e239-4d93-8e71-0d2e140f00ca@icloud.com>



On 5/8/26 12:39, Jihong Min wrote:
>  > This define should be in a common header used by xhci-pci.c and
>  > xhci-pci-prom21.c both.
> 
> Agreed. I moved PCI_DEVICE_ID_AMD_PROM21_XHCI to xhci-pci.h so both
> xhci-pci.c and xhci-pci-prom21.c use the same definition.
> 
> Sincerely,
> Jihong Min
> 

Something else I was thinking about while reviewing this series.

Promontory 21 is only on AMD platforms and AMD platforms are only x86. 
I think the Kconfig should be conditional on AMD CPU support being 
enabled and X86 architecture so that we don't bloat other architectures 
with dead code that will never run.

^ permalink raw reply

* Re: [PATCH 2/5] docs: fix repeated word 'that' across documentation
From: Randy Dunlap @ 2026-05-08 17:40 UTC (permalink / raw)
  To: Shuah Khan, Adrien Reynard, Paul E. McKenney, Frederic Weisbecker,
	Neeraj Upadhyay, Joel Fernandes, Josh Triplett, Boqun Feng,
	Uladzislau Rezki, Steven Rostedt, Mathieu Desnoyers,
	Lai Jiangshan, Zqiang, Jonathan Corbet, Greg Kroah-Hartman,
	Rafael J. Wysocki, Danilo Krummrich, David Howells,
	Paulo Alcantara, Masami Hiramatsu,
	open list:READ-COPY UPDATE (RCU), open list:DOCUMENTATION,
	open list, open list:DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS,
	open list:FILESYSTEMS [NETFS LIBRARY],
	open list:FILESYSTEMS [NETFS LIBRARY], open list:TRACING
In-Reply-To: <1501caea-8cff-4968-aca6-e8d4b20e0e80@linuxfoundation.org>



On 5/8/26 10:15 AM, Shuah Khan wrote:
> On 5/8/26 10:37, Adrien Reynard wrote:
> 
> Missing commit log in all your patches - I don't patch 1/5 in
> my Inbox.
> 
>> Signed-off-by: Adrien Reynard <reynard.adrien.08@gmail.com>
>> ---
>>   Documentation/RCU/rcu.rst                          | 2 +-
>>   Documentation/driver-api/driver-model/overview.rst | 2 +-
>>   Documentation/filesystems/netfs_library.rst        | 2 +-
>>   Documentation/trace/histogram-design.rst           | 2 +-
>>   Documentation/trace/histogram.rst                  | 2 +-
>>   5 files changed, 5 insertions(+), 5 deletions(-)
>>
>> diff --git a/Documentation/RCU/rcu.rst b/Documentation/RCU/rcu.rst
>> index bf6617b330a7..320ad3292b75 100644
>> --- a/Documentation/RCU/rcu.rst
>> +++ b/Documentation/RCU/rcu.rst
>> @@ -32,7 +32,7 @@ Frequently Asked Questions
>>     Just as with spinlocks, RCU readers are not permitted to
>>     block, switch to user-mode execution, or enter the idle loop.
>>     Therefore, as soon as a CPU is seen passing through any of these
>> -  three states, we know that that CPU has exited any previous RCU
>> +  three states, we know that CPU has exited any previous RCU
> 
> The original intent might have been to say, "that cpu", so adding
> the missing comma after the first "that" or change "that" to "the"
> would make sense.

Not a comma, please.
I don't see a problem with "that that," but "that the" could also be OK.

> 
> 
>>     read-side critical sections.  So, if we remove an item from a
>>     linked list, and then wait until all CPUs have switched context,
>>     executed in user mode, or executed in the idle loop, we can


-- 
~Randy


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox