Skip to contentSkip to conversation

6.12.29-rc1 review

PATCH In review Greg Kroah-Hartman 10 participants 194 messages May 12, 2025 – May 14, 2025 Page 2 of 2

Subsystems (2)
lore
Share & tools
lore
author maintainer
#146 lore raw

PATCH 146/184 nvme: unblock ctrl state transition for firmware update

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Daniel Wagner <[email protected]>

[ Upstream commit 650415fca0a97472fdd79725e35152614d1aad76 ]

The original nvme subsystem design didn't have a CONNECTING state; the state machine allowed transitions from RESETTING to LIVE directly.

With the introduction of nvme fabrics the CONNECTING state was introduce. Over time the nvme-pci started to use the CONNECTING state as well.

Eventually, a bug fix for the nvme-fc started to depend that the only valid transition to LIVE was from CONNECTING. Though this change didn't update the firmware update handler which was still depending on RESETTING to LIVE transition.

The simplest way to address it for the time being is to switch into CONNECTING state before going to LIVE state.

---
 drivers/nvme/host/core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/nvme/host/core.c +2 -1
index f19410723b179..98dad1bdff440 100644
@@ -4473,7 +4473,8 @@ static void nvme_fw_act_work(struct work_struct *work)
 		msleep(100);
 	}
 
-	if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE))
+	if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_CONNECTING) ||
+	    !nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE))
 		return;
 
 	nvme_unquiesce_io_queues(ctrl);
Signature · 1 line
2.39.5
author maintainer
#147 lore raw

PATCH 147/184 riscv: misaligned: factorize trap handling

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Clément Léger <[email protected]>

[ Upstream commit fd94de9f9e7aac11ec659e386b9db1203d502023 ]

Since both load/store and user/kernel should use almost the same path and that we are going to add some code around that, factorize it.

Stable-dep-of: 453805f0a28f ("riscv: misaligned: enable IRQs while handling misaligned accesses")

---
 arch/riscv/kernel/traps.c | 66 +++++++++++++++++++++------------------
 1 file changed, 36 insertions(+), 30 deletions(-)
arch/riscv/kernel/traps.c +36 -30
index 8ff8e8b36524b..b1d991c78a233 100644
@@ -198,47 +198,53 @@ asmlinkage __visible __trap_section void do_trap_insn_illegal(struct pt_regs *re
 DO_ERROR_INFO(do_trap_load_fault,
 	SIGSEGV, SEGV_ACCERR, "load access fault");
 
-asmlinkage __visible __trap_section void do_trap_load_misaligned(struct pt_regs *regs)
+enum misaligned_access_type {
+	MISALIGNED_STORE,
+	MISALIGNED_LOAD,
+};
+static const struct {
+	const char *type_str;
+	int (*handler)(struct pt_regs *regs);
+} misaligned_handler[] = {
+	[MISALIGNED_STORE] = {
+		.type_str = "Oops - store (or AMO) address misaligned",
+		.handler = handle_misaligned_store,
+	},
+	[MISALIGNED_LOAD] = {
+		.type_str = "Oops - load address misaligned",
+		.handler = handle_misaligned_load,
+	},
+};
+
+static void do_trap_misaligned(struct pt_regs *regs, enum misaligned_access_type type)
 {
-	if (user_mode(regs)) {
+	irqentry_state_t state;
+
+	if (user_mode(regs))
 		irqentry_enter_from_user_mode(regs);
+	else
+		state = irqentry_nmi_enter(regs);
 
-		if (handle_misaligned_load(regs))
-			do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
-			      "Oops - load address misaligned");
+	if (misaligned_handler[type].handler(regs))
+		do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
+			      misaligned_handler[type].type_str);
 
+	if (user_mode(regs))
 		irqentry_exit_to_user_mode(regs);
-	} else {
-		irqentry_state_t state = irqentry_nmi_enter(regs);
-
-		if (handle_misaligned_load(regs))
-			do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
-			      "Oops - load address misaligned");
-
+	else
 		irqentry_nmi_exit(regs, state);
-	}
 }
 
-asmlinkage __visible __trap_section void do_trap_store_misaligned(struct pt_regs *regs)
+asmlinkage __visible __trap_section void do_trap_load_misaligned(struct pt_regs *regs)
 {
-	if (user_mode(regs)) {
-		irqentry_enter_from_user_mode(regs);
-
-		if (handle_misaligned_store(regs))
-			do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
-				"Oops - store (or AMO) address misaligned");
-
-		irqentry_exit_to_user_mode(regs);
-	} else {
-		irqentry_state_t state = irqentry_nmi_enter(regs);
-
-		if (handle_misaligned_store(regs))
-			do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
-				"Oops - store (or AMO) address misaligned");
+	do_trap_misaligned(regs, MISALIGNED_LOAD);
+}
 
-		irqentry_nmi_exit(regs, state);
-	}
+asmlinkage __visible __trap_section void do_trap_store_misaligned(struct pt_regs *regs)
+{
+	do_trap_misaligned(regs, MISALIGNED_STORE);
 }
+
 DO_ERROR_INFO(do_trap_store_fault,
 	SIGSEGV, SEGV_ACCERR, "store (or AMO) access fault");
 DO_ERROR_INFO(do_trap_ecall_s,
Signature · 1 line
2.39.5
author maintainer
#148 lore raw

PATCH 148/184 riscv: misaligned: enable IRQs while handling misaligned accesses

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Clément Léger <[email protected]>

[ Upstream commit 453805f0a28fc5091e46145e6560c776f7c7a611 ]

We can safely reenable IRQs if coming from userspace. This allows to access user memory that could potentially trigger a page fault.

Fixes b686ecdeacf6 ("riscv: misaligned: Restrict user access to kernel memory")
---
 arch/riscv/kernel/traps.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)
arch/riscv/kernel/traps.c +8 -4
index b1d991c78a233..9c83848797a78 100644
@@ -220,19 +220,23 @@ static void do_trap_misaligned(struct pt_regs *regs, enum misaligned_access_type
 {
 	irqentry_state_t state;
 
-	if (user_mode(regs))
+	if (user_mode(regs)) {
 		irqentry_enter_from_user_mode(regs);
-	else
+		local_irq_enable();
+	} else {
 		state = irqentry_nmi_enter(regs);
+	}
 
 	if (misaligned_handler[type].handler(regs))
 		do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
 			      misaligned_handler[type].type_str);
 
-	if (user_mode(regs))
+	if (user_mode(regs)) {
+		local_irq_disable();
 		irqentry_exit_to_user_mode(regs);
-	else
+	} else {
 		irqentry_nmi_exit(regs, state);
+	}
 }
 
 asmlinkage __visible __trap_section void do_trap_load_misaligned(struct pt_regs *regs)
Signature · 1 line
2.39.5
author maintainer
#149 lore raw

PATCH 149/184 drm/xe/tests/mocs: Update xe_force_wake_get() return handling

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Himal Prasad Ghimiray <[email protected]>

[ Upstream commit 6a966d677d06e96a81d430537abb5db65e2b4fda ]

With xe_force_wake_get() now returning the refcount-incremented domain mask, a return value of 0 indicates failure for single domains. Change assert condition to incorporate this change in return and pass the return value to xe_force_wake_put()

v3
- return xe_wakeref_t instead of int in xe_force_wake_get()

v5
- return unsigned int for xe_force_wake_get()

Stable-dep-of: 51c0ee84e4dc ("drm/xe/tests/mocs: Hold XE_FORCEWAKE_ALL for LNCF regs")

---
 drivers/gpu/drm/xe/tests/xe_mocs.c | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)
drivers/gpu/drm/xe/tests/xe_mocs.c +8 -10
index 79be73b4a02ba..434e7c7e60883 100644
@@ -43,12 +43,11 @@ static void read_l3cc_table(struct xe_gt *gt,
 {
 	struct kunit *test = kunit_get_current_test();
 	u32 l3cc, l3cc_expected;
-	unsigned int i;
+	unsigned int fw_ref, i;
 	u32 reg_val;
-	u32 ret;
 
-	ret = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
-	KUNIT_ASSERT_EQ_MSG(test, ret, 0, "Forcewake Failed.\n");
+	fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
+	KUNIT_ASSERT_NE_MSG(test, fw_ref, 0, "Forcewake Failed.\n");
 
 	for (i = 0; i < info->num_mocs_regs; i++) {
 		if (!(i & 1)) {
@@ -72,7 +71,7 @@ static void read_l3cc_table(struct xe_gt *gt,
 		KUNIT_EXPECT_EQ_MSG(test, l3cc_expected, l3cc,
 				    "l3cc idx=%u has incorrect val.\n", i);
 	}
-	xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
+	xe_force_wake_put(gt_to_fw(gt), fw_ref);
 }
 
 static void read_mocs_table(struct xe_gt *gt,
@@ -80,15 +79,14 @@ static void read_mocs_table(struct xe_gt *gt,
 {
 	struct kunit *test = kunit_get_current_test();
 	u32 mocs, mocs_expected;
-	unsigned int i;
+	unsigned int fw_ref, i;
 	u32 reg_val;
-	u32 ret;
 
 	KUNIT_EXPECT_TRUE_MSG(test, info->unused_entries_index,
 			      "Unused entries index should have been defined\n");
 
-	ret = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
-	KUNIT_ASSERT_EQ_MSG(test, ret, 0, "Forcewake Failed.\n");
+	fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
+	KUNIT_ASSERT_NE_MSG(test, fw_ref, 0, "Forcewake Failed.\n");
 
 	for (i = 0; i < info->num_mocs_regs; i++) {
 		if (regs_are_mcr(gt))
@@ -106,7 +104,7 @@ static void read_mocs_table(struct xe_gt *gt,
 				    "mocs reg 0x%x has incorrect val.\n", i);
 	}
 
-	xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
+	xe_force_wake_put(gt_to_fw(gt), fw_ref);
 }
 
 static int mocs_kernel_test_run_device(struct xe_device *xe)
Signature · 1 line
2.39.5
author maintainer
#150 lore raw

PATCH 150/184 drm/xe/tests/mocs: Hold XE_FORCEWAKE_ALL for LNCF regs

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tejas Upadhyay <[email protected]>

[ Upstream commit 51c0ee84e4dc339287b2d7335f2b54d747794c83 ]

LNCF registers report wrong values when XE_FORCEWAKE_GT only is held. Holding XE_FORCEWAKE_ALL ensures correct operations on LNCF regs.

V2(Himal):
- Use xe_force_wake_ref_has_domain

Fixes a6a4ea6d7d37 ("drm/xe: Add mocs kunit")
(cherry picked from commit 70a2585e582058e94fe4381a337be42dec800337)
---
 drivers/gpu/drm/xe/tests/xe_mocs.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/gpu/drm/xe/tests/xe_mocs.c +5 -2
index 434e7c7e60883..61a7d20ce42bf 100644
@@ -46,8 +46,11 @@ static void read_l3cc_table(struct xe_gt *gt,
 	unsigned int fw_ref, i;
 	u32 reg_val;
 
-	fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
-	KUNIT_ASSERT_NE_MSG(test, fw_ref, 0, "Forcewake Failed.\n");
+	fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
+	if (!xe_force_wake_ref_has_domain(fw_ref, XE_FORCEWAKE_ALL)) {
+		xe_force_wake_put(gt_to_fw(gt), fw_ref);
+		KUNIT_ASSERT_TRUE_MSG(test, true, "Forcewake Failed.\n");
+	}
 
 	for (i = 0; i < info->num_mocs_regs; i++) {
 		if (!(i & 1)) {
Signature · 1 line
2.39.5
author maintainer
#151 lore raw

PATCH 151/184 io_uring/sqpoll: Increase task_work submission batch size

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Gabriel Krisman Bertazi <[email protected]>

[ Upstream commit 92835cebab120f8a5f023a26a792a2ac3f816c4f ]

Our QA team reported a 10%-23%, throughput reduction on an io_uring sqpoll testcase doing IO to a null_blk, that I traced back to a reduction of the device submission queue depth utilization. It turns out that, after commit af5d68f8892f ("io_uring/sqpoll: manage task_work privately"), we capped the number of task_work entries that can be completed from a single spin of sqpoll to only 8 entries, before the sqpoll goes around to (potentially) sleep. While this cap doesn't drive the submission side directly, it impacts the completion behavior, which affects the number of IO queued by fio per sqpoll cycle on the submission side, and io_uring ends up seeing less ios per sqpoll cycle. As a result, block layer plugging is less effective, and we see more time spent inside the block layer in profilings charts, and increased submission latency measured by fio.

There are other places that have increased overhead once sqpoll sleeps more often, such as the sqpoll utilization calculation. But, in this microbenchmark, those were not representative enough in perf charts, and their removal didn't yield measurable changes in throughput. The major overhead comes from the fact we plug less, and less often, when submitting to the block layer.

My benchmark is:

fio --ioengine=io_uring --direct=1 --iodepth=128 --runtime=300 --bs=4k \
    --invalidate=1 --time_based  --ramp_time=10 --group_reporting=1 \
    --filename=/dev/nullb0 --name=RandomReads-direct-nullb-sqpoll-4k-1 \
    --rw=randread --numjobs=1 --sqthread_poll

In one machine, tested on top of Linux 6.15-rc1, we have the following
baseline:
READ: bw=4994MiB/s (5236MB/s), 4994MiB/s-4994MiB/s (5236MB/s-5236MB/s), io=439GiB (471GB), run=90001-90001msec

With this patch:
READ: bw=5762MiB/s (6042MB/s), 5762MiB/s-5762MiB/s (6042MB/s-6042MB/s), io=506GiB (544GB), run=90001-90001msec

which is a 15% improvement in measured bandwidth. The average submission latency is noticeably lowered too. As measured by fio:

Baseline:
lat (usec): min=20, max=241, avg=99.81, stdev=3.38
Patched:
lat (usec): min=26, max=226, avg=86.48, stdev=4.82

If we look at blktrace, we can also see the plugging behavior is improved. In the baseline, we end up limited to plugging 8 requests in the block layer regardless of the device queue depth size, while after patching we can drive more io, and we manage to utilize the full device queue.

In the baseline, after a stabilization phase, an ordinary submission looks like:
254,0 1 49942 0.016028795 5977 U N [iou-sqp-5976] 7

After patching, I see consistently more requests per unplug.
254,0 1 4996 0.001432872 3145 U N [iou-sqp-3144] 32

Ideally, the cap size would at least be the deep enough to fill the device queue, but we can't predict that behavior, or assume all IO goes to a single device, and thus can't guess the ideal batch size. We also don't want to let the tw run unbounded, though I'm not sure it would really be a problem. Instead, let's just give it a more sensible value that will allow for more efficient batching. I've tested with different cap values, and initially proposed to increase the cap to 1024. Jens argued it is too big of a bump and I observed that, with 32, I'm no longer able to observe this bottleneck in any of my machines.

Fixes af5d68f8892f ("io_uring/sqpoll: manage task_work privately")
---
 io_uring/sqpoll.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
io_uring/sqpoll.c +1 -1
index 5bc54c6df20fd..430922c541681 100644
@@ -20,7 +20,7 @@
 #include "sqpoll.h"
 
 #define IORING_SQPOLL_CAP_ENTRIES_VALUE 8
-#define IORING_TW_CAP_ENTRIES_VALUE	8
+#define IORING_TW_CAP_ENTRIES_VALUE	32
 
 enum {
 	IO_SQ_THREAD_SHOULD_STOP = 0,
Signature · 1 line
2.39.5
author maintainer
#152 lore raw

PATCH 152/184 do_umount(): add missing barrier before refcount checks in sync case

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Al Viro <[email protected]>

[ Upstream commit 65781e19dcfcb4aed1167d87a3ffcc2a0c071d47 ]

do_umount() analogue of the race fixed in 119e1ef80ecf "fix __legitimize_mnt()/mntput() race". Here we want to make sure that if __legitimize_mnt() doesn't notice our lock_mount_hash(), we will notice their refcount increment. Harder to hit than mntput_no_expire() one, fortunately, and consequences are milder (sync umount acting like umount -l on a rare race with RCU pathwalk hitting at just the wrong time instead of use-after-free galore mntput_no_expire() counterpart used to be hit). Still a bug...

Fixes 48a066e72d97 ("RCU'd vfsmounts")
---
 fs/namespace.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
fs/namespace.c +2 -1
index bd601ab26e781..c3c1e8c644f2e 100644
@@ -747,7 +747,7 @@ int __legitimize_mnt(struct vfsmount *bastard, unsigned seq)
 		return 0;
 	mnt = real_mount(bastard);
 	mnt_add_count(mnt, 1);
-	smp_mb();			// see mntput_no_expire()
+	smp_mb();		// see mntput_no_expire() and do_umount()
 	if (likely(!read_seqretry(&mount_lock, seq)))
 		return 0;
 	if (bastard->mnt_flags & MNT_SYNC_UMOUNT) {
@@ -1916,6 +1916,7 @@ static int do_umount(struct mount *mnt, int flags)
 			umount_tree(mnt, UMOUNT_PROPAGATE);
 		retval = 0;
 	} else {
+		smp_mb(); // paired with __legitimize_mnt()
 		shrink_submounts(mnt);
 		retval = -EBUSY;
 		if (!propagate_mount_busy(mnt, 2)) {
Signature · 1 line
2.39.5
author maintainer
#153 lore raw

PATCH 153/184 Revert "um: work around sched_yield not yielding in time-travel mode"

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Christian Lamparter <[email protected]>

This reverts commit da780c4a075ba2deb05ae29f0af4a990578c7901 which is commit 887c5c12e80c8424bd471122d2e8b6b462e12874 upstream.

Reason being that the patch depends on at least commit 0b8b2668f998 ("um: insert scheduler ticks when userspace does not yield") in order to build. Otherwise it fails with:

| /usr/bin/ld: arch/um/kernel/skas/syscall.o: in function `handle_syscall':
|      linux-6.12.27/arch/um/kernel/skas/syscall.c:43:(.text+0xa2): undefined
| reference to `tt_extra_sched_jiffies'
| collect2: error: ld returned 1 exit status

The author Benjamin Berg commented: "I think it is better to just not backport commit 0b8b2668f998 ("um: insert scheduler ticks when userspace does not yield")"

---
 arch/um/include/linux/time-internal.h |    2 --
 arch/um/kernel/skas/syscall.c         |   11 -----------
 2 files changed, 13 deletions(-)
arch/um/include/linux/time-internal.h +0 -2
@@ -83,8 +83,6 @@ extern void time_travel_not_configured(v
 #define time_travel_del_event(...) time_travel_not_configured()
 #endif /* CONFIG_UML_TIME_TRAVEL_SUPPORT */
 
-extern unsigned long tt_extra_sched_jiffies;
-
 /*
  * Without CONFIG_UML_TIME_TRAVEL_SUPPORT this is a linker error if used,
  * which is intentional since we really shouldn't link it in that case.
arch/um/kernel/skas/syscall.c +0 -11
@@ -31,17 +31,6 @@ void handle_syscall(struct uml_pt_regs *
 		goto out;
 
 	syscall = UPT_SYSCALL_NR(r);
-
-	/*
-	 * If no time passes, then sched_yield may not actually yield, causing
-	 * broken spinlock implementations in userspace (ASAN) to hang for long
-	 * periods of time.
-	 */
-	if ((time_travel_mode == TT_MODE_INFCPU ||
-	     time_travel_mode == TT_MODE_EXTERNAL) &&
-	    syscall == __NR_sched_yield)
-		tt_extra_sched_jiffies += 1;
-
 	if (syscall >= 0 && syscall < __NR_syscalls) {
 		unsigned long ret = EXECUTE_SYSCALL(syscall, regs);
 
author maintainer
#154 lore raw

PATCH 154/184 rust: allow Rust 1.87.0s `clippy::ptr_eq` lint

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Miguel Ojeda <[email protected]>

commit a39f3087092716f2bd531d6fdc20403c3dc2a879 upstream.

Starting with Rust 1.87.0 (expected 2025-05-15) [1], Clippy may expand the ptr_eq lint, e.g.:

    error: use `core::ptr::eq` when comparing raw pointers
       --> rust/kernel/list.rs:438:12
        |
    438 |         if self.first == item {
        |            ^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(self.first, item)`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_eq
        = note: `-D clippy::ptr-eq` implied by `-D warnings`
        = help: to override `-D warnings` add `#[allow(clippy::ptr_eq)]`

It is expected that a PR to relax the lint will be backported [2] by the time Rust 1.87.0 releases, since the lint was considered too eager (at least by default) [3].

Thus allow the lint temporarily just in case.

---
 rust/kernel/alloc/kvec.rs |    3 +++
 rust/kernel/list.rs       |    3 +++
 2 files changed, 6 insertions(+)
rust/kernel/alloc/kvec.rs +3 -0
@@ -2,6 +2,9 @@
 
 //! Implementation of [`Vec`].
 
+// May not be needed in Rust 1.87.0 (pending beta backport).
+#![allow(clippy::ptr_eq)]
+
 use super::{
     allocator::{KVmalloc, Kmalloc, Vmalloc},
     layout::ArrayLayout,
rust/kernel/list.rs +3 -0
@@ -4,6 +4,9 @@
 
 //! A linked list implementation.
 
+// May not be needed in Rust 1.87.0 (pending beta backport).
+#![allow(clippy::ptr_eq)]
+
 use crate::init::PinInit;
 use crate::sync::ArcBorrow;
 use crate::types::Opaque;
author maintainer
#155 lore raw

PATCH 155/184 rust: clean Rust 1.88.0s `clippy::uninlined_format_args` lint

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Miguel Ojeda <[email protected]>

commit 211dcf77856db64c73e0c3b9ce0c624ec855daca upstream.

Starting with Rust 1.88.0 (expected 2025-06-26) [1], rustc may move back the uninlined_format_args to style from pedantic (it was there waiting for rust-analyzer suppotr), and thus we will start to see lints like:

    warning: variables can be used directly in the `format!` string
       --> rust/macros/kunit.rs:105:37
        |
    105 |         let kunit_wrapper_fn_name = format!("kunit_rust_wrapper_{}", test);
        |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
        |
    105 -         let kunit_wrapper_fn_name = format!("kunit_rust_wrapper_{}", test);
    105 +         let kunit_wrapper_fn_name = format!("kunit_rust_wrapper_{test}");

There is even a case that is a pure removal:

    warning: variables can be used directly in the `format!` string
      --> rust/macros/module.rs:51:13
       |
    51 |             format!("{field}={content}\0", field = field, content = content)
       |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
       |
    51 -             format!("{field}={content}\0", field = field, content = content)
    51 +             format!("{field}={content}\0")

The lints all seem like nice cleanups, thus just apply them.

We may want to disable allow-mixed-uninlined-format-args in the future.

---
 rust/kernel/str.rs         |   46 ++++++++++++++++++++++-----------------------
 rust/macros/module.rs      |   19 ++++--------------
 rust/macros/pinned_drop.rs |    3 --
 3 files changed, 29 insertions(+), 39 deletions(-)
rust/kernel/str.rs +23 -23
@@ -55,7 +55,7 @@ impl fmt::Display for BStr {
                 b'\r' => f.write_str("\\r")?,
                 // Printable characters.
                 0x20..=0x7e => f.write_char(b as char)?,
-                _ => write!(f, "\\x{:02x}", b)?,
+                _ => write!(f, "\\x{b:02x}")?,
             }
         }
         Ok(())
@@ -90,7 +90,7 @@ impl fmt::Debug for BStr {
                 b'\\' => f.write_str("\\\\")?,
                 // Printable characters.
                 0x20..=0x7e => f.write_char(b as char)?,
-                _ => write!(f, "\\x{:02x}", b)?,
+                _ => write!(f, "\\x{b:02x}")?,
             }
         }
         f.write_char('"')
@@ -397,7 +397,7 @@ impl fmt::Display for CStr {
                 // Printable character.
                 f.write_char(c as char)?;
             } else {
-                write!(f, "\\x{:02x}", c)?;
+                write!(f, "\\x{c:02x}")?;
             }
         }
         Ok(())
@@ -428,7 +428,7 @@ impl fmt::Debug for CStr {
                 // Printable characters.
                 b'\"' => f.write_str("\\\"")?,
                 0x20..=0x7e => f.write_char(c as char)?,
-                _ => write!(f, "\\x{:02x}", c)?,
+                _ => write!(f, "\\x{c:02x}")?,
             }
         }
         f.write_str("\"")
@@ -588,13 +588,13 @@ mod tests {
     #[test]
     fn test_cstr_display() {
         let hello_world = CStr::from_bytes_with_nul(b"hello, world!\0").unwrap();
-        assert_eq!(format!("{}", hello_world), "hello, world!");
+        assert_eq!(format!("{hello_world}"), "hello, world!");
         let non_printables = CStr::from_bytes_with_nul(b"\x01\x09\x0a\0").unwrap();
-        assert_eq!(format!("{}", non_printables), "\\x01\\x09\\x0a");
+        assert_eq!(format!("{non_printables}"), "\\x01\\x09\\x0a");
         let non_ascii = CStr::from_bytes_with_nul(b"d\xe9j\xe0 vu\0").unwrap();
-        assert_eq!(format!("{}", non_ascii), "d\\xe9j\\xe0 vu");
+        assert_eq!(format!("{non_ascii}"), "d\\xe9j\\xe0 vu");
         let good_bytes = CStr::from_bytes_with_nul(b"\xf0\x9f\xa6\x80\0").unwrap();
-        assert_eq!(format!("{}", good_bytes), "\\xf0\\x9f\\xa6\\x80");
+        assert_eq!(format!("{good_bytes}"), "\\xf0\\x9f\\xa6\\x80");
     }
 
     #[test]
@@ -605,47 +605,47 @@ mod tests {
             bytes[i as usize] = i.wrapping_add(1);
         }
         let cstr = CStr::from_bytes_with_nul(&bytes).unwrap();
-        assert_eq!(format!("{}", cstr), ALL_ASCII_CHARS);
+        assert_eq!(format!("{cstr}"), ALL_ASCII_CHARS);
     }
 
     #[test]
     fn test_cstr_debug() {
         let hello_world = CStr::from_bytes_with_nul(b"hello, world!\0").unwrap();
-        assert_eq!(format!("{:?}", hello_world), "\"hello, world!\"");
+        assert_eq!(format!("{hello_world:?}"), "\"hello, world!\"");
         let non_printables = CStr::from_bytes_with_nul(b"\x01\x09\x0a\0").unwrap();
-        assert_eq!(format!("{:?}", non_printables), "\"\\x01\\x09\\x0a\"");
+        assert_eq!(format!("{non_printables:?}"), "\"\\x01\\x09\\x0a\"");
         let non_ascii = CStr::from_bytes_with_nul(b"d\xe9j\xe0 vu\0").unwrap();
-        assert_eq!(format!("{:?}", non_ascii), "\"d\\xe9j\\xe0 vu\"");
+        assert_eq!(format!("{non_ascii:?}"), "\"d\\xe9j\\xe0 vu\"");
         let good_bytes = CStr::from_bytes_with_nul(b"\xf0\x9f\xa6\x80\0").unwrap();
-        assert_eq!(format!("{:?}", good_bytes), "\"\\xf0\\x9f\\xa6\\x80\"");
+        assert_eq!(format!("{good_bytes:?}"), "\"\\xf0\\x9f\\xa6\\x80\"");
     }
 
     #[test]
     fn test_bstr_display() {
         let hello_world = BStr::from_bytes(b"hello, world!");
-        assert_eq!(format!("{}", hello_world), "hello, world!");
+        assert_eq!(format!("{hello_world}"), "hello, world!");
         let escapes = BStr::from_bytes(b"_\t_\n_\r_\\_\'_\"_");
-        assert_eq!(format!("{}", escapes), "_\\t_\\n_\\r_\\_'_\"_");
+        assert_eq!(format!("{escapes}"), "_\\t_\\n_\\r_\\_'_\"_");
         let others = BStr::from_bytes(b"\x01");
-        assert_eq!(format!("{}", others), "\\x01");
+        assert_eq!(format!("{others}"), "\\x01");
         let non_ascii = BStr::from_bytes(b"d\xe9j\xe0 vu");
-        assert_eq!(format!("{}", non_ascii), "d\\xe9j\\xe0 vu");
+        assert_eq!(format!("{non_ascii}"), "d\\xe9j\\xe0 vu");
         let good_bytes = BStr::from_bytes(b"\xf0\x9f\xa6\x80");
-        assert_eq!(format!("{}", good_bytes), "\\xf0\\x9f\\xa6\\x80");
+        assert_eq!(format!("{good_bytes}"), "\\xf0\\x9f\\xa6\\x80");
     }
 
     #[test]
     fn test_bstr_debug() {
         let hello_world = BStr::from_bytes(b"hello, world!");
-        assert_eq!(format!("{:?}", hello_world), "\"hello, world!\"");
+        assert_eq!(format!("{hello_world:?}"), "\"hello, world!\"");
         let escapes = BStr::from_bytes(b"_\t_\n_\r_\\_\'_\"_");
-        assert_eq!(format!("{:?}", escapes), "\"_\\t_\\n_\\r_\\\\_'_\\\"_\"");
+        assert_eq!(format!("{escapes:?}"), "\"_\\t_\\n_\\r_\\\\_'_\\\"_\"");
         let others = BStr::from_bytes(b"\x01");
-        assert_eq!(format!("{:?}", others), "\"\\x01\"");
+        assert_eq!(format!("{others:?}"), "\"\\x01\"");
         let non_ascii = BStr::from_bytes(b"d\xe9j\xe0 vu");
-        assert_eq!(format!("{:?}", non_ascii), "\"d\\xe9j\\xe0 vu\"");
+        assert_eq!(format!("{non_ascii:?}"), "\"d\\xe9j\\xe0 vu\"");
         let good_bytes = BStr::from_bytes(b"\xf0\x9f\xa6\x80");
-        assert_eq!(format!("{:?}", good_bytes), "\"\\xf0\\x9f\\xa6\\x80\"");
+        assert_eq!(format!("{good_bytes:?}"), "\"\\xf0\\x9f\\xa6\\x80\"");
     }
 }
 
rust/macros/module.rs +5 -14
@@ -48,7 +48,7 @@ impl<'a> ModInfoBuilder<'a> {
             )
         } else {
             // Loadable modules' modinfo strings go as-is.
-            format!("{field}={content}\0", field = field, content = content)
+            format!("{field}={content}\0")
         };
 
         write!(
@@ -124,10 +124,7 @@ impl ModuleInfo {
             };
 
             if seen_keys.contains(&key) {
-                panic!(
-                    "Duplicated key \"{}\". Keys can only be specified once.",
-                    key
-                );
+                panic!("Duplicated key \"{key}\". Keys can only be specified once.");
             }
 
             assert_eq!(expect_punct(it), ':');
@@ -140,10 +137,7 @@ impl ModuleInfo {
                 "license" => info.license = expect_string_ascii(it),
                 "alias" => info.alias = Some(expect_string_array(it)),
                 "firmware" => info.firmware = Some(expect_string_array(it)),
-                _ => panic!(
-                    "Unknown key \"{}\". Valid keys are: {:?}.",
-                    key, EXPECTED_KEYS
-                ),
+                _ => panic!("Unknown key \"{key}\". Valid keys are: {EXPECTED_KEYS:?}."),
             }
 
             assert_eq!(expect_punct(it), ',');
@@ -155,7 +149,7 @@ impl ModuleInfo {
 
         for key in REQUIRED_KEYS {
             if !seen_keys.iter().any(|e| e == key) {
-                panic!("Missing required key \"{}\".", key);
+                panic!("Missing required key \"{key}\".");
             }
         }
 
@@ -167,10 +161,7 @@ impl ModuleInfo {
         }
 
         if seen_keys != ordered_keys {
-            panic!(
-                "Keys are not ordered as expected. Order them like: {:?}.",
-                ordered_keys
-            );
+            panic!("Keys are not ordered as expected. Order them like: {ordered_keys:?}.");
         }
 
         info
rust/macros/pinned_drop.rs +1 -2
@@ -25,8 +25,7 @@ pub(crate) fn pinned_drop(_args: TokenSt
             // Found the end of the generics, this should be `PinnedDrop`.
             assert!(
                 matches!(tt, TokenTree::Ident(i) if i.to_string() == "PinnedDrop"),
-                "expected 'PinnedDrop', found: '{:?}'",
-                tt
+                "expected 'PinnedDrop', found: '{tt:?}'"
             );
             pinned_drop_idx = Some(i);
             break;
author maintainer
#156 lore raw

PATCH 156/184 io_uring: always arm linked timeouts prior to issue

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jens Axboe <[email protected]>

Commit b53e523261bf058ea4a518b482222e7a277b186b upstream.

There are a few spots where linked timeouts are armed, and not all of them adhere to the pre-arm, attempt issue, post-arm pattern. This can be problematic if the linked request returns that it will trigger a callback later, and does so before the linked timeout is fully armed.

Consolidate all the linked timeout handling into __io_issue_sqe(), rather than have it spread throughout the various issue entry points.

---
 io_uring/io_uring.c |   50 +++++++++++++++-----------------------------------
 1 file changed, 15 insertions(+), 35 deletions(-)
io_uring/io_uring.c +15 -35
@@ -441,24 +441,6 @@ static struct io_kiocb *__io_prep_linked
 	return req->link;
 }
 
-static inline struct io_kiocb *io_prep_linked_timeout(struct io_kiocb *req)
-{
-	if (likely(!(req->flags & REQ_F_ARM_LTIMEOUT)))
-		return NULL;
-	return __io_prep_linked_timeout(req);
-}
-
-static noinline void __io_arm_ltimeout(struct io_kiocb *req)
-{
-	io_queue_linked_timeout(__io_prep_linked_timeout(req));
-}
-
-static inline void io_arm_ltimeout(struct io_kiocb *req)
-{
-	if (unlikely(req->flags & REQ_F_ARM_LTIMEOUT))
-		__io_arm_ltimeout(req);
-}
-
 static void io_prep_async_work(struct io_kiocb *req)
 {
 	const struct io_issue_def *def = &io_issue_defs[req->opcode];
@@ -511,7 +493,6 @@ static void io_prep_async_link(struct io
 
 static void io_queue_iowq(struct io_kiocb *req)
 {
-	struct io_kiocb *link = io_prep_linked_timeout(req);
 	struct io_uring_task *tctx = req->task->io_uring;
 
 	BUG_ON(!tctx);
@@ -536,8 +517,6 @@ static void io_queue_iowq(struct io_kioc
 
 	trace_io_uring_queue_async_work(req, io_wq_is_hashed(&req->work));
 	io_wq_enqueue(tctx->io_wq, &req->work);
-	if (link)
-		io_queue_linked_timeout(link);
 }
 
 static void io_req_queue_iowq_tw(struct io_kiocb *req, struct io_tw_state *ts)
@@ -1731,17 +1710,24 @@ static bool io_assign_file(struct io_kio
 	return !!req->file;
 }
 
+#define REQ_ISSUE_SLOW_FLAGS	(REQ_F_CREDS | REQ_F_ARM_LTIMEOUT)
+
 static int io_issue_sqe(struct io_kiocb *req, unsigned int issue_flags)
 {
 	const struct io_issue_def *def = &io_issue_defs[req->opcode];
 	const struct cred *creds = NULL;
+	struct io_kiocb *link = NULL;
 	int ret;
 
 	if (unlikely(!io_assign_file(req, def, issue_flags)))
 		return -EBADF;
 
-	if (unlikely((req->flags & REQ_F_CREDS) && req->creds != current_cred()))
-		creds = override_creds(req->creds);
+	if (unlikely(req->flags & REQ_ISSUE_SLOW_FLAGS)) {
+		if ((req->flags & REQ_F_CREDS) && req->creds != current_cred())
+			creds = override_creds(req->creds);
+		if (req->flags & REQ_F_ARM_LTIMEOUT)
+			link = __io_prep_linked_timeout(req);
+	}
 
 	if (!def->audit_skip)
 		audit_uring_entry(req->opcode);
@@ -1751,8 +1737,12 @@ static int io_issue_sqe(struct io_kiocb
 	if (!def->audit_skip)
 		audit_uring_exit(!ret, ret);
 
-	if (creds)
-		revert_creds(creds);
+	if (unlikely(creds || link)) {
+		if (creds)
+			revert_creds(creds);
+		if (link)
+			io_queue_linked_timeout(link);
+	}
 
 	if (ret == IOU_OK) {
 		if (issue_flags & IO_URING_F_COMPLETE_DEFER)
@@ -1765,7 +1755,6 @@ static int io_issue_sqe(struct io_kiocb
 
 	if (ret == IOU_ISSUE_SKIP_COMPLETE) {
 		ret = 0;
-		io_arm_ltimeout(req);
 
 		/* If the op doesn't have a file, we're not polling for it */
 		if ((req->ctx->flags & IORING_SETUP_IOPOLL) && def->iopoll_queue)
@@ -1808,8 +1797,6 @@ void io_wq_submit_work(struct io_wq_work
 	else
 		req_ref_get(req);
 
-	io_arm_ltimeout(req);
-
 	/* either cancelled or io-wq is dying, so don't touch tctx->iowq */
 	if (atomic_read(&work->flags) & IO_WQ_WORK_CANCEL) {
 fail:
@@ -1929,15 +1916,11 @@ struct file *io_file_get_normal(struct i
 static void io_queue_async(struct io_kiocb *req, int ret)
 	__must_hold(&req->ctx->uring_lock)
 {
-	struct io_kiocb *linked_timeout;
-
 	if (ret != -EAGAIN || (req->flags & REQ_F_NOWAIT)) {
 		io_req_defer_failed(req, ret);
 		return;
 	}
 
-	linked_timeout = io_prep_linked_timeout(req);
-
 	switch (io_arm_poll_handler(req, 0)) {
 	case IO_APOLL_READY:
 		io_kbuf_recycle(req, 0);
@@ -1950,9 +1933,6 @@ static void io_queue_async(struct io_kio
 	case IO_APOLL_OK:
 		break;
 	}
-
-	if (linked_timeout)
-		io_queue_linked_timeout(linked_timeout);
 }
 
 static inline void io_queue_sqe(struct io_kiocb *req)
author maintainer
#157 lore raw

PATCH 157/184 Bluetooth: btmtk: Remove resetting mt7921 before downloading the fw

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hao Qin <[email protected]>

commit a7208610761ae9b3bc109ddc493eb7c332fca5b2 upstream.

Remove resetting mt7921 before downloading the fw, as it may cause command timeout when performing the reset.

---
 drivers/bluetooth/btmtk.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/bluetooth/btmtk.c +2 -2
@@ -1329,7 +1329,6 @@ int btmtk_usb_setup(struct hci_dev *hdev
 		fwname = FIRMWARE_MT7668;
 		break;
 	case 0x7922:
-	case 0x7961:
 	case 0x7925:
 		/* Reset the device to ensure it's in the initial state before
 		 * downloading the firmware to ensure.
@@ -1337,7 +1336,8 @@ int btmtk_usb_setup(struct hci_dev *hdev
 
 		if (!test_bit(BTMTK_FIRMWARE_LOADED, &btmtk_data->flags))
 			btmtk_usb_subsys_reset(hdev, dev_id);
-
+		fallthrough;
+	case 0x7961:
 		btmtk_fw_get_filename(fw_bin_name, sizeof(fw_bin_name), dev_id,
 				      fw_version, fw_flavor);
 
author maintainer
#158 lore raw

PATCH 158/184 Bluetooth: btmtk: Remove the resetting step before downloading the fw

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hao Qin <[email protected]>

commit 33634e2ab7c6369391e0ca4b9b97dc861e33d20e upstream.

Remove the resetting step before downloading the fw, as it may cause other usb devices to fail to initialise when connected during boot on kernels 6.11 and newer.

---
 drivers/bluetooth/btmtk.c |   10 ----------
 1 file changed, 10 deletions(-)
drivers/bluetooth/btmtk.c +0 -10
@@ -1330,13 +1330,6 @@ int btmtk_usb_setup(struct hci_dev *hdev
 		break;
 	case 0x7922:
 	case 0x7925:
-		/* Reset the device to ensure it's in the initial state before
-		 * downloading the firmware to ensure.
-		 */
-
-		if (!test_bit(BTMTK_FIRMWARE_LOADED, &btmtk_data->flags))
-			btmtk_usb_subsys_reset(hdev, dev_id);
-		fallthrough;
 	case 0x7961:
 		btmtk_fw_get_filename(fw_bin_name, sizeof(fw_bin_name), dev_id,
 				      fw_version, fw_flavor);
@@ -1345,12 +1338,9 @@ int btmtk_usb_setup(struct hci_dev *hdev
 						btmtk_usb_hci_wmt_sync);
 		if (err < 0) {
 			bt_dev_err(hdev, "Failed to set up firmware (%d)", err);
-			clear_bit(BTMTK_FIRMWARE_LOADED, &btmtk_data->flags);
 			return err;
 		}
 
-		set_bit(BTMTK_FIRMWARE_LOADED, &btmtk_data->flags);
-
 		/* It's Device EndPoint Reset Option Register */
 		err = btmtk_usb_uhw_reg_write(hdev, MTK_EP_RST_OPT,
 					      MTK_EP_RST_IN_OUT_OPT);
author maintainer
#159 lore raw

PATCH 159/184 mm: page_alloc: dont steal single pages from biggest buddy

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johannes Weiner <[email protected]>

commit c2f6ea38fc1b640aa7a2e155cc1c0410ff91afa2 upstream.

The fallback code searches for the biggest buddy first in an attempt to steal the whole block and encourage type grouping down the line.

The approach used to be this:

- Non-movable requests will split the largest buddy and steal the remainder. This splits up contiguity, but it allows subsequent requests of this type to fall back into adjacent space.

- Movable requests go and look for the smallest buddy instead. The thinking is that movable requests can be compacted, so grouping is less important than retaining contiguity.

c0cd6f557b90 ("mm: page_alloc: fix freelist movement during block conversion") enforces freelist type hygiene, which restricts stealing to either claiming the whole block or just taking the requested chunk; no additional pages or buddy remainders can be stolen any more.

The patch mishandled when to switch to finding the smallest buddy in that new reality. As a result, it may steal the exact request size, but from the biggest buddy. This causes fracturing for no good reason.

Fix this by committing to the new behavior: either steal the whole block, or fall back to the smallest buddy.

Remove single-page stealing from steal_suitable_fallback(). Rename it to try_to_steal_block() to make the intentions clear. If this fails, always fall back to the smallest buddy.

The following is from 4 runs of mmtest's thpchallenge. "Pollute" is single page fallback, "steal" is conversion of a partially used block. The numbers for free block conversions (omitted) are comparable.

vanilla patched

@pollute[unmovable from reclaimable]: 27 106
@pollute[unmovable from movable]: 82 46
@pollute[reclaimable from unmovable]: 256 83
@pollute[reclaimable from movable]: 46 8
@pollute[movable from unmovable]: 4841 868
@pollute[movable from reclaimable]: 5278 12568

@steal[unmovable from reclaimable]: 11 12
@steal[unmovable from movable]: 113 49
@steal[reclaimable from unmovable]: 19 34
@steal[reclaimable from movable]: 47 21
@steal[movable from unmovable]: 250 183
@steal[movable from reclaimable]: 81 93

The allocator appears to do a better job at keeping stealing and polluting to the first fallback preference. As a result, the numbers for "from movable" - the least preferred fallback option, and most detrimental to compactability - are down across the board.

---
 mm/page_alloc.c |   80 +++++++++++++++++++++++---------------------------------
 1 file changed, 34 insertions(+), 46 deletions(-)
mm/page_alloc.c +34 -46
@@ -1907,13 +1907,12 @@ static inline bool boost_watermark(struc
  * can claim the whole pageblock for the requested migratetype. If not, we check
  * the pageblock for constituent pages; if at least half of the pages are free
  * or compatible, we can still claim the whole block, so pages freed in the
- * future will be put on the correct free list. Otherwise, we isolate exactly
- * the order we need from the fallback block and leave its migratetype alone.
+ * future will be put on the correct free list.
  */
 static struct page *
-steal_suitable_fallback(struct zone *zone, struct page *page,
-			int current_order, int order, int start_type,
-			unsigned int alloc_flags, bool whole_block)
+try_to_steal_block(struct zone *zone, struct page *page,
+		   int current_order, int order, int start_type,
+		   unsigned int alloc_flags)
 {
 	int free_pages, movable_pages, alike_pages;
 	unsigned long start_pfn;
@@ -1926,7 +1925,7 @@ steal_suitable_fallback(struct zone *zon
 	 * highatomic accounting.
 	 */
 	if (is_migrate_highatomic(block_type))
-		goto single_page;
+		return NULL;
 
 	/* Take ownership for orders >= pageblock_order */
 	if (current_order >= pageblock_order) {
@@ -1947,14 +1946,10 @@ steal_suitable_fallback(struct zone *zon
 	if (boost_watermark(zone) && (alloc_flags & ALLOC_KSWAPD))
 		set_bit(ZONE_BOOSTED_WATERMARK, &zone->flags);
 
-	/* We are not allowed to try stealing from the whole block */
-	if (!whole_block)
-		goto single_page;
-
 	/* moving whole block can fail due to zone boundary conditions */
 	if (!prep_move_freepages_block(zone, page, &start_pfn, &free_pages,
 				       &movable_pages))
-		goto single_page;
+		return NULL;
 
 	/*
 	 * Determine how many pages are compatible with our allocation.
@@ -1987,9 +1982,7 @@ steal_suitable_fallback(struct zone *zon
 		return __rmqueue_smallest(zone, order, start_type);
 	}
 
-single_page:
-	page_del_and_expand(zone, page, order, current_order, block_type);
-	return page;
+	return NULL;
 }
 
 /*
@@ -2171,14 +2164,19 @@ static bool unreserve_highatomic_pageblo
 }
 
 /*
- * Try finding a free buddy page on the fallback list and put it on the free
- * list of requested migratetype, possibly along with other pages from the same
- * block, depending on fragmentation avoidance heuristics. Returns true if
- * fallback was found so that __rmqueue_smallest() can grab it.
+ * Try finding a free buddy page on the fallback list.
+ *
+ * This will attempt to steal a whole pageblock for the requested type
+ * to ensure grouping of such requests in the future.
+ *
+ * If a whole block cannot be stolen, regress to __rmqueue_smallest()
+ * logic to at least break up as little contiguity as possible.
  *
  * The use of signed ints for order and current_order is a deliberate
  * deviation from the rest of this file, to make the for loop
  * condition simpler.
+ *
+ * Return the stolen page, or NULL if none can be found.
  */
 static __always_inline struct page *
 __rmqueue_fallback(struct zone *zone, int order, int start_migratetype,
@@ -2212,45 +2210,35 @@ __rmqueue_fallback(struct zone *zone, in
 		if (fallback_mt == -1)
 			continue;
 
-		/*
-		 * We cannot steal all free pages from the pageblock and the
-		 * requested migratetype is movable. In that case it's better to
-		 * steal and split the smallest available page instead of the
-		 * largest available page, because even if the next movable
-		 * allocation falls back into a different pageblock than this
-		 * one, it won't cause permanent fragmentation.
-		 */
-		if (!can_steal && start_migratetype == MIGRATE_MOVABLE
-					&& current_order > order)
-			goto find_smallest;
+		if (!can_steal)
+			break;
 
-		goto do_steal;
+		page = get_page_from_free_area(area, fallback_mt);
+		page = try_to_steal_block(zone, page, current_order, order,
+					  start_migratetype, alloc_flags);
+		if (page)
+			goto got_one;
 	}
 
-	return NULL;
+	if (alloc_flags & ALLOC_NOFRAGMENT)
+		return NULL;
 
-find_smallest:
+	/* No luck stealing blocks. Find the smallest fallback page */
 	for (current_order = order; current_order < NR_PAGE_ORDERS; current_order++) {
 		area = &(zone->free_area[current_order]);
 		fallback_mt = find_suitable_fallback(area, current_order,
 				start_migratetype, false, &can_steal);
-		if (fallback_mt != -1)
-			break;
-	}
-
-	/*
-	 * This should not happen - we already found a suitable fallback
-	 * when looking for the largest page.
-	 */
-	VM_BUG_ON(current_order > MAX_PAGE_ORDER);
+		if (fallback_mt == -1)
+			continue;
 
-do_steal:
-	page = get_page_from_free_area(area, fallback_mt);
+		page = get_page_from_free_area(area, fallback_mt);
+		page_del_and_expand(zone, page, order, current_order, fallback_mt);
+		goto got_one;
+	}
 
-	/* take off list, maybe claim block, expand remainder */
-	page = steal_suitable_fallback(zone, page, current_order, order,
-				       start_migratetype, alloc_flags, can_steal);
+	return NULL;
 
+got_one:
 	trace_mm_page_alloc_extfrag(page, order, current_order,
 		start_migratetype, fallback_mt);
 
author maintainer
#160 lore raw

PATCH 160/184 mm: page_alloc: speed up fallbacks in rmqueue_bulk()

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johannes Weiner <[email protected]>

commit 90abee6d7895d5eef18c91d870d8168be4e76e9d upstream.

The test robot identified c2f6ea38fc1b ("mm: page_alloc: don't steal single pages from biggest buddy") as the root cause of a 56.4% regression in vm-scalability::lru-file-mmap-read.

Carlos reports an earlier patch, c0cd6f557b90 ("mm: page_alloc: fix freelist movement during block conversion"), as the root cause for a regression in worst-case zone->lock+irqoff hold times.

Both of these patches modify the page allocator's fallback path to be less greedy in an effort to stave off fragmentation. The flip side of this is that fallbacks are also less productive each time around, which means the fallback search can run much more frequently.

Carlos' traces point to rmqueue_bulk() specifically, which tries to refill the percpu cache by allocating a large batch of pages in a loop. It highlights how once the native freelists are exhausted, the fallback code first scans orders top-down for whole blocks to claim, then falls back to a bottom-up search for the smallest buddy to steal. For the next batch page, it goes through the same thing again.

This can be made more efficient. Since rmqueue_bulk() holds the zone->lock over the entire batch, the freelists are not subject to outside changes; when the search for a block to claim has already failed, there is no point in trying again for the next page.

Modify __rmqueue() to remember the last successful fallback mode, and restart directly from there on the next rmqueue_bulk() iteration.

Oliver confirms that this improves beyond the regression that the test robot reported against c2f6ea38fc1b:

commit:
f3b92176f4 ("tools/selftests: add guard region test for /proc/$pid/pagemap") c2f6ea38fc ("mm: page_alloc: don't steal single pages from biggest buddy") acc4d5ff0b ("Merge tag 'net-6.15-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net")
2c847f27c3 ("mm: page_alloc: speed up fallbacks in rmqueue_bulk()") <--- your patch

f3b92176f4f7100f c2f6ea38fc1b640aa7a2e155cc1 acc4d5ff0b61eb1715c498b6536 2c847f27c37da65a93d23c237c5 ---------------- --------------------------- --------------------------- ---------------------------
%stddev %change %stddev %change %stddev %change %stddev
\ | \ | \ | \
25525364 ± 3% -56.4% 11135467 -57.8% 10779336 +31.6% 33581409 vm-scalability.throughput

Carlos confirms that worst-case times are almost fully recovered compared to before the earlier culprit patch:

2dd482ba627d (before freelist hygiene): 1ms
c0cd6f557b90 (after freelist hygiene): 90ms
next-20250319 (steal smallest buddy): 280ms
this patch : 8ms

---
 mm/page_alloc.c |  113 +++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 80 insertions(+), 33 deletions(-)
mm/page_alloc.c +80 -33
@@ -2164,22 +2164,15 @@ static bool unreserve_highatomic_pageblo
 }
 
 /*
- * Try finding a free buddy page on the fallback list.
- *
- * This will attempt to steal a whole pageblock for the requested type
- * to ensure grouping of such requests in the future.
- *
- * If a whole block cannot be stolen, regress to __rmqueue_smallest()
- * logic to at least break up as little contiguity as possible.
+ * Try to allocate from some fallback migratetype by claiming the entire block,
+ * i.e. converting it to the allocation's start migratetype.
  *
  * The use of signed ints for order and current_order is a deliberate
  * deviation from the rest of this file, to make the for loop
  * condition simpler.
- *
- * Return the stolen page, or NULL if none can be found.
  */
 static __always_inline struct page *
-__rmqueue_fallback(struct zone *zone, int order, int start_migratetype,
+__rmqueue_claim(struct zone *zone, int order, int start_migratetype,
 						unsigned int alloc_flags)
 {
 	struct free_area *area;
@@ -2216,14 +2209,29 @@ __rmqueue_fallback(struct zone *zone, in
 		page = get_page_from_free_area(area, fallback_mt);
 		page = try_to_steal_block(zone, page, current_order, order,
 					  start_migratetype, alloc_flags);
-		if (page)
-			goto got_one;
+		if (page) {
+			trace_mm_page_alloc_extfrag(page, order, current_order,
+						    start_migratetype, fallback_mt);
+			return page;
+		}
 	}
 
-	if (alloc_flags & ALLOC_NOFRAGMENT)
-		return NULL;
+	return NULL;
+}
+
+/*
+ * Try to steal a single page from some fallback migratetype. Leave the rest of
+ * the block as its current migratetype, potentially causing fragmentation.
+ */
+static __always_inline struct page *
+__rmqueue_steal(struct zone *zone, int order, int start_migratetype)
+{
+	struct free_area *area;
+	int current_order;
+	struct page *page;
+	int fallback_mt;
+	bool can_steal;
 
-	/* No luck stealing blocks. Find the smallest fallback page */
 	for (current_order = order; current_order < NR_PAGE_ORDERS; current_order++) {
 		area = &(zone->free_area[current_order]);
 		fallback_mt = find_suitable_fallback(area, current_order,
@@ -2233,25 +2241,28 @@ __rmqueue_fallback(struct zone *zone, in
 
 		page = get_page_from_free_area(area, fallback_mt);
 		page_del_and_expand(zone, page, order, current_order, fallback_mt);
-		goto got_one;
+		trace_mm_page_alloc_extfrag(page, order, current_order,
+					    start_migratetype, fallback_mt);
+		return page;
 	}
 
 	return NULL;
-
-got_one:
-	trace_mm_page_alloc_extfrag(page, order, current_order,
-		start_migratetype, fallback_mt);
-
-	return page;
 }
 
+enum rmqueue_mode {
+	RMQUEUE_NORMAL,
+	RMQUEUE_CMA,
+	RMQUEUE_CLAIM,
+	RMQUEUE_STEAL,
+};
+
 /*
  * Do the hard work of removing an element from the buddy allocator.
  * Call me with the zone->lock already held.
  */
 static __always_inline struct page *
 __rmqueue(struct zone *zone, unsigned int order, int migratetype,
-						unsigned int alloc_flags)
+	  unsigned int alloc_flags, enum rmqueue_mode *mode)
 {
 	struct page *page;
 
@@ -2270,16 +2281,49 @@ __rmqueue(struct zone *zone, unsigned in
 		}
 	}
 
-	page = __rmqueue_smallest(zone, order, migratetype);
-	if (unlikely(!page)) {
-		if (alloc_flags & ALLOC_CMA)
+	/*
+	 * First try the freelists of the requested migratetype, then try
+	 * fallbacks modes with increasing levels of fragmentation risk.
+	 *
+	 * The fallback logic is expensive and rmqueue_bulk() calls in
+	 * a loop with the zone->lock held, meaning the freelists are
+	 * not subject to any outside changes. Remember in *mode where
+	 * we found pay dirt, to save us the search on the next call.
+	 */
+	switch (*mode) {
+	case RMQUEUE_NORMAL:
+		page = __rmqueue_smallest(zone, order, migratetype);
+		if (page)
+			return page;
+		fallthrough;
+	case RMQUEUE_CMA:
+		if (alloc_flags & ALLOC_CMA) {
 			page = __rmqueue_cma_fallback(zone, order);
-
-		if (!page)
-			page = __rmqueue_fallback(zone, order, migratetype,
-						  alloc_flags);
+			if (page) {
+				*mode = RMQUEUE_CMA;
+				return page;
+			}
+		}
+		fallthrough;
+	case RMQUEUE_CLAIM:
+		page = __rmqueue_claim(zone, order, migratetype, alloc_flags);
+		if (page) {
+			/* Replenished preferred freelist, back to normal mode. */
+			*mode = RMQUEUE_NORMAL;
+			return page;
+		}
+		fallthrough;
+	case RMQUEUE_STEAL:
+		if (!(alloc_flags & ALLOC_NOFRAGMENT)) {
+			page = __rmqueue_steal(zone, order, migratetype);
+			if (page) {
+				*mode = RMQUEUE_STEAL;
+				return page;
+			}
+		}
 	}
-	return page;
+
+	return NULL;
 }
 
 /*
@@ -2291,13 +2335,14 @@ static int rmqueue_bulk(struct zone *zon
 			unsigned long count, struct list_head *list,
 			int migratetype, unsigned int alloc_flags)
 {
+	enum rmqueue_mode rmqm = RMQUEUE_NORMAL;
 	unsigned long flags;
 	int i;
 
 	spin_lock_irqsave(&zone->lock, flags);
 	for (i = 0; i < count; ++i) {
 		struct page *page = __rmqueue(zone, order, migratetype,
-								alloc_flags);
+					      alloc_flags, &rmqm);
 		if (unlikely(page == NULL))
 			break;
 
@@ -2898,7 +2943,9 @@ struct page *rmqueue_buddy(struct zone *
 		if (alloc_flags & ALLOC_HIGHATOMIC)
 			page = __rmqueue_smallest(zone, order, MIGRATE_HIGHATOMIC);
 		if (!page) {
-			page = __rmqueue(zone, order, migratetype, alloc_flags);
+			enum rmqueue_mode rmqm = RMQUEUE_NORMAL;
+
+			page = __rmqueue(zone, order, migratetype, alloc_flags, &rmqm);
 
 			/*
 			 * If the allocation fails, allow OOM handling and
author maintainer
#161 lore raw

PATCH 161/184 sched/eevdf: Fix se->slice being set to U64_MAX and resulting crash

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Omar Sandoval <[email protected]>

commit bbce3de72be56e4b5f68924b7da9630cc89aa1a8 upstream.

There is a code path in dequeue_entities() that can set the slice of a sched_entity to U64_MAX, which sometimes results in a crash.

The offending case is when dequeue_entities() is called to dequeue a delayed group entity, and then the entity's parent's dequeue is delayed. In that case:

1. In the if (entity_is_task(se)) else block at the beginning of dequeue_entities(), slice is set to cfs_rq_min_slice(group_cfs_rq(se)). If the entity was delayed, then it has no queued tasks, so cfs_rq_min_slice() returns U64_MAX.
2. The first for_each_sched_entity() loop dequeues the entity.
3. If the entity was its parent's only child, then the next iteration tries to dequeue the parent.
4. If the parent's dequeue needs to be delayed, then it breaks from the first for_each_sched_entity() loop _without updating slice_.
5. The second for_each_sched_entity() loop sets the parent's ->slice to the saved slice, which is still U64_MAX.

This throws off subsequent calculations with potentially catastrophic results. A manifestation we saw in production was:

6. In update_entity_lag(), se->slice is used to calculate limit, which ends up as a huge negative number.
7. limit is used in se->vlag = clamp(vlag, -limit, limit). Because limit is negative, vlag > limit, so se->vlag is set to the same huge negative number.
8. In place_entity(), se->vlag is scaled, which overflows and results in another huge (positive or negative) number.
9. The adjusted lag is subtracted from se->vruntime, which increases or decreases se->vruntime by a huge number.
10. pick_eevdf() calls entity_eligible()/vruntime_eligible(), which incorrectly returns false because the vruntime is so far from the other vruntimes on the queue, causing the
(vruntime - cfs_rq->min_vruntime) * load calulation to overflow.
11. Nothing appears to be eligible, so pick_eevdf() returns NULL.
12. pick_next_entity() tries to dereference the return value of pick_eevdf() and crashes.

Dumping the cfs_rq states from the core dumps with drgn showed tell-tale huge vruntime ranges and bogus vlag values, and I also traced se->slice being set to U64_MAX on live systems (which was usually "benign" since the rest of the runqueue needed to be in a particular state to crash).

Fix it in dequeue_entities() by always setting slice from the first non-empty cfs_rq.

---
 kernel/sched/fair.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)
kernel/sched/fair.c +1 -3
@@ -7182,9 +7182,6 @@ static int dequeue_entities(struct rq *r
 		idle_h_nr_running = task_has_idle_policy(p);
 		if (!task_sleep && !task_delayed)
 			h_nr_delayed = !!se->sched_delayed;
-	} else {
-		cfs_rq = group_cfs_rq(se);
-		slice = cfs_rq_min_slice(cfs_rq);
 	}
 
 	for_each_sched_entity(se) {
@@ -7194,6 +7191,7 @@ static int dequeue_entities(struct rq *r
 			if (p && &p->se == se)
 				return -1;
 
+			slice = cfs_rq_min_slice(cfs_rq);
 			break;
 		}
 
author maintainer
#162 lore raw

PATCH 162/184 arm64: insn: Add support for encoding DSB

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: James Morse <[email protected]>

commit 63de8abd97ddb9b758bd8f915ecbd18e1f1a87a0 upstream.

To generate code in the eBPF epilogue that uses the DSB instruction, insn.c needs a heler to encode the type and domain.

Re-use the crm encoding logic from the DMB instruction.

---
 arch/arm64/include/asm/insn.h |    1 
 arch/arm64/lib/insn.c         |   60 +++++++++++++++++++++++++-----------------
 2 files changed, 38 insertions(+), 23 deletions(-)
arch/arm64/include/asm/insn.h +1 -0
@@ -693,6 +693,7 @@ u32 aarch64_insn_gen_cas(enum aarch64_in
 }
 #endif
 u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type);
+u32 aarch64_insn_gen_dsb(enum aarch64_insn_mb_type type);
 u32 aarch64_insn_gen_mrs(enum aarch64_insn_register result,
 			 enum aarch64_insn_system_register sysreg);
 
arch/arm64/lib/insn.c +37 -23

91 lines not on this page · raw message

author maintainer
#163 lore raw

PATCH 163/184 arm64: proton-pack: Expose whether the platform is mitigated by firmware

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: James Morse <[email protected]>

commit e7956c92f396a44eeeb6eaf7a5b5e1ad24db6748 upstream.

is_spectre_bhb_fw_affected() allows the caller to determine if the CPU is known to need a firmware mitigation. CPUs are either on the list of CPUs we know about, or firmware has been queried and reported that the platform is affected - and mitigated by firmware.

This helper is not useful to determine if the platform is mitigated by firmware. A CPU could be on the know list, but the firmware may not be implemented. Its affected but not mitigated.

spectre_bhb_enable_mitigation() handles this distinction by checking the firmware state before enabling the mitigation.

Add a helper to expose this state. This will be used by the BPF JIT to determine if calling firmware for a mitigation is necessary and supported.

---
 arch/arm64/include/asm/spectre.h |    1 +
 arch/arm64/kernel/proton-pack.c  |    5 +++++
 2 files changed, 6 insertions(+)
arch/arm64/include/asm/spectre.h +1 -0
@@ -97,6 +97,7 @@ enum mitigation_state arm64_get_meltdown
 
 enum mitigation_state arm64_get_spectre_bhb_state(void);
 bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, int scope);
+bool is_spectre_bhb_fw_mitigated(void);
 void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
 bool try_emulate_el1_ssbs(struct pt_regs *regs, u32 instr);
 
arch/arm64/kernel/proton-pack.c +5 -0
@@ -1093,6 +1093,11 @@ void spectre_bhb_enable_mitigation(const
 	update_mitigation_state(&spectre_bhb_state, state);
 }
 
+bool is_spectre_bhb_fw_mitigated(void)
+{
+	return test_bit(BHB_FW, &system_bhb_mitigations);
+}
+
 /* Patched to NOP when enabled */
 void noinstr spectre_bhb_patch_loop_mitigation_enable(struct alt_instr *alt,
 						     __le32 *origptr,
author maintainer
#164 lore raw

PATCH 164/184 arm64: proton-pack: Expose whether the branchy loop k value

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: James Morse <[email protected]>

commit a1152be30a043d2d4dcb1683415f328bf3c51978 upstream.

Add a helper to expose the k value of the branchy loop. This is needed by the BPF JIT to generate the mitigation sequence in BPF programs.

---
 arch/arm64/include/asm/spectre.h |    1 +
 arch/arm64/kernel/proton-pack.c  |    5 +++++
 2 files changed, 6 insertions(+)
arch/arm64/include/asm/spectre.h +1 -0
@@ -97,6 +97,7 @@ enum mitigation_state arm64_get_meltdown
 
 enum mitigation_state arm64_get_spectre_bhb_state(void);
 bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, int scope);
+u8 get_spectre_bhb_loop_value(void);
 bool is_spectre_bhb_fw_mitigated(void);
 void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
 bool try_emulate_el1_ssbs(struct pt_regs *regs, u32 instr);
arch/arm64/kernel/proton-pack.c +5 -0
@@ -998,6 +998,11 @@ bool is_spectre_bhb_affected(const struc
 	return true;
 }
 
+u8 get_spectre_bhb_loop_value(void)
+{
+	return max_bhb_k;
+}
+
 static void this_cpu_set_vectors(enum arm64_bp_harden_el1_vectors slot)
 {
 	const char *v = arm64_get_bp_hardening_vector(slot);
author maintainer
#165 lore raw

PATCH 165/184 arm64: bpf: Add BHB mitigation to the epilogue for cBPF programs

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: James Morse <[email protected]>

commit 0dfefc2ea2f29ced2416017d7e5b1253a54c2735 upstream.

A malicious BPF program may manipulate the branch history to influence what the hardware speculates will happen next.

On exit from a BPF program, emit the BHB mititgation sequence.

This is only applied for 'classic' cBPF programs that are loaded by seccomp.

---
 arch/arm64/include/asm/spectre.h |    1 
 arch/arm64/kernel/proton-pack.c  |    2 -
 arch/arm64/net/bpf_jit_comp.c    |   54 ++++++++++++++++++++++++++++++++++++---
 3 files changed, 52 insertions(+), 5 deletions(-)
arch/arm64/include/asm/spectre.h +1 -0
@@ -97,6 +97,7 @@ enum mitigation_state arm64_get_meltdown
 
 enum mitigation_state arm64_get_spectre_bhb_state(void);
 bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, int scope);
+extern bool __nospectre_bhb;
 u8 get_spectre_bhb_loop_value(void);
 bool is_spectre_bhb_fw_mitigated(void);
 void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
arch/arm64/kernel/proton-pack.c +1 -1
@@ -1020,7 +1020,7 @@ static void this_cpu_set_vectors(enum ar
 	isb();
 }
 
-static bool __read_mostly __nospectre_bhb;
+bool __read_mostly __nospectre_bhb;
 static int __init parse_spectre_bhb_param(char *str)
 {
 	__nospectre_bhb = true;
arch/arm64/net/bpf_jit_comp.c +50 -4

93 lines not on this page · raw message

author maintainer
#166 lore raw

PATCH 166/184 arm64: bpf: Only mitigate cBPF programs loaded by unprivileged users

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: James Morse <[email protected]>

commit f300769ead032513a68e4a02e806393402e626f8 upstream.

Support for eBPF programs loaded by unprivileged users is typically disabled. This means only cBPF programs need to be mitigated for BHB.

In addition, only mitigate cBPF programs that were loaded by an unprivileged user. Privileged users can also load the same program via eBPF, making the mitigation pointless.

---
 arch/arm64/net/bpf_jit_comp.c |    3 +++
 1 file changed, 3 insertions(+)
arch/arm64/net/bpf_jit_comp.c +3 -0
@@ -870,6 +870,9 @@ static void __maybe_unused build_bhb_mit
 	    arm64_get_spectre_v2_state() == SPECTRE_VULNERABLE)
 		return;
 
+	if (capable(CAP_SYS_ADMIN))
+		return;
+
 	if (supports_clearbhb(SCOPE_SYSTEM)) {
 		emit(aarch64_insn_gen_hint(AARCH64_INSN_HINT_CLEARBHB), ctx);
 		return;
author maintainer
#167 lore raw

PATCH 167/184 arm64: proton-pack: Add new CPUs k values for branch mitigation

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: James Morse <[email protected]>

commit efe676a1a7554219eae0b0dcfe1e0cdcc9ef9aef upstream.

Update the list of 'k' values for the branch mitigation from arm's website.

Add the values for Cortex-X1C. The MIDR_EL1 value can be found here:
https://developer.arm.com/documentation/101968/0002/Register-descriptions/AArch>

---
 arch/arm64/include/asm/cputype.h |    2 ++
 arch/arm64/kernel/proton-pack.c  |    1 +
 2 files changed, 3 insertions(+)
arch/arm64/include/asm/cputype.h +2 -0
@@ -81,6 +81,7 @@
 #define ARM_CPU_PART_CORTEX_A78AE	0xD42
 #define ARM_CPU_PART_CORTEX_X1		0xD44
 #define ARM_CPU_PART_CORTEX_A510	0xD46
+#define ARM_CPU_PART_CORTEX_X1C		0xD4C
 #define ARM_CPU_PART_CORTEX_A520	0xD80
 #define ARM_CPU_PART_CORTEX_A710	0xD47
 #define ARM_CPU_PART_CORTEX_A715	0xD4D
@@ -166,6 +167,7 @@
 #define MIDR_CORTEX_A78AE	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78AE)
 #define MIDR_CORTEX_X1	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1)
 #define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510)
+#define MIDR_CORTEX_X1C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1C)
 #define MIDR_CORTEX_A520 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A520)
 #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
 #define MIDR_CORTEX_A715 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A715)
arch/arm64/kernel/proton-pack.c +1 -0
@@ -891,6 +891,7 @@ static u8 spectre_bhb_loop_affected(void
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_A78AE),
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_X1C),
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
 		MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
author maintainer
#168 lore raw

PATCH 168/184 x86/bpf: Call branch history clearing sequence on exit

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Daniel Sneddon <[email protected]>

commit d4e89d212d401672e9cdfe825d947ee3a9fbe3f5 upstream.

Classic BPF programs have been identified as potential vectors for intra-mode Branch Target Injection (BTI) attacks. Classic BPF programs can be run by unprivileged users. They allow unprivileged code to execute inside the kernel. Attackers can use unprivileged cBPF to craft branch history in kernel mode that can influence the target of indirect branches.

Introduce a branch history buffer (BHB) clearing sequence during the JIT compilation of classic BPF programs. The clearing sequence is the same as is used in previous mitigations to protect syscalls. Since eBPF programs already have their own mitigations in place, only insert the call on classic programs that aren't run by privileged users.

---
 arch/x86/net/bpf_jit_comp.c |   31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
arch/x86/net/bpf_jit_comp.c +31 -0
@@ -1412,6 +1412,30 @@ static void emit_shiftx(u8 **pprog, u32
 #define LOAD_TAIL_CALL_CNT_PTR(stack)				\
 	__LOAD_TCC_PTR(BPF_TAIL_CALL_CNT_PTR_STACK_OFF(stack))
 
+static int emit_spectre_bhb_barrier(u8 **pprog, u8 *ip,
+				    struct bpf_prog *bpf_prog)
+{
+	u8 *prog = *pprog;
+	u8 *func;
+
+	if (cpu_feature_enabled(X86_FEATURE_CLEAR_BHB_LOOP)) {
+		/* The clearing sequence clobbers eax and ecx. */
+		EMIT1(0x50); /* push rax */
+		EMIT1(0x51); /* push rcx */
+		ip += 2;
+
+		func = (u8 *)clear_bhb_loop;
+		ip += x86_call_depth_emit_accounting(&prog, func, ip);
+
+		if (emit_call(&prog, func, ip))
+			return -EINVAL;
+		EMIT1(0x59); /* pop rcx */
+		EMIT1(0x58); /* pop rax */
+	}
+	*pprog = prog;
+	return 0;
+}
+
 static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image,
 		  int oldproglen, struct jit_context *ctx, bool jmp_padding)
 {
@@ -2402,6 +2426,13 @@ emit_jmp:
 			seen_exit = true;
 			/* Update cleanup_addr */
 			ctx->cleanup_addr = proglen;
+			if (bpf_prog_was_classic(bpf_prog) &&
+			    !capable(CAP_SYS_ADMIN)) {
+				u8 *ip = image + addrs[i - 1];
+
+				if (emit_spectre_bhb_barrier(&prog, ip, bpf_prog))
+					return -EINVAL;
+			}
 			if (bpf_prog->aux->exception_boundary) {
 				pop_callee_regs(&prog, all_callee_regs_used);
 				pop_r12(&prog);
author maintainer
#169 lore raw

PATCH 169/184 x86/bpf: Add IBHF call at end of classic BPF

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Daniel Sneddon <[email protected]>

commit 9f725eec8fc0b39bdc07dcc8897283c367c1a163 upstream.

Classic BPF programs can be run by unprivileged users, allowing unprivileged code to execute inside the kernel. Attackers can use this to craft branch history in kernel mode that can influence the target of indirect branches.

BHI_DIS_S provides user-kernel isolation of branch history, but cBPF can be used to bypass this protection by crafting branch history in kernel mode. To stop intra-mode attacks via cBPF programs, Intel created a new instruction Indirect Branch History Fence (IBHF). IBHF prevents the predicted targets of subsequent indirect branches from being influenced by branch history prior to the IBHF. IBHF is only effective while BHI_DIS_S is enabled.

Add the IBHF instruction to cBPF jitted code's exit path. Add the new fence when the hardware mitigation is enabled (i.e., X86_FEATURE_CLEAR_BHB_HW is set) or after the software sequence (X86_FEATURE_CLEAR_BHB_LOOP) is being used in a virtual machine. Note that X86_FEATURE_CLEAR_BHB_HW and X86_FEATURE_CLEAR_BHB_LOOP are mutually exclusive, so the JIT compiler will only emit the new fence, not the SW sequence, when X86_FEATURE_CLEAR_BHB_HW is set.

Hardware that enumerates BHI_NO basically has BHI_DIS_S protections always enabled, regardless of the value of BHI_DIS_S. Since BHI_DIS_S doesn't protect against intra-mode attacks, enumerate BHI bug on BHI_NO hardware as well.

---
 arch/x86/kernel/cpu/common.c |    9 ++++++---
 arch/x86/net/bpf_jit_comp.c  |   19 +++++++++++++++++++
 2 files changed, 25 insertions(+), 3 deletions(-)
arch/x86/kernel/cpu/common.c +6 -3
@@ -1437,9 +1437,12 @@ static void __init cpu_set_bug_bits(stru
 	if (vulnerable_to_rfds(x86_arch_cap_msr))
 		setup_force_cpu_bug(X86_BUG_RFDS);
 
-	/* When virtualized, eIBRS could be hidden, assume vulnerable */
-	if (!(x86_arch_cap_msr & ARCH_CAP_BHI_NO) &&
-	    !cpu_matches(cpu_vuln_whitelist, NO_BHI) &&
+	/*
+	 * Intel parts with eIBRS are vulnerable to BHI attacks. Parts with
+	 * BHI_NO still need to use the BHI mitigation to prevent Intra-mode
+	 * attacks.  When virtualized, eIBRS could be hidden, assume vulnerable.
+	 */
+	if (!cpu_matches(cpu_vuln_whitelist, NO_BHI) &&
 	    (boot_cpu_has(X86_FEATURE_IBRS_ENHANCED) ||
 	     boot_cpu_has(X86_FEATURE_HYPERVISOR)))
 		setup_force_cpu_bug(X86_BUG_BHI);
arch/x86/net/bpf_jit_comp.c +19 -0
@@ -41,6 +41,8 @@ static u8 *emit_code(u8 *ptr, u32 bytes,
 #define EMIT2(b1, b2)		EMIT((b1) + ((b2) << 8), 2)
 #define EMIT3(b1, b2, b3)	EMIT((b1) + ((b2) << 8) + ((b3) << 16), 3)
 #define EMIT4(b1, b2, b3, b4)   EMIT((b1) + ((b2) << 8) + ((b3) << 16) + ((b4) << 24), 4)
+#define EMIT5(b1, b2, b3, b4, b5) \
+	do { EMIT1(b1); EMIT4(b2, b3, b4, b5); } while (0)
 
 #define EMIT1_off32(b1, off) \
 	do { EMIT1(b1); EMIT(off, 4); } while (0)
@@ -1432,6 +1434,23 @@ static int emit_spectre_bhb_barrier(u8 *
 		EMIT1(0x59); /* pop rcx */
 		EMIT1(0x58); /* pop rax */
 	}
+	/* Insert IBHF instruction */
+	if ((cpu_feature_enabled(X86_FEATURE_CLEAR_BHB_LOOP) &&
+	     cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) ||
+	    (cpu_feature_enabled(X86_FEATURE_CLEAR_BHB_HW) &&
+	     IS_ENABLED(CONFIG_X86_64))) {
+		/*
+		 * Add an Indirect Branch History Fence (IBHF). IBHF acts as a
+		 * fence preventing branch history from before the fence from
+		 * affecting indirect branches after the fence. This is
+		 * specifically used in cBPF jitted code to prevent Intra-mode
+		 * BHI attacks. The IBHF instruction is designed to be a NOP on
+		 * hardware that doesn't need or support it.  The REP and REX.W
+		 * prefixes are required by the microcode, and they also ensure
+		 * that the NOP is unlikely to be used in existing code.
+		 */
+		EMIT5(0xF3, 0x48, 0x0F, 0x1E, 0xF8); /* ibhf */
+	}
 	*pprog = prog;
 	return 0;
 }
author maintainer
#170 lore raw

PATCH 170/184 x86/bhi: Do not set BHI_DIS_S in 32-bit mode

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pawan Gupta <[email protected]>

commit 073fdbe02c69c43fb7c0d547ec265c7747d4a646 upstream.

With the possibility of intra-mode BHI via cBPF, complete mitigation for BHI is to use IBHF (history fence) instruction with BHI_DIS_S set. Since this new instruction is only available in 64-bit mode, setting BHI_DIS_S in 32-bit mode is only a partial mitigation.

Do not set BHI_DIS_S in 32-bit mode so as to avoid reporting misleading mitigated status. With this change IBHF won't be used in 32-bit mode, also remove the CONFIG_X86_64 check from emit_spectre_bhb_barrier().

---
 arch/x86/kernel/cpu/bugs.c  |    6 +++---
 arch/x86/net/bpf_jit_comp.c |    5 +++--
 2 files changed, 6 insertions(+), 5 deletions(-)
arch/x86/kernel/cpu/bugs.c +3 -3
@@ -1684,11 +1684,11 @@ static void __init bhi_select_mitigation
 			return;
 	}
 
-	/* Mitigate in hardware if supported */
-	if (spec_ctrl_bhi_dis())
+	if (!IS_ENABLED(CONFIG_X86_64))
 		return;
 
-	if (!IS_ENABLED(CONFIG_X86_64))
+	/* Mitigate in hardware if supported */
+	if (spec_ctrl_bhi_dis())
 		return;
 
 	if (bhi_mitigation == BHI_MITIGATION_VMEXIT_ONLY) {
arch/x86/net/bpf_jit_comp.c +3 -2
@@ -1437,8 +1437,7 @@ static int emit_spectre_bhb_barrier(u8 *
 	/* Insert IBHF instruction */
 	if ((cpu_feature_enabled(X86_FEATURE_CLEAR_BHB_LOOP) &&
 	     cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) ||
-	    (cpu_feature_enabled(X86_FEATURE_CLEAR_BHB_HW) &&
-	     IS_ENABLED(CONFIG_X86_64))) {
+	    cpu_feature_enabled(X86_FEATURE_CLEAR_BHB_HW)) {
 		/*
 		 * Add an Indirect Branch History Fence (IBHF). IBHF acts as a
 		 * fence preventing branch history from before the fence from
@@ -1448,6 +1447,8 @@ static int emit_spectre_bhb_barrier(u8 *
 		 * hardware that doesn't need or support it.  The REP and REX.W
 		 * prefixes are required by the microcode, and they also ensure
 		 * that the NOP is unlikely to be used in existing code.
+		 *
+		 * IBHF is not a valid instruction in 32-bit mode.
 		 */
 		EMIT5(0xF3, 0x48, 0x0F, 0x1E, 0xF8); /* ibhf */
 	}
author maintainer
#171 lore raw

PATCH 171/184 x86/speculation: Simplify and make CALL_NOSPEC consistent

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pawan Gupta <[email protected]>

commit cfceff8526a426948b53445c02bcb98453c7330d upstream.

CALL_NOSPEC macro is used to generate Spectre-v2 mitigation friendly indirect branches. At compile time the macro defaults to indirect branch, and at runtime those can be patched to thunk based mitigations.

This approach is opposite of what is done for the rest of the kernel, where the compile time default is to replace indirect calls with retpoline thunk calls.

Make CALL_NOSPEC consistent with the rest of the kernel, default to retpoline thunk at compile time when CONFIG_MITIGATION_RETPOLINE is enabled.

---
 arch/x86/include/asm/nospec-branch.h |   15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)
arch/x86/include/asm/nospec-branch.h +5 -10
@@ -442,16 +442,11 @@ static inline void call_depth_return_thu
  * Inline asm uses the %V modifier which is only in newer GCC
  * which is ensured when CONFIG_MITIGATION_RETPOLINE is defined.
  */
-# define CALL_NOSPEC						\
-	ALTERNATIVE_2(						\
-	ANNOTATE_RETPOLINE_SAFE					\
-	"call *%[thunk_target]\n",				\
-	"call __x86_indirect_thunk_%V[thunk_target]\n",		\
-	X86_FEATURE_RETPOLINE,					\
-	"lfence;\n"						\
-	ANNOTATE_RETPOLINE_SAFE					\
-	"call *%[thunk_target]\n",				\
-	X86_FEATURE_RETPOLINE_LFENCE)
+#ifdef CONFIG_MITIGATION_RETPOLINE
+#define CALL_NOSPEC	"call __x86_indirect_thunk_%V[thunk_target]\n"
+#else
+#define CALL_NOSPEC	"call *%[thunk_target]\n"
+#endif
 
 # define THUNK_TARGET(addr) [thunk_target] "r" (addr)
 
author maintainer
#172 lore raw

PATCH 172/184 x86/speculation: Add a conditional CS prefix to CALL_NOSPEC

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pawan Gupta <[email protected]>

commit 052040e34c08428a5a388b85787e8531970c0c67 upstream.

Retpoline mitigation for spectre-v2 uses thunks for indirect branches. To support this mitigation compilers add a CS prefix with -mindirect-branch-cs-prefix. For an indirect branch in asm, this needs to be added manually.

CS prefix is already being added to indirect branches in asm files, but not in inline asm. Add CS prefix to CALL_NOSPEC for inline asm as well. There is no JMP_NOSPEC for inline asm.

---
 arch/x86/include/asm/nospec-branch.h |   19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)
arch/x86/include/asm/nospec-branch.h +15 -4
@@ -210,9 +210,8 @@
 .endm
 
 /*
- * Equivalent to -mindirect-branch-cs-prefix; emit the 5 byte jmp/call
- * to the retpoline thunk with a CS prefix when the register requires
- * a RAX prefix byte to encode. Also see apply_retpolines().
+ * Emits a conditional CS prefix that is compatible with
+ * -mindirect-branch-cs-prefix.
  */
 .macro __CS_PREFIX reg:req
 	.irp rs,r8,r9,r10,r11,r12,r13,r14,r15
@@ -439,11 +438,23 @@ static inline void call_depth_return_thu
 #ifdef CONFIG_X86_64
 
 /*
+ * Emits a conditional CS prefix that is compatible with
+ * -mindirect-branch-cs-prefix.
+ */
+#define __CS_PREFIX(reg)				\
+	".irp rs,r8,r9,r10,r11,r12,r13,r14,r15\n"	\
+	".ifc \\rs," reg "\n"				\
+	".byte 0x2e\n"					\
+	".endif\n"					\
+	".endr\n"
+
+/*
  * Inline asm uses the %V modifier which is only in newer GCC
  * which is ensured when CONFIG_MITIGATION_RETPOLINE is defined.
  */
 #ifdef CONFIG_MITIGATION_RETPOLINE
-#define CALL_NOSPEC	"call __x86_indirect_thunk_%V[thunk_target]\n"
+#define CALL_NOSPEC	__CS_PREFIX("%V[thunk_target]")	\
+			"call __x86_indirect_thunk_%V[thunk_target]\n"
 #else
 #define CALL_NOSPEC	"call *%[thunk_target]\n"
 #endif
author maintainer
#173 lore raw

PATCH 173/184 x86/speculation: Remove the extra #ifdef around CALL_NOSPEC

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pawan Gupta <[email protected]>

commit c8c81458863ab686cda4fe1e603fccaae0f12460 upstream.

Commit:

010c4a461c1d ("x86/speculation: Simplify and make CALL_NOSPEC consistent")

added an #ifdef CONFIG_MITIGATION_RETPOLINE around the CALL_NOSPEC definition. This is not required as this code is already under a larger #ifdef.

Remove the extra #ifdef, no functional change.

vmlinux size remains same before and after this change:

CONFIG_MITIGATION_RETPOLINE=y:

      text       data        bss         dec        hex    filename
  25434752    7342290    2301212    35078254    217406e    vmlinux.before
  25434752    7342290    2301212    35078254    217406e    vmlinux.after

# CONFIG_MITIGATION_RETPOLINE is not set:

      text       data        bss         dec        hex    filename
  22943094    6214994    1550152    30708240    1d49210    vmlinux.before
  22943094    6214994    1550152    30708240    1d49210    vmlinux.after
---
 arch/x86/include/asm/nospec-branch.h |    4 ----
 1 file changed, 4 deletions(-)
arch/x86/include/asm/nospec-branch.h +0 -4
@@ -452,12 +452,8 @@ static inline void call_depth_return_thu
  * Inline asm uses the %V modifier which is only in newer GCC
  * which is ensured when CONFIG_MITIGATION_RETPOLINE is defined.
  */
-#ifdef CONFIG_MITIGATION_RETPOLINE
 #define CALL_NOSPEC	__CS_PREFIX("%V[thunk_target]")	\
 			"call __x86_indirect_thunk_%V[thunk_target]\n"
-#else
-#define CALL_NOSPEC	"call *%[thunk_target]\n"
-#endif
 
 # define THUNK_TARGET(addr) [thunk_target] "r" (addr)
 
author maintainer
#174 lore raw

PATCH 174/184 Documentation: x86/bugs/its: Add ITS documentation

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pawan Gupta <[email protected]>

commit 1ac116ce6468670eeda39345a5585df308243dca upstream.

Add the admin-guide for Indirect Target Selection (ITS).

---
 Documentation/admin-guide/hw-vuln/index.rst                     |    1 
 Documentation/admin-guide/hw-vuln/indirect-target-selection.rst |  168 ++++++++++
 2 files changed, 169 insertions(+)
 create mode 100644 Documentation/admin-guide/hw-vuln/indirect-target-selection.rst
Documentation/admin-guide/hw-vuln/index.rst +1 -0
@@ -22,3 +22,4 @@ are configurable at compile, boot or run
    srso
    gather_data_sampling
    reg-file-data-sampling
+   indirect-target-selection
Documentation/admin-guide/hw-vuln/indirect-target-selection.rst new file +168 -0

168 lines not on this page · raw message

author maintainer
#175 lore raw

PATCH 175/184 x86/its: Enumerate Indirect Target Selection (ITS) bug

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pawan Gupta <[email protected]>

commit 159013a7ca18c271ff64192deb62a689b622d860 upstream.

ITS bug in some pre-Alderlake Intel CPUs may allow indirect branches in the first half of a cache line get predicted to a target of a branch located in the second half of the cache line.

Set X86_BUG_ITS on affected CPUs. Mitigation to follow in later commits.

---
 arch/x86/include/asm/cpufeatures.h |    1 
 arch/x86/include/asm/msr-index.h   |    8 +++++
 arch/x86/kernel/cpu/common.c       |   58 +++++++++++++++++++++++++++++--------
 arch/x86/kvm/x86.c                 |    4 +-
 4 files changed, 58 insertions(+), 13 deletions(-)
arch/x86/include/asm/cpufeatures.h +1 -0
@@ -526,4 +526,5 @@
 #define X86_BUG_RFDS			X86_BUG(1*32 + 2) /* "rfds" CPU is vulnerable to Register File Data Sampling */
 #define X86_BUG_BHI			X86_BUG(1*32 + 3) /* "bhi" CPU is affected by Branch History Injection */
 #define X86_BUG_IBPB_NO_RET	   	X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB omits return target predictions */
+#define X86_BUG_ITS			X86_BUG(1*32 + 5) /* "its" CPU is affected by Indirect Target Selection */
 #endif /* _ASM_X86_CPUFEATURES_H */
arch/x86/include/asm/msr-index.h +8 -0
@@ -209,6 +209,14 @@
 						 * VERW clears CPU Register
 						 * File.
 						 */
+#define ARCH_CAP_ITS_NO			BIT_ULL(62) /*
+						     * Not susceptible to
+						     * Indirect Target Selection.
+						     * This bit is not set by
+						     * HW, but is synthesized by
+						     * VMMs for guests to know
+						     * their affected status.
+						     */
 
 #define MSR_IA32_FLUSH_CMD		0x0000010b
 #define L1D_FLUSH			BIT(0)	/*
arch/x86/kernel/cpu/common.c +46 -12

86 lines not on this page · raw message

arch/x86/kvm/x86.c +3 -1
@@ -1623,7 +1623,7 @@ EXPORT_SYMBOL_GPL(kvm_emulate_rdpmc);
 	 ARCH_CAP_PSCHANGE_MC_NO | ARCH_CAP_TSX_CTRL_MSR | ARCH_CAP_TAA_NO | \
 	 ARCH_CAP_SBDR_SSDP_NO | ARCH_CAP_FBSDP_NO | ARCH_CAP_PSDP_NO | \
 	 ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | ARCH_CAP_GDS_NO | \
-	 ARCH_CAP_RFDS_NO | ARCH_CAP_RFDS_CLEAR | ARCH_CAP_BHI_NO)
+	 ARCH_CAP_RFDS_NO | ARCH_CAP_RFDS_CLEAR | ARCH_CAP_BHI_NO | ARCH_CAP_ITS_NO)
 
 static u64 kvm_get_arch_capabilities(void)
 {
@@ -1657,6 +1657,8 @@ static u64 kvm_get_arch_capabilities(voi
 		data |= ARCH_CAP_MDS_NO;
 	if (!boot_cpu_has_bug(X86_BUG_RFDS))
 		data |= ARCH_CAP_RFDS_NO;
+	if (!boot_cpu_has_bug(X86_BUG_ITS))
+		data |= ARCH_CAP_ITS_NO;
 
 	if (!boot_cpu_has(X86_FEATURE_RTM)) {
 		/*
author maintainer
#176 lore raw

PATCH 176/184 x86/its: Add support for ITS-safe indirect thunk

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pawan Gupta <[email protected]>

commit 8754e67ad4ac692c67ff1f99c0d07156f04ae40c upstream.

Due to ITS, indirect branches in the lower half of a cacheline may be vulnerable to branch target injection attack.

Introduce ITS-safe thunks to patch indirect branches in the lower half of cacheline with the thunk. Also thunk any eBPF generated indirect branches in emit_indirect_jump().

Below category of indirect branches are not mitigated:

- Indirect branches in the .init section are not mitigated because they are discarded after boot.
- Indirect branches that are explicitly marked retpoline-safe.

Note that retpoline also mitigates the indirect branches against ITS. This is because the retpoline sequence fills an RSB entry before RET, and it does not suffer from RSB-underflow part of the ITS.

---
 arch/x86/Kconfig                     |   11 ++++++++
 arch/x86/include/asm/cpufeatures.h   |    1 
 arch/x86/include/asm/nospec-branch.h |    4 +++
 arch/x86/kernel/alternative.c        |   45 ++++++++++++++++++++++++++++++++---
 arch/x86/kernel/vmlinux.lds.S        |    6 ++++
 arch/x86/lib/retpoline.S             |   28 +++++++++++++++++++++
 arch/x86/net/bpf_jit_comp.c          |    5 +++
 7 files changed, 96 insertions(+), 4 deletions(-)
arch/x86/Kconfig +11 -0
@@ -2747,6 +2747,17 @@ config MITIGATION_SSB
 	  of speculative execution in a similar way to the Meltdown and Spectre
 	  security vulnerabilities.
 
+config MITIGATION_ITS
+	bool "Enable Indirect Target Selection mitigation"
+	depends on CPU_SUP_INTEL && X86_64
+	depends on MITIGATION_RETPOLINE && MITIGATION_RETHUNK
+	default y
+	help
+	  Enable Indirect Target Selection (ITS) mitigation. ITS is a bug in
+	  BPU on some Intel CPUs that may allow Spectre V2 style attacks. If
+	  disabled, mitigation cannot be enabled via cmdline.
+	  See <file:Documentation/admin-guide/hw-vuln/indirect-target-selection.rst>
+
 endif
 
 config ARCH_HAS_ADD_PAGES
arch/x86/include/asm/cpufeatures.h +1 -0
@@ -475,6 +475,7 @@
 #define X86_FEATURE_CLEAR_BHB_HW	(21*32+ 3) /* BHI_DIS_S HW control enabled */
 #define X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT (21*32+ 4) /* Clear branch history at vmexit using SW loop */
 #define X86_FEATURE_FAST_CPPC		(21*32 + 5) /* AMD Fast CPPC */
+#define X86_FEATURE_INDIRECT_THUNK_ITS	(21*32 + 6) /* Use thunk for indirect branches in lower half of cacheline */
 
 /*
  * BUG word(s)
arch/x86/include/asm/nospec-branch.h +4 -0
@@ -355,10 +355,14 @@
 	".long 999b\n\t"					\
 	".popsection\n\t"
 
+#define ITS_THUNK_SIZE	64
+
 typedef u8 retpoline_thunk_t[RETPOLINE_THUNK_SIZE];
+typedef u8 its_thunk_t[ITS_THUNK_SIZE];
 extern retpoline_thunk_t __x86_indirect_thunk_array[];
 extern retpoline_thunk_t __x86_indirect_call_thunk_array[];
 extern retpoline_thunk_t __x86_indirect_jump_thunk_array[];
+extern its_thunk_t	 __x86_indirect_its_thunk_array[];
 
 #ifdef CONFIG_MITIGATION_RETHUNK
 extern void __x86_return_thunk(void);
arch/x86/kernel/alternative.c +42 -3

75 lines not on this page · raw message

arch/x86/kernel/vmlinux.lds.S +6 -0
@@ -530,4 +530,10 @@ INIT_PER_CPU(irq_stack_backing_store);
 		"SRSO function pair won't alias");
 #endif
 
+#if defined(CONFIG_MITIGATION_ITS) && !defined(CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B)
+. = ASSERT(__x86_indirect_its_thunk_rax & 0x20, "__x86_indirect_thunk_rax not in second half of cacheline");
+. = ASSERT(((__x86_indirect_its_thunk_rcx - __x86_indirect_its_thunk_rax) % 64) == 0, "Indirect thunks are not cacheline apart");
+. = ASSERT(__x86_indirect_its_thunk_array == __x86_indirect_its_thunk_rax, "Gap in ITS thunk array");
+#endif
+
 #endif /* CONFIG_X86_64 */
arch/x86/lib/retpoline.S +28 -0
@@ -366,6 +366,34 @@ SYM_FUNC_END(call_depth_return_thunk)
 
 #endif /* CONFIG_MITIGATION_CALL_DEPTH_TRACKING */
 
+#ifdef CONFIG_MITIGATION_ITS
+
+.macro ITS_THUNK reg
+
+SYM_INNER_LABEL(__x86_indirect_its_thunk_\reg, SYM_L_GLOBAL)
+	UNWIND_HINT_UNDEFINED
+	ANNOTATE_NOENDBR
+	ANNOTATE_RETPOLINE_SAFE
+	jmp *%\reg
+	int3
+	.align 32, 0xcc		/* fill to the end of the line */
+	.skip  32, 0xcc		/* skip to the next upper half */
+.endm
+
+/* ITS mitigation requires thunks be aligned to upper half of cacheline */
+.align 64, 0xcc
+.skip 32, 0xcc
+SYM_CODE_START(__x86_indirect_its_thunk_array)
+
+#define GEN(reg) ITS_THUNK reg
+#include <asm/GEN-for-each-reg.h>
+#undef GEN
+
+	.align 64, 0xcc
+SYM_CODE_END(__x86_indirect_its_thunk_array)
+
+#endif
+
 /*
  * This function name is magical and is used by -mfunction-return=thunk-extern
  * for the compiler to generate JMPs to it.
arch/x86/net/bpf_jit_comp.c +4 -1
@@ -639,7 +639,10 @@ static void emit_indirect_jump(u8 **ppro
 {
 	u8 *prog = *pprog;
 
-	if (cpu_feature_enabled(X86_FEATURE_RETPOLINE_LFENCE)) {
+	if (cpu_feature_enabled(X86_FEATURE_INDIRECT_THUNK_ITS)) {
+		OPTIMIZER_HIDE_VAR(reg);
+		emit_jump(&prog, &__x86_indirect_its_thunk_array[reg], ip);
+	} else if (cpu_feature_enabled(X86_FEATURE_RETPOLINE_LFENCE)) {
 		EMIT_LFENCE();
 		EMIT2(0xFF, 0xE0 + reg);
 	} else if (cpu_feature_enabled(X86_FEATURE_RETPOLINE)) {
author maintainer
#177 lore raw

PATCH 177/184 x86/its: Add support for ITS-safe return thunk

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pawan Gupta <[email protected]>

commit a75bf27fe41abe658c53276a0c486c4bf9adecfc upstream.

RETs in the lower half of cacheline may be affected by ITS bug, specifically when the RSB-underflows. Use ITS-safe return thunk for such RETs.

RETs that are not patched:

- RET in retpoline sequence does not need to be patched, because the sequence itself fills an RSB before RET.
- RET in Call Depth Tracking (CDT) thunks __x86_indirect_{call|jump}_thunk and call_depth_return_thunk are not patched because CDT by design prevents RSB-underflow.
- RETs in .init section are not reachable after init.
- RETs that are explicitly marked safe with ANNOTATE_UNRET_SAFE.

---
 arch/x86/include/asm/alternative.h   |   14 ++++++++++++++
 arch/x86/include/asm/nospec-branch.h |    6 ++++++
 arch/x86/kernel/alternative.c        |   19 +++++++++++++++++--
 arch/x86/kernel/ftrace.c             |    2 +-
 arch/x86/kernel/static_call.c        |    4 ++--
 arch/x86/kernel/vmlinux.lds.S        |    4 ++++
 arch/x86/lib/retpoline.S             |   13 ++++++++++++-
 arch/x86/net/bpf_jit_comp.c          |    2 +-
 8 files changed, 57 insertions(+), 7 deletions(-)
arch/x86/include/asm/alternative.h +14 -0
@@ -134,6 +134,20 @@ static __always_inline int x86_call_dept
 }
 #endif
 
+#if defined(CONFIG_MITIGATION_RETHUNK) && defined(CONFIG_OBJTOOL)
+extern bool cpu_wants_rethunk(void);
+extern bool cpu_wants_rethunk_at(void *addr);
+#else
+static __always_inline bool cpu_wants_rethunk(void)
+{
+	return false;
+}
+static __always_inline bool cpu_wants_rethunk_at(void *addr)
+{
+	return false;
+}
+#endif
+
 #ifdef CONFIG_SMP
 extern void alternatives_smp_module_add(struct module *mod, char *name,
 					void *locks, void *locks_end,
arch/x86/include/asm/nospec-branch.h +6 -0
@@ -386,6 +386,12 @@ static inline void srso_return_thunk(voi
 static inline void srso_alias_return_thunk(void) {}
 #endif
 
+#ifdef CONFIG_MITIGATION_ITS
+extern void its_return_thunk(void);
+#else
+static inline void its_return_thunk(void) {}
+#endif
+
 extern void retbleed_return_thunk(void);
 extern void srso_return_thunk(void);
 extern void srso_alias_return_thunk(void);
arch/x86/kernel/alternative.c +17 -2
@@ -809,6 +809,21 @@ void __init_or_module noinline apply_ret
 
 #ifdef CONFIG_MITIGATION_RETHUNK
 
+bool cpu_wants_rethunk(void)
+{
+	return cpu_feature_enabled(X86_FEATURE_RETHUNK);
+}
+
+bool cpu_wants_rethunk_at(void *addr)
+{
+	if (!cpu_feature_enabled(X86_FEATURE_RETHUNK))
+		return false;
+	if (x86_return_thunk != its_return_thunk)
+		return true;
+
+	return !((unsigned long)addr & 0x20);
+}
+
 /*
  * Rewrite the compiler generated return thunk tail-calls.
  *
@@ -825,7 +840,7 @@ static int patch_return(void *addr, stru
 	int i = 0;
 
 	/* Patch the custom return thunks... */
-	if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) {
+	if (cpu_wants_rethunk_at(addr)) {
 		i = JMP32_INSN_SIZE;
 		__text_gen_insn(bytes, JMP32_INSN_OPCODE, addr, x86_return_thunk, i);
 	} else {
@@ -842,7 +857,7 @@ void __init_or_module noinline apply_ret
 {
 	s32 *s;
 
-	if (cpu_feature_enabled(X86_FEATURE_RETHUNK))
+	if (cpu_wants_rethunk())
 		static_call_force_reinit();
 
 	for (s = start; s < end; s++) {
arch/x86/kernel/ftrace.c +1 -1
@@ -354,7 +354,7 @@ create_trampoline(struct ftrace_ops *ops
 		goto fail;
 
 	ip = trampoline + size;
-	if (cpu_feature_enabled(X86_FEATURE_RETHUNK))
+	if (cpu_wants_rethunk_at(ip))
 		__text_gen_insn(ip, JMP32_INSN_OPCODE, ip, x86_return_thunk, JMP32_INSN_SIZE);
 	else
 		memcpy(ip, retq, sizeof(retq));
arch/x86/kernel/static_call.c +2 -2
@@ -81,7 +81,7 @@ static void __ref __static_call_transfor
 		break;
 
 	case RET:
-		if (cpu_feature_enabled(X86_FEATURE_RETHUNK))
+		if (cpu_wants_rethunk_at(insn))
 			code = text_gen_insn(JMP32_INSN_OPCODE, insn, x86_return_thunk);
 		else
 			code = &retinsn;
@@ -90,7 +90,7 @@ static void __ref __static_call_transfor
 	case JCC:
 		if (!func) {
 			func = __static_call_return;
-			if (cpu_feature_enabled(X86_FEATURE_RETHUNK))
+			if (cpu_wants_rethunk())
 				func = x86_return_thunk;
 		}
 
arch/x86/kernel/vmlinux.lds.S +4 -0
@@ -536,4 +536,8 @@ INIT_PER_CPU(irq_stack_backing_store);
 . = ASSERT(__x86_indirect_its_thunk_array == __x86_indirect_its_thunk_rax, "Gap in ITS thunk array");
 #endif
 
+#if defined(CONFIG_MITIGATION_ITS) && !defined(CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B)
+. = ASSERT(its_return_thunk & 0x20, "its_return_thunk not in second half of cacheline");
+#endif
+
 #endif /* CONFIG_X86_64 */
arch/x86/lib/retpoline.S +12 -1
@@ -392,7 +392,18 @@ SYM_CODE_START(__x86_indirect_its_thunk_
 	.align 64, 0xcc
 SYM_CODE_END(__x86_indirect_its_thunk_array)
 
-#endif
+.align 64, 0xcc
+.skip 32, 0xcc
+SYM_CODE_START(its_return_thunk)
+	UNWIND_HINT_FUNC
+	ANNOTATE_NOENDBR
+	ANNOTATE_UNRET_SAFE
+	ret
+	int3
+SYM_CODE_END(its_return_thunk)
+EXPORT_SYMBOL(its_return_thunk)
+
+#endif /* CONFIG_MITIGATION_ITS */
 
 /*
  * This function name is magical and is used by -mfunction-return=thunk-extern
arch/x86/net/bpf_jit_comp.c +1 -1
@@ -664,7 +664,7 @@ static void emit_return(u8 **pprog, u8 *
 {
 	u8 *prog = *pprog;
 
-	if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) {
+	if (cpu_wants_rethunk()) {
 		emit_jump(&prog, x86_return_thunk, ip);
 	} else {
 		EMIT1(0xC3);		/* ret */
author maintainer
#178 lore raw

PATCH 178/184 x86/its: Enable Indirect Target Selection mitigation

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pawan Gupta <[email protected]>

commit f4818881c47fd91fcb6d62373c57c7844e3de1c0 upstream.

Indirect Target Selection (ITS) is a bug in some pre-ADL Intel CPUs with eIBRS. It affects prediction of indirect branch and RETs in the lower half of cacheline. Due to ITS such branches may get wrongly predicted to a target of (direct or indirect) branch that is located in the upper half of the cacheline.

Scope of impact
===============

Guest/host isolation
--------------------
When eIBRS is used for guest/host isolation, the indirect branches in the VMM may still be predicted with targets corresponding to branches in the guest.

Intra-mode
----------
cBPF or other native gadgets can be used for intra-mode training and disclosure using ITS.

User/kernel isolation
---------------------
When eIBRS is enabled user/kernel isolation is not impacted.

Indirect Branch Prediction Barrier (IBPB)
-----------------------------------------
After an IBPB, indirect branches may be predicted with targets corresponding to direct branches which were executed prior to IBPB. This is mitigated by a microcode update.

Add cmdline parameter indirect_target_selection=off|on|force to control the mitigation to relocate the affected branches to an ITS-safe thunk i.e. located in the upper half of cacheline. Also add the sysfs reporting.

When retpoline mitigation is deployed, ITS safe-thunks are not needed, because retpoline sequence is already ITS-safe. Similarly, when call depth tracking (CDT) mitigation is deployed (retbleed=stuff), ITS safe return thunk is not used, as CDT prevents RSB-underflow.

To not overcomplicate things, ITS mitigation is not supported with spectre-v2 lfence;jmp mitigation. Moreover, it is less practical to deploy lfence;jmp mitigation on ITS affected parts anyways.

---
 Documentation/ABI/testing/sysfs-devices-system-cpu |    1 
 Documentation/admin-guide/kernel-parameters.txt    |   13 +
 arch/x86/kernel/cpu/bugs.c                         |  140 ++++++++++++++++++++-
 drivers/base/cpu.c                                 |    3 
 include/linux/cpu.h                                |    2 
 5 files changed, 155 insertions(+), 4 deletions(-)
Documentation/ABI/testing/sysfs-devices-system-cpu +1 -0
@@ -511,6 +511,7 @@ Description:	information about CPUs hete
 
 What:		/sys/devices/system/cpu/vulnerabilities
 		/sys/devices/system/cpu/vulnerabilities/gather_data_sampling
+		/sys/devices/system/cpu/vulnerabilities/indirect_target_selection
 		/sys/devices/system/cpu/vulnerabilities/itlb_multihit
 		/sys/devices/system/cpu/vulnerabilities/l1tf
 		/sys/devices/system/cpu/vulnerabilities/mds
Documentation/admin-guide/kernel-parameters.txt +13 -0
@@ -2149,6 +2149,18 @@
 			different crypto accelerators. This option can be used
 			to achieve best performance for particular HW.
 
+	indirect_target_selection= [X86,Intel] Mitigation control for Indirect
+			Target Selection(ITS) bug in Intel CPUs. Updated
+			microcode is also required for a fix in IBPB.
+
+			on:     Enable mitigation (default).
+			off:    Disable mitigation.
+			force:	Force the ITS bug and deploy default
+				mitigation.
+
+			For details see:
+			Documentation/admin-guide/hw-vuln/indirect-target-selection.rst
+
 	init=		[KNL]
 			Format: <full_path>
 			Run specified binary instead of /sbin/init as init
@@ -3510,6 +3522,7 @@
 				expose users to several CPU vulnerabilities.
 				Equivalent to: if nokaslr then kpti=0 [ARM64]
 					       gather_data_sampling=off [X86]
+					       indirect_target_selection=off [X86]
 					       kvm.nx_huge_pages=off [X86]
 					       l1tf=off [X86]
 					       mds=off [X86]
arch/x86/kernel/cpu/bugs.c +136 -4

202 lines not on this page · raw message

drivers/base/cpu.c +3 -0
@@ -599,6 +599,7 @@ CPU_SHOW_VULN_FALLBACK(retbleed);
 CPU_SHOW_VULN_FALLBACK(spec_rstack_overflow);
 CPU_SHOW_VULN_FALLBACK(gds);
 CPU_SHOW_VULN_FALLBACK(reg_file_data_sampling);
+CPU_SHOW_VULN_FALLBACK(indirect_target_selection);
 
 static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL);
 static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL);
@@ -614,6 +615,7 @@ static DEVICE_ATTR(retbleed, 0444, cpu_s
 static DEVICE_ATTR(spec_rstack_overflow, 0444, cpu_show_spec_rstack_overflow, NULL);
 static DEVICE_ATTR(gather_data_sampling, 0444, cpu_show_gds, NULL);
 static DEVICE_ATTR(reg_file_data_sampling, 0444, cpu_show_reg_file_data_sampling, NULL);
+static DEVICE_ATTR(indirect_target_selection, 0444, cpu_show_indirect_target_selection, NULL);
 
 static struct attribute *cpu_root_vulnerabilities_attrs[] = {
 	&dev_attr_meltdown.attr,
@@ -630,6 +632,7 @@ static struct attribute *cpu_root_vulner
 	&dev_attr_spec_rstack_overflow.attr,
 	&dev_attr_gather_data_sampling.attr,
 	&dev_attr_reg_file_data_sampling.attr,
+	&dev_attr_indirect_target_selection.attr,
 	NULL
 };
 
include/linux/cpu.h +2 -0
@@ -77,6 +77,8 @@ extern ssize_t cpu_show_gds(struct devic
 			    struct device_attribute *attr, char *buf);
 extern ssize_t cpu_show_reg_file_data_sampling(struct device *dev,
 					       struct device_attribute *attr, char *buf);
+extern ssize_t cpu_show_indirect_target_selection(struct device *dev,
+						  struct device_attribute *attr, char *buf);
 
 extern __printf(4, 5)
 struct device *cpu_device_create(struct device *parent, void *drvdata,
author maintainer
#179 lore raw

PATCH 179/184 x86/its: Add "vmexit" option to skip mitigation on some CPUs

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pawan Gupta <[email protected]>

commit 2665281a07e19550944e8354a2024635a7b2714a upstream.

Ice Lake generation CPUs are not affected by guest/host isolation part of ITS. If a user is only concerned about KVM guests, they can now choose a new cmdline option "vmexit" that will not deploy the ITS mitigation when CPU is not affected by guest/host isolation. This saves the performance overhead of ITS mitigation on Ice Lake gen CPUs.

When "vmexit" option selected, if the CPU is affected by ITS guest/host isolation, the default ITS mitigation is deployed.

---
 Documentation/admin-guide/kernel-parameters.txt |    2 ++
 arch/x86/include/asm/cpufeatures.h              |    1 +
 arch/x86/kernel/cpu/bugs.c                      |   11 +++++++++++
 arch/x86/kernel/cpu/common.c                    |   19 ++++++++++++-------
 4 files changed, 26 insertions(+), 7 deletions(-)
Documentation/admin-guide/kernel-parameters.txt +2 -0
@@ -2157,6 +2157,8 @@
 			off:    Disable mitigation.
 			force:	Force the ITS bug and deploy default
 				mitigation.
+			vmexit: Only deploy mitigation if CPU is affected by
+				guest/host isolation part of ITS.
 
 			For details see:
 			Documentation/admin-guide/hw-vuln/indirect-target-selection.rst
arch/x86/include/asm/cpufeatures.h +1 -0
@@ -528,4 +528,5 @@
 #define X86_BUG_BHI			X86_BUG(1*32 + 3) /* "bhi" CPU is affected by Branch History Injection */
 #define X86_BUG_IBPB_NO_RET	   	X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB omits return target predictions */
 #define X86_BUG_ITS			X86_BUG(1*32 + 5) /* "its" CPU is affected by Indirect Target Selection */
+#define X86_BUG_ITS_NATIVE_ONLY		X86_BUG(1*32 + 6) /* "its_native_only" CPU is affected by ITS, VMX is not affected */
 #endif /* _ASM_X86_CPUFEATURES_H */
arch/x86/kernel/cpu/bugs.c +11 -0
@@ -1189,16 +1189,19 @@ do_cmd_auto:
 enum its_mitigation_cmd {
 	ITS_CMD_OFF,
 	ITS_CMD_ON,
+	ITS_CMD_VMEXIT,
 };
 
 enum its_mitigation {
 	ITS_MITIGATION_OFF,
+	ITS_MITIGATION_VMEXIT_ONLY,
 	ITS_MITIGATION_ALIGNED_THUNKS,
 	ITS_MITIGATION_RETPOLINE_STUFF,
 };
 
 static const char * const its_strings[] = {
 	[ITS_MITIGATION_OFF]			= "Vulnerable",
+	[ITS_MITIGATION_VMEXIT_ONLY]		= "Mitigation: Vulnerable, KVM: Not affected",
 	[ITS_MITIGATION_ALIGNED_THUNKS]		= "Mitigation: Aligned branch/return thunks",
 	[ITS_MITIGATION_RETPOLINE_STUFF]	= "Mitigation: Retpolines, Stuffing RSB",
 };
@@ -1225,6 +1228,8 @@ static int __init its_parse_cmdline(char
 	} else if (!strcmp(str, "force")) {
 		its_cmd = ITS_CMD_ON;
 		setup_force_cpu_bug(X86_BUG_ITS);
+	} else if (!strcmp(str, "vmexit")) {
+		its_cmd = ITS_CMD_VMEXIT;
 	} else {
 		pr_err("Ignoring unknown indirect_target_selection option (%s).", str);
 	}
@@ -1280,6 +1285,12 @@ static void __init its_select_mitigation
 	case ITS_CMD_OFF:
 		its_mitigation = ITS_MITIGATION_OFF;
 		break;
+	case ITS_CMD_VMEXIT:
+		if (boot_cpu_has_bug(X86_BUG_ITS_NATIVE_ONLY)) {
+			its_mitigation = ITS_MITIGATION_VMEXIT_ONLY;
+			goto out;
+		}
+		fallthrough;
 	case ITS_CMD_ON:
 		its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
 		if (!boot_cpu_has(X86_FEATURE_RETPOLINE))
arch/x86/kernel/cpu/common.c +12 -7
@@ -1230,6 +1230,8 @@ static const __initconst struct x86_cpu_
 #define RFDS		BIT(7)
 /* CPU is affected by Indirect Target Selection */
 #define ITS		BIT(8)
+/* CPU is affected by Indirect Target Selection, but guest-host isolation is not affected */
+#define ITS_NATIVE_ONLY	BIT(9)
 
 static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
 	VULNBL_INTEL_STEPPINGS(INTEL_IVYBRIDGE,		X86_STEPPING_ANY,		SRBDS),
@@ -1250,16 +1252,16 @@ static const struct x86_cpu_id cpu_vuln_
 	VULNBL_INTEL_STEPPINGS(INTEL_KABYLAKE,		X86_STEPPINGS(0x0, 0xc),	MMIO | RETBLEED | GDS | SRBDS),
 	VULNBL_INTEL_STEPPINGS(INTEL_KABYLAKE,		X86_STEPPING_ANY,		MMIO | RETBLEED | GDS | SRBDS | ITS),
 	VULNBL_INTEL_STEPPINGS(INTEL_CANNONLAKE_L,	X86_STEPPING_ANY,		RETBLEED),
-	VULNBL_INTEL_STEPPINGS(INTEL_ICELAKE_L,		X86_STEPPING_ANY,		MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
-	VULNBL_INTEL_STEPPINGS(INTEL_ICELAKE_D,		X86_STEPPING_ANY,		MMIO | GDS | ITS),
-	VULNBL_INTEL_STEPPINGS(INTEL_ICELAKE_X,		X86_STEPPING_ANY,		MMIO | GDS | ITS),
+	VULNBL_INTEL_STEPPINGS(INTEL_ICELAKE_L,		X86_STEPPING_ANY,		MMIO | MMIO_SBDS | RETBLEED | GDS | ITS | ITS_NATIVE_ONLY),
+	VULNBL_INTEL_STEPPINGS(INTEL_ICELAKE_D,		X86_STEPPING_ANY,		MMIO | GDS | ITS | ITS_NATIVE_ONLY),
+	VULNBL_INTEL_STEPPINGS(INTEL_ICELAKE_X,		X86_STEPPING_ANY,		MMIO | GDS | ITS | ITS_NATIVE_ONLY),
 	VULNBL_INTEL_STEPPINGS(INTEL_COMETLAKE,		X86_STEPPING_ANY,		MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
 	VULNBL_INTEL_STEPPINGS(INTEL_COMETLAKE_L,	X86_STEPPINGS(0x0, 0x0),	MMIO | RETBLEED | ITS),
 	VULNBL_INTEL_STEPPINGS(INTEL_COMETLAKE_L,	X86_STEPPING_ANY,		MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
-	VULNBL_INTEL_STEPPINGS(INTEL_TIGERLAKE_L,	X86_STEPPING_ANY,		GDS | ITS),
-	VULNBL_INTEL_STEPPINGS(INTEL_TIGERLAKE,		X86_STEPPING_ANY,		GDS | ITS),
+	VULNBL_INTEL_STEPPINGS(INTEL_TIGERLAKE_L,	X86_STEPPING_ANY,		GDS | ITS | ITS_NATIVE_ONLY),
+	VULNBL_INTEL_STEPPINGS(INTEL_TIGERLAKE,		X86_STEPPING_ANY,		GDS | ITS | ITS_NATIVE_ONLY),
 	VULNBL_INTEL_STEPPINGS(INTEL_LAKEFIELD,		X86_STEPPING_ANY,		MMIO | MMIO_SBDS | RETBLEED),
-	VULNBL_INTEL_STEPPINGS(INTEL_ROCKETLAKE,	X86_STEPPING_ANY,		MMIO | RETBLEED | GDS | ITS),
+	VULNBL_INTEL_STEPPINGS(INTEL_ROCKETLAKE,	X86_STEPPING_ANY,		MMIO | RETBLEED | GDS | ITS | ITS_NATIVE_ONLY),
 	VULNBL_INTEL_STEPPINGS(INTEL_ALDERLAKE,		X86_STEPPING_ANY,		RFDS),
 	VULNBL_INTEL_STEPPINGS(INTEL_ALDERLAKE_L,	X86_STEPPING_ANY,		RFDS),
 	VULNBL_INTEL_STEPPINGS(INTEL_RAPTORLAKE,	X86_STEPPING_ANY,		RFDS),
@@ -1481,8 +1483,11 @@ static void __init cpu_set_bug_bits(stru
 	if (cpu_has(c, X86_FEATURE_AMD_IBPB) && !cpu_has(c, X86_FEATURE_AMD_IBPB_RET))
 		setup_force_cpu_bug(X86_BUG_IBPB_NO_RET);
 
-	if (vulnerable_to_its(x86_arch_cap_msr))
+	if (vulnerable_to_its(x86_arch_cap_msr)) {
 		setup_force_cpu_bug(X86_BUG_ITS);
+		if (cpu_matches(cpu_vuln_blacklist, ITS_NATIVE_ONLY))
+			setup_force_cpu_bug(X86_BUG_ITS_NATIVE_ONLY);
+	}
 
 	if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))
 		return;
author maintainer
#180 lore raw

PATCH 180/184 x86/its: Add support for RSB stuffing mitigation

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pawan Gupta <[email protected]>

commit facd226f7e0c8ca936ac114aba43cb3e8b94e41e upstream.

When retpoline mitigation is enabled for spectre-v2, enabling call-depth-tracking and RSB stuffing also mitigates ITS. Add cmdline option indirect_target_selection=stuff to allow enabling RSB stuffing mitigation.

When retpoline mitigation is not enabled, =stuff option is ignored, and default mitigation for ITS is deployed.

---
 Documentation/admin-guide/kernel-parameters.txt |    3 +++
 arch/x86/kernel/cpu/bugs.c                      |   19 +++++++++++++++++++
 2 files changed, 22 insertions(+)
Documentation/admin-guide/kernel-parameters.txt +3 -0
@@ -2159,6 +2159,9 @@
 				mitigation.
 			vmexit: Only deploy mitigation if CPU is affected by
 				guest/host isolation part of ITS.
+			stuff:	Deploy RSB-fill mitigation when retpoline is
+				also deployed. Otherwise, deploy the default
+				mitigation.
 
 			For details see:
 			Documentation/admin-guide/hw-vuln/indirect-target-selection.rst
arch/x86/kernel/cpu/bugs.c +19 -0
@@ -1190,6 +1190,7 @@ enum its_mitigation_cmd {
 	ITS_CMD_OFF,
 	ITS_CMD_ON,
 	ITS_CMD_VMEXIT,
+	ITS_CMD_RSB_STUFF,
 };
 
 enum its_mitigation {
@@ -1230,6 +1231,8 @@ static int __init its_parse_cmdline(char
 		setup_force_cpu_bug(X86_BUG_ITS);
 	} else if (!strcmp(str, "vmexit")) {
 		its_cmd = ITS_CMD_VMEXIT;
+	} else if (!strcmp(str, "stuff")) {
+		its_cmd = ITS_CMD_RSB_STUFF;
 	} else {
 		pr_err("Ignoring unknown indirect_target_selection option (%s).", str);
 	}
@@ -1281,6 +1284,12 @@ static void __init its_select_mitigation
 		goto out;
 	}
 
+	if (cmd == ITS_CMD_RSB_STUFF &&
+	    (!boot_cpu_has(X86_FEATURE_RETPOLINE) || !IS_ENABLED(CONFIG_MITIGATION_CALL_DEPTH_TRACKING))) {
+		pr_err("RSB stuff mitigation not supported, using default\n");
+		cmd = ITS_CMD_ON;
+	}
+
 	switch (cmd) {
 	case ITS_CMD_OFF:
 		its_mitigation = ITS_MITIGATION_OFF;
@@ -1298,6 +1307,16 @@ static void __init its_select_mitigation
 		setup_force_cpu_cap(X86_FEATURE_RETHUNK);
 		set_return_thunk(its_return_thunk);
 		break;
+	case ITS_CMD_RSB_STUFF:
+		its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
+		setup_force_cpu_cap(X86_FEATURE_RETHUNK);
+		setup_force_cpu_cap(X86_FEATURE_CALL_DEPTH);
+		set_return_thunk(call_depth_return_thunk);
+		if (retbleed_mitigation == RETBLEED_MITIGATION_NONE) {
+			retbleed_mitigation = RETBLEED_MITIGATION_STUFF;
+			pr_info("Retbleed mitigation updated to stuffing\n");
+		}
+		break;
 	}
 out:
 	pr_info("%s\n", its_strings[its_mitigation]);
author maintainer
#181 lore raw

PATCH 181/184 x86/its: Align RETs in BHB clear sequence to avoid thunking

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pawan Gupta <[email protected]>

commit f0cd7091cc5a032c8870b4285305d9172569d126 upstream.

The software mitigation for BHI is to execute BHB clear sequence at syscall entry, and possibly after a cBPF program. ITS mitigation thunks RETs in the lower half of the cacheline. This causes the RETs in the BHB clear sequence to be thunked as well, adding unnecessary branches to the BHB clear sequence.

Since the sequence is in hot path, align the RET instructions in the sequence to avoid thunking.

This is how disassembly clear_bhb_loop() looks like after this change:

   0x44 <+4>:     mov    $0x5,%ecx
   0x49 <+9>:     call   0xffffffff81001d9b <clear_bhb_loop+91>
   0x4e <+14>:    jmp    0xffffffff81001de5 <clear_bhb_loop+165>
   0x53 <+19>:    int3
   ...
   0x9b <+91>:    call   0xffffffff81001dce <clear_bhb_loop+142>
   0xa0 <+96>:    ret
   0xa1 <+97>:    int3
   ...
   0xce <+142>:   mov    $0x5,%eax
   0xd3 <+147>:   jmp    0xffffffff81001dd6 <clear_bhb_loop+150>
   0xd5 <+149>:   nop
   0xd6 <+150>:   sub    $0x1,%eax
   0xd9 <+153>:   jne    0xffffffff81001dd3 <clear_bhb_loop+147>
   0xdb <+155>:   sub    $0x1,%ecx
   0xde <+158>:   jne    0xffffffff81001d9b <clear_bhb_loop+91>
   0xe0 <+160>:   ret
   0xe1 <+161>:   int3
   0xe2 <+162>:   int3
   0xe3 <+163>:   int3
   0xe4 <+164>:   int3
   0xe5 <+165>:   lfence
   0xe8 <+168>:   pop    %rbp
   0xe9 <+169>:   ret
---
 arch/x86/entry/entry_64.S |   20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)
arch/x86/entry/entry_64.S +17 -3
@@ -1524,7 +1524,9 @@ SYM_CODE_END(rewind_stack_and_make_dead)
  * ORC to unwind properly.
  *
  * The alignment is for performance and not for safety, and may be safely
- * refactored in the future if needed.
+ * refactored in the future if needed. The .skips are for safety, to ensure
+ * that all RETs are in the second half of a cacheline to mitigate Indirect
+ * Target Selection, rather than taking the slowpath via its_return_thunk.
  */
 SYM_FUNC_START(clear_bhb_loop)
 	push	%rbp
@@ -1534,10 +1536,22 @@ SYM_FUNC_START(clear_bhb_loop)
 	call	1f
 	jmp	5f
 	.align 64, 0xcc
+	/*
+	 * Shift instructions so that the RET is in the upper half of the
+	 * cacheline and don't take the slowpath to its_return_thunk.
+	 */
+	.skip 32 - (.Lret1 - 1f), 0xcc
 	ANNOTATE_INTRA_FUNCTION_CALL
 1:	call	2f
-	RET
+.Lret1:	RET
 	.align 64, 0xcc
+	/*
+	 * As above shift instructions for RET at .Lret2 as well.
+	 *
+	 * This should be ideally be: .skip 32 - (.Lret2 - 2f), 0xcc
+	 * but some Clang versions (e.g. 18) don't like this.
+	 */
+	.skip 32 - 18, 0xcc
 2:	movl	$5, %eax
 3:	jmp	4f
 	nop
@@ -1545,7 +1559,7 @@ SYM_FUNC_START(clear_bhb_loop)
 	jnz	3b
 	sub	$1, %ecx
 	jnz	1b
-	RET
+.Lret2:	RET
 5:	lfence
 	pop	%rbp
 	RET
author maintainer
#182 lore raw

PATCH 182/184 x86/ibt: Keep IBT disabled during alternative patching

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pawan Gupta <[email protected]>

commit ebebe30794d38c51f71fe4951ba6af4159d9837d upstream.

cfi_rewrite_callers() updates the fineIBT hash matching at the caller side, but except for paranoid-mode it relies on apply_retpoline() and friends for any ENDBR relocation. This could temporarily cause an indirect branch to land on a poisoned ENDBR.

For instance, with para-virtualization enabled, a simple wrmsrl() could have an indirect branch pointing to native_write_msr() who's ENDBR has been relocated due to fineIBT:

<wrmsrl>:

       push   %rbp
       mov    %rsp,%rbp
       mov    %esi,%eax
       mov    %rsi,%rdx
       shr    $0x20,%rdx
       mov    %edi,%edi
       mov    %rax,%rsi
       call   *0x21e65d0(%rip)        # <pv_ops+0xb8>
       ^^^^^^^^^^^^^^^^^^^^^^^

Such an indirect call during the alternative patching could #CP if the caller is not *yet* adjusted for the new target ENDBR. To prevent a false
#CP, keep CET-IBT disabled until all callers are patched.

Patching during the module load does not need to be guarded by IBT-disable because the module code is not executed until the patching is complete.

---
 arch/x86/kernel/alternative.c |    8 ++++++++
 1 file changed, 8 insertions(+)
arch/x86/kernel/alternative.c +8 -0
@@ -31,6 +31,7 @@
 #include <asm/paravirt.h>
 #include <asm/asm-prototypes.h>
 #include <asm/cfi.h>
+#include <asm/ibt.h>
 
 int __read_mostly alternatives_patched;
 
@@ -1719,6 +1720,8 @@ static noinline void __init alt_reloc_se
 
 void __init alternative_instructions(void)
 {
+	u64 ibt;
+
 	int3_selftest();
 
 	/*
@@ -1745,6 +1748,9 @@ void __init alternative_instructions(voi
 	 */
 	paravirt_set_cap();
 
+	/* Keep CET-IBT disabled until caller/callee are patched */
+	ibt = ibt_save(/*disable*/ true);
+
 	__apply_fineibt(__retpoline_sites, __retpoline_sites_end,
 			__cfi_sites, __cfi_sites_end, true);
 
@@ -1768,6 +1774,8 @@ void __init alternative_instructions(voi
 	 */
 	apply_seal_endbr(__ibt_endbr_seal, __ibt_endbr_seal_end);
 
+	ibt_restore(ibt);
+
 #ifdef CONFIG_SMP
 	/* Patch to UP if other cpus not imminent. */
 	if (!noreplace_smp && (num_present_cpus() == 1 || setup_max_cpus <= 1)) {
author maintainer
#183 lore raw

PATCH 183/184 x86/its: Use dynamic thunks for indirect branches

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Peter Zijlstra <[email protected]>

commit 872df34d7c51a79523820ea6a14860398c639b87 upstream.

ITS mitigation moves the unsafe indirect branches to a safe thunk. This could degrade the prediction accuracy as the source address of indirect branches becomes same for different execution paths.

To improve the predictions, and hence the performance, assign a separate thunk for each indirect callsite. This is also a defense-in-depth measure to avoid indirect branches aliasing with each other.

As an example, 5000 dynamic thunks would utilize around 16 bits of the address space, thereby gaining entropy. For a BTB that uses 32 bits for indexing, dynamic thunks could provide better prediction accuracy over fixed thunks.

Have ITS thunks be variable sized and use EXECMEM_MODULE_TEXT such that they are both more flexible (got to extend them later) and live in 2M TLBs, just like kernel code, avoiding undue TLB pressure.

[ pawan: CONFIG_EXECMEM_ROX is not supported on backport kernel, made
adjustments to set memory to RW and ROX ]

---
 arch/x86/Kconfig                   |    1 
 arch/x86/include/asm/alternative.h |   10 ++
 arch/x86/kernel/alternative.c      |  129 ++++++++++++++++++++++++++++++++++++-
 arch/x86/kernel/module.c           |    6 +
 include/linux/execmem.h            |    3 
 include/linux/module.h             |    5 +
 6 files changed, 151 insertions(+), 3 deletions(-)
arch/x86/Kconfig +1 -0
@@ -2751,6 +2751,7 @@ config MITIGATION_ITS
 	bool "Enable Indirect Target Selection mitigation"
 	depends on CPU_SUP_INTEL && X86_64
 	depends on MITIGATION_RETPOLINE && MITIGATION_RETHUNK
+	select EXECMEM
 	default y
 	help
 	  Enable Indirect Target Selection (ITS) mitigation. ITS is a bug in
arch/x86/include/asm/alternative.h +10 -0
@@ -134,6 +134,16 @@ static __always_inline int x86_call_dept
 }
 #endif
 
+#ifdef CONFIG_MITIGATION_ITS
+extern void its_init_mod(struct module *mod);
+extern void its_fini_mod(struct module *mod);
+extern void its_free_mod(struct module *mod);
+#else /* CONFIG_MITIGATION_ITS */
+static inline void its_init_mod(struct module *mod) { }
+static inline void its_fini_mod(struct module *mod) { }
+static inline void its_free_mod(struct module *mod) { }
+#endif
+
 #if defined(CONFIG_MITIGATION_RETHUNK) && defined(CONFIG_OBJTOOL)
 extern bool cpu_wants_rethunk(void);
 extern bool cpu_wants_rethunk_at(void *addr);
arch/x86/kernel/alternative.c +126 -3

153 lines not on this page · raw message

arch/x86/kernel/module.c +6 -0
@@ -251,6 +251,8 @@ int module_finalize(const Elf_Ehdr *hdr,
 			ibt_endbr = s;
 	}
 
+	its_init_mod(me);
+
 	if (retpolines || cfi) {
 		void *rseg = NULL, *cseg = NULL;
 		unsigned int rsize = 0, csize = 0;
@@ -271,6 +273,9 @@ int module_finalize(const Elf_Ehdr *hdr,
 		void *rseg = (void *)retpolines->sh_addr;
 		apply_retpolines(rseg, rseg + retpolines->sh_size);
 	}
+
+	its_fini_mod(me);
+
 	if (returns) {
 		void *rseg = (void *)returns->sh_addr;
 		apply_returns(rseg, rseg + returns->sh_size);
@@ -318,4 +323,5 @@ int module_finalize(const Elf_Ehdr *hdr,
 void module_arch_cleanup(struct module *mod)
 {
 	alternatives_smp_module_del(mod);
+	its_free_mod(mod);
 }
include/linux/execmem.h +3 -0
@@ -4,6 +4,7 @@
 
 #include <linux/types.h>
 #include <linux/moduleloader.h>
+#include <linux/cleanup.h>
 
 #if (defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) && \
 		!defined(CONFIG_KASAN_VMALLOC)
@@ -123,6 +124,8 @@ void *execmem_alloc(enum execmem_type ty
  */
 void execmem_free(void *ptr);
 
+DEFINE_FREE(execmem, void *, if (_T) execmem_free(_T));
+
 #if defined(CONFIG_EXECMEM) && !defined(CONFIG_ARCH_WANTS_EXECMEM_LATE)
 void execmem_init(void);
 #else
include/linux/module.h +5 -0
@@ -582,6 +582,11 @@ struct module {
 	atomic_t refcnt;
 #endif
 
+#ifdef CONFIG_MITIGATION_ITS
+	int its_num_pages;
+	void **its_page_array;
+#endif
+
 #ifdef CONFIG_CONSTRUCTORS
 	/* Constructor functions. */
 	ctor_fn_t *ctors;
author maintainer
#184 lore raw

PATCH 184/184 selftest/x86/bugs: Add selftests for ITS

In reply to Greg Kroah-Hartman

6.12-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pawan Gupta <[email protected]>

commit 7a9b709e7cc5ce1ffb84ce07bf6d157e1de758df upstream.

Below are the tests added for Indirect Target Selection (ITS):

- its_sysfs.py - Check if sysfs reflects the correct mitigation status for the mitigation selected via the kernel cmdline.

- its_permutations.py - tests mitigation selection with cmdline permutations with other bugs like spectre_v2 and retbleed.

- its_indirect_alignment.py - verifies that for addresses in .retpoline_sites section that belong to lower half of cacheline are patched to ITS-safe thunk. Typical output looks like below:

Site 49: function symbol: __x64_sys_restart_syscall+0x1f <0xffffffffbb1509af>

  #     vmlinux: 0xffffffff813509af:    jmp     0xffffffff81f5a8e0
  #     kcore:   0xffffffffbb1509af:    jmpq    *%rax
  #     ITS thunk NOT expected for site 49
  #     PASSED: Found *%rax
  #
  Site 50: function symbol: __resched_curr+0xb0 <0xffffffffbb181910>
  #     vmlinux: 0xffffffff81381910:    jmp     0xffffffff81f5a8e0
  #     kcore:   0xffffffffbb181910:    jmp     0xffffffffc02000fc
  #     ITS thunk expected for site 50
  #     PASSED: Found 0xffffffffc02000fc -> jmpq *%rax <scattered-thunk?>

- its_ret_alignment.py - verifies that for addresses in .return_sites section that belong to lower half of cacheline are patched to its_return_thunk. Typical output looks like below:

Site 97: function symbol: collect_event+0x48 <0xffffffffbb007f18>

  #     vmlinux: 0xffffffff81207f18:    jmp     0xffffffff81f5b500
  #     kcore:   0xffffffffbb007f18:    jmp     0xffffffffbbd5b560
  #     PASSED: Found jmp 0xffffffffbbd5b560 <its_return_thunk>
  #
  Site 98: function symbol: collect_event+0xa4 <0xffffffffbb007f74>
  #     vmlinux: 0xffffffff81207f74:    jmp     0xffffffff81f5b500
  #     kcore:   0xffffffffbb007f74:    retq
  #     PASSED: Found retq

Some of these tests have dependency on tools like virtme-ng[1] and drgn[2]. When the dependencies are not met, the test will be skipped.

[1] https://github.com/arighi/virtme-ng
[2] https://github.com/osandov/drgn

---
 tools/testing/selftests/Makefile                           |    1 
 tools/testing/selftests/x86/bugs/Makefile                  |    3 
 tools/testing/selftests/x86/bugs/common.py                 |  164 +++++++++++++
 tools/testing/selftests/x86/bugs/its_indirect_alignment.py |  150 +++++++++++
 tools/testing/selftests/x86/bugs/its_permutations.py       |  109 ++++++++
 tools/testing/selftests/x86/bugs/its_ret_alignment.py      |  139 +++++++++++
 tools/testing/selftests/x86/bugs/its_sysfs.py              |   65 +++++
 7 files changed, 631 insertions(+)
 create mode 100644 tools/testing/selftests/x86/bugs/Makefile
 create mode 100755 tools/testing/selftests/x86/bugs/common.py
 create mode 100755 tools/testing/selftests/x86/bugs/its_indirect_alignment.py
 create mode 100755 tools/testing/selftests/x86/bugs/its_permutations.py
 create mode 100755 tools/testing/selftests/x86/bugs/its_ret_alignment.py
 create mode 100755 tools/testing/selftests/x86/bugs/its_sysfs.py
tools/testing/selftests/Makefile +1 -0
@@ -115,6 +115,7 @@ TARGETS += user_events
 TARGETS += vDSO
 TARGETS += mm
 TARGETS += x86
+TARGETS += x86/bugs
 TARGETS += zram
 #Please keep the TARGETS list alphabetically sorted
 # Run "make quicktest=1 run_tests" or
tools/testing/selftests/x86/bugs/Makefile new file +3 -0
@@ -0,0 +1,3 @@
+TEST_PROGS := its_sysfs.py its_permutations.py its_indirect_alignment.py its_ret_alignment.py
+TEST_FILES := common.py
+include ../../lib.mk
tools/testing/selftests/x86/bugs/common.py new file +164 -0

164 lines not on this page · raw message

tools/testing/selftests/x86/bugs/its_indirect_alignment.py new file +150 -0

150 lines not on this page · raw message

tools/testing/selftests/x86/bugs/its_permutations.py new file +109 -0

109 lines not on this page · raw message

tools/testing/selftests/x86/bugs/its_ret_alignment.py new file +139 -0

139 lines not on this page · raw message

tools/testing/selftests/x86/bugs/its_sysfs.py new file +65 -0

65 lines not on this page · raw message

maintainer Tested-by on the v1 series
#185 lore raw
In reply to Greg Kroah-Hartman
Quoted 9 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 6.12.29 release. There are 184 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Wed, 14 May 2025 17:19:58 +0000. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

Quoted 8 lines
	https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.12.29-rc1.gz

or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.12.y
and the diffstat can be found below.

thanks,

greg k-h

All tests passing for Tegra ...

Test results for stable-v6.12:

    10 builds:	10 pass, 0 fail
    28 boots:	28 pass, 0 fail
    116 tests:	116 pass, 0 fail

Linux version: 6.12.29-rc1-gd90d77b7ffdf
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,

                tegra186-p3509-0000+p3636-0001, tegra194-p2972-0000,
                tegra194-p3509-0000+p3668-0000, tegra20-ventana,
                tegra210-p2371-2180, tegra210-p3450-0000,
                tegra30-cardhu-a04

Jon

Tested-by on the v1 series
#187 lore raw
In reply to Greg Kroah-Hartman
Quoted 9 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 6.12.29 release. There are 184 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Wed, 14 May 2025 17:19:58 +0000. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

Quoted 8 lines
	https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.12.29-rc1.gz

or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.12.y
and the diffstat can be found below.

thanks,

greg k-h

Built and booted successfully on RISC-V RV64 (HiFive Unmatched).

Tested-by on the v1 series
#188 lore raw
In reply to Greg Kroah-Hartman
Quoted 9 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 6.12.29 release. There are 184 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Wed, 14 May 2025 17:19:58 +0000. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

Quoted 8 lines
	https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.12.29-rc1.gz

or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.12.y
and the diffstat can be found below.

thanks,

greg k-h

On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:

Signature · 1 line
Florian
Tested-by on the v1 series
#189 lore raw
In reply to Greg Kroah-Hartman
Quoted 10 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 6.12.29 release. There are 184 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Wed, 14 May 2025 17:19:58 +0000. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

Quoted 8 lines
        https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.12.29-rc1.gz

or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.12.y
and the diffstat can be found below.

thanks,

greg k-h

Builds successfully. Boots and works on qemu and Dell XPS 15 9520 w/ Intel Core i7-12600H

Thanks,
Brett

#190 lore raw
In reply to Greg Kroah-Hartman
Quoted 10 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 6.12.29 release. There are 184 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Wed, 14 May 2025 17:19:58 +0000. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

Quoted 8 lines
        https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.12.29-rc1.gz

or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.12.y
and the diffstat can be found below.

thanks,

greg k-h

Regressions on mips defconfig tinyconfig and allnoconfig builds failed with clang-20 toolchain on stable-rc 6.12.29-rc1, 6.14.7-rc1, and 6.6.91-rc1. But, builds pass with gcc-12.

* mips, build
- clang-20-allnoconfig
- clang-20-defconfig
- clang-20-tinyconfig
- korg-clang-20-lkftconfig-hardening
- korg-clang-20-lkftconfig-lto-full
- korg-clang-20-lkftconfig-lto-thing

Regression Analysis:
- New regression? Yes
- Reproducibility? Yes

Build regression: mips defconfig clang-20 instantiation error expected an immediate

## Build error mips
<instantiation>:7:11: error: expected an immediate
ori $26, r4k_wait_idle_size - 2

          ^
<instantiation>:10:13: error: expected an immediate
 addiu $26, r4k_wait_exit - r4k_wait_insn + 2
            ^
<instantiation>:10:29: error: expected an immediate
 addiu $26, r4k_wait_exit - r4k_wait_insn + 2
                            ^
<instantiation>:7:11: error: expected an immediate
 ori $26, r4k_wait_idle_size - 2
          ^
<instantiation>:10:13: error: expected an immediate
 addiu $26, r4k_wait_exit - r4k_wait_insn + 2
            ^
<instantiation>:10:29: error: expected an immediate
 addiu $26, r4k_wait_exit - r4k_wait_insn + 2
                            ^

## Build mips
* Build log: https://qa-reports.linaro.org/api/testruns/28410167/log_file/
* Build history:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.12.y/build/v6.12.28-185-gd90d77b7ffdf/testrun/28410167/suite/build/test/clang-20-defconfig/history/
* Build details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.12.y/build/v6.12.28-185-gd90d77b7ffdf/testrun/28410167/suite/build/test/clang-20-defconfig/details/
* Build link: https://storage.tuxsuite.com/public/linaro/lkft/builds/2x0STWrUibOnjQLcSDWp3b7iEHf/
* Kernel config:
https://storage.tuxsuite.com/public/linaro/lkft/builds/2x0STWrUibOnjQLcSDWp3b7iEHf/config
* Toolchain: clang-20

## Build
* kernel: 6.12.29-rc1
* git: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
* git commit: d90d77b7ffdf042185947a9671131e657003287a
* git describe: v6.12.28-185-gd90d77b7ffdf
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.12.y/build/v6.12.28-185-gd90d77b7ffdf

## Test Regressions (compared to v6.12.26-167-g483b39c5e6de)
* mips, build
- clang-20-allnoconfig
- clang-20-defconfig
- clang-20-tinyconfig
- korg-clang-20-lkftconfig-hardening
- korg-clang-20-lkftconfig-lto-full
- korg-clang-20-lkftconfig-lto-thing

## Metric Regressions (compared to v6.12.26-167-g483b39c5e6de)

## Test Fixes (compared to v6.12.26-167-g483b39c5e6de)

## Metric Fixes (compared to v6.12.26-167-g483b39c5e6de)

## Test result summary
total: 148229, pass: 122716, fail: 6415, skip: 18536, xfail: 562

## Build Summary
* arc: 5 total, 5 passed, 0 failed
* arm: 139 total, 137 passed, 2 failed
* arm64: 56 total, 55 passed, 1 failed
* i386: 18 total, 16 passed, 2 failed
* mips: 34 total, 27 passed, 7 failed
* parisc: 4 total, 4 passed, 0 failed
* powerpc: 40 total, 40 passed, 0 failed
* riscv: 25 total, 23 passed, 2 failed
* s390: 22 total, 21 passed, 1 failed
* sh: 5 total, 5 passed, 0 failed
* sparc: 4 total, 3 passed, 1 failed
* x86_64: 49 total, 42 passed, 7 failed

## Test suites summary
* boot
* commands
* kselftest-arm64
* kselftest-breakpoints
* kselftest-capabilities
* kselftest-cgroup
* kselftest-clone3
* kselftest-core
* kselftest-cpu-hotplug
* kselftest-cpufreq
* kselftest-efivarfs
* kselftest-exec
* kselftest-fpu
* kselftest-futex
* kselftest-gpio
* kselftest-intel_pstate
* kselftest-ipc
* kselftest-kcmp
* kselftest-kvm
* kselftest-livepatch
* kselftest-membarrier
* kselftest-memfd
* kselftest-mincore
* kselftest-mm
* kselftest-mqueue
* kselftest-net
* kselftest-net-mptcp
* kselftest-openat2
* kselftest-ptrace
* kselftest-rseq
* kselftest-rtc
* kselftest-seccomp
* kselftest-sigaltstack
* kselftest-size
* kselftest-tc-testing
* kselftest-timers
* kselftest-tmpfs
* kselftest-tpm2
* kselftest-user_events
* kselftest-vDSO
* kselftest-x86
* kunit
* kvm-unit-tests
* lava
* libgpiod
* libhugetlbfs
* log-parser-boot
* log-parser-build-clang
* log-parser-build-gcc
* log-parser-test
* ltp-capability
* ltp-commands
* ltp-containers
* ltp-controllers
* ltp-cpuhotplug
* ltp-crypto
* ltp-cve
* ltp-di[
* ltp-dio
* ltp-fcntl-locktests
* ltp-fs
* ltp-fs_bind
* ltp-fs_perms_simple
* ltp-hugetlb
* ltp-ipc
* ltp-math
* ltp-mm
* ltp-nptl
* ltp-pty
* ltp-sched
* ltp-smoke
* ltp-syscalls
* ltp-tracing
* perf
* rcutorture
* rt-tests-cyclicdeadline
* rt-tests-pi-stress
* rt-tests-pmqtest
* rt-tests-rt-migrate-test
* rt-tests-signaltest

--
Linaro LKFT
https://lkft.linaro.org

Tested-by on the v1 series
#191 lore raw
In reply to Greg Kroah-Hartman

Am 12.05.2025 um 19:43 schrieb Greg Kroah-Hartman:

Quoted 4 lines

This is the start of the stable review cycle for the 6.12.29 release. There are 184 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Builds, boots and works on my 2-socket Ivy Bridge Xeon E5-2697 v2 server. No dmesg oddities or regressions found.

Beste Grüße,
Peter Schneider

Signature · 8 lines
Climb the mountain not to plant your flag, but to embrace the challenge,
enjoy the air and behold the view. Climb it so you can see the world,
not so the world can see you.                    -- David McCullough Jr.

OpenPGP:  0xA3828BD796CCE11A8CADE8866E3A92C92C3FF244
Download: https://www.peters-netzplatz.de/download/pschneider1968_pub.asc
https://keys.mailvelope.com/pks/lookup?op=get&[email protected]
https://keys.mailvelope.com/pks/lookup?op=get&[email protected]
Tested-by on the v1 series
#192 lore raw
In reply to Greg Kroah-Hartman
Quoted 9 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 6.12.29 release. There are 184 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Wed, 14 May 2025 17:19:58 +0000. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

Quoted 9 lines
	https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.12.29-rc1.gz

or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.12.y
and the diffstat can be found below.

thanks,

greg k-h

Compiled and booted on my test system. No dmesg regressions.

thanks,
-- Shuah

Tested-by on the v1 series
#193 lore raw
In reply to Greg Kroah-Hartman

The kernel, bpf tool and perf tool builds fine for v6.12.29-rc1 on x86 and arm64 Azure VM.

KernelCI with LTP and selftest results: Tree: stable/linux-6.12.y <https://dashboard.kernelci.org/tree/f08cdc6cc92e3d23a05745f0f12f8caa348a27b4?o=microsoft&p=t&ti%7Cc=v6.12.28&ti%7Cch=f08cdc6cc92e3d23a05745f0f12f8caa348a27b4&ti%7Cgb=linux-6.12.y&ti%7Cgu=https%3A%2F%2Fgit.kernel.org%2Fpub%2Fscm%2Flinux%2Fkernel%2Fgit%2Fstable%2Flinux.git&ti%7Ct=stable>

Thanks,
Hardik

Quoted 775 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 6.12.29 release. There are 184 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Wed, 14 May 2025 17:19:58 +0000. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

	https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.12.29-rc1.gz

or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.12.y
and the diffstat can be found below.

thanks,

greg k-h

-------------
Pseudo-Shortlog of commits:

Greg Kroah-Hartman <[email protected]>

     Linux 6.12.29-rc1

Pawan Gupta <[email protected]>
selftest/x86/bugs: Add selftests for ITS

Peter Zijlstra <[email protected]>
x86/its: Use dynamic thunks for indirect branches

Pawan Gupta <[email protected]>
x86/ibt: Keep IBT disabled during alternative patching

Pawan Gupta <[email protected]>
x86/its: Align RETs in BHB clear sequence to avoid thunking

Pawan Gupta <[email protected]>
x86/its: Add support for RSB stuffing mitigation

Pawan Gupta <[email protected]>
x86/its: Add "vmexit" option to skip mitigation on some CPUs

Pawan Gupta <[email protected]>
x86/its: Enable Indirect Target Selection mitigation

Pawan Gupta <[email protected]>
x86/its: Add support for ITS-safe return thunk

Pawan Gupta <[email protected]>
x86/its: Add support for ITS-safe indirect thunk

Pawan Gupta <[email protected]>
x86/its: Enumerate Indirect Target Selection (ITS) bug

Pawan Gupta <[email protected]>
Documentation: x86/bugs/its: Add ITS documentation

Pawan Gupta <[email protected]>
x86/speculation: Remove the extra #ifdef around CALL_NOSPEC

Pawan Gupta <[email protected]>
x86/speculation: Add a conditional CS prefix to CALL_NOSPEC

Pawan Gupta <[email protected]>
x86/speculation: Simplify and make CALL_NOSPEC consistent

Pawan Gupta <[email protected]>
x86/bhi: Do not set BHI_DIS_S in 32-bit mode

Daniel Sneddon <[email protected]>
x86/bpf: Add IBHF call at end of classic BPF

Daniel Sneddon <[email protected]>
x86/bpf: Call branch history clearing sequence on exit

James Morse <[email protected]>
arm64: proton-pack: Add new CPUs 'k' values for branch mitigation

James Morse <[email protected]>
arm64: bpf: Only mitigate cBPF programs loaded by unprivileged users

James Morse <[email protected]>
arm64: bpf: Add BHB mitigation to the epilogue for cBPF programs

James Morse <[email protected]>
arm64: proton-pack: Expose whether the branchy loop k value

James Morse <[email protected]>
arm64: proton-pack: Expose whether the platform is mitigated by firmware

James Morse <[email protected]>
arm64: insn: Add support for encoding DSB

Omar Sandoval <[email protected]>

     sched/eevdf: Fix se->slice being set to U64_MAX and resulting crash

Johannes Weiner <[email protected]>
mm: page_alloc: speed up fallbacks in rmqueue_bulk()

Johannes Weiner <[email protected]>
mm: page_alloc: don't steal single pages from biggest buddy

Hao Qin <[email protected]>
Bluetooth: btmtk: Remove the resetting step before downloading the fw

Hao Qin <[email protected]>
Bluetooth: btmtk: Remove resetting mt7921 before downloading the fw

Jens Axboe <[email protected]>
io_uring: always arm linked timeouts prior to issue

Miguel Ojeda <[email protected]>
rust: clean Rust 1.88.0's clippy::uninlined_format_args lint

Miguel Ojeda <[email protected]>

     rust: allow Rust 1.87.0's `clippy::ptr_eq` lint

Christian Lamparter <[email protected]>
Revert "um: work around sched_yield not yielding in time-travel mode"

Al Viro <[email protected]>
do_umount(): add missing barrier before refcount checks in sync case

Gabriel Krisman Bertazi <[email protected]>
io_uring/sqpoll: Increase task_work submission batch size

Tejas Upadhyay <[email protected]>
drm/xe/tests/mocs: Hold XE_FORCEWAKE_ALL for LNCF regs

Himal Prasad Ghimiray <[email protected]>
drm/xe/tests/mocs: Update xe_force_wake_get() return handling

Clément Léger <[email protected]>
riscv: misaligned: enable IRQs while handling misaligned accesses

Clément Léger <[email protected]>
riscv: misaligned: factorize trap handling

Daniel Wagner <[email protected]>
nvme: unblock ctrl state transition for firmware update

Kevin Baker <[email protected]>
drm/panel: simple: Update timings for AUO G101EVN010

Lizhi Xu <[email protected]>
loop: Add sanity check for read/write_iter

Christoph Hellwig <[email protected]>
loop: factor out a loop_assign_backing_file helper

Christoph Hellwig <[email protected]>
loop: refactor queue limits updates

OGAWA Hirofumi <[email protected]>
loop: Fix ABBA locking race

John Garry <[email protected]>
loop: Simplify discard granularity calc

John Garry <[email protected]>
loop: Use bdev limit helpers for configuring discard

Nylon Chen <[email protected]>
riscv: misaligned: Add handling for ZCB instructions

Thorsten Blum <[email protected]>
MIPS: Fix MAX_REG_OFFSET

Marco Crivellari <[email protected]>
MIPS: Move r4k_wait() to .cpuidle.text section

Marco Crivellari <[email protected]>
MIPS: Fix idle VS timer enqueue

Jonathan Cameron <[email protected]>
iio: adc: dln2: Use aligned_s64 for timestamp

Jonathan Cameron <[email protected]>
iio: accel: adxl355: Make timestamp 64-bit aligned using aligned_s64

Andy Shevchenko <[email protected]>
types: Complement the aligned types with signed 64-bit one

Jonathan Cameron <[email protected]>
iio: temp: maxim-thermocouple: Fix potential lack of DMA safe buffer.

Lothar Rubusch <[email protected]>
iio: accel: adxl367: fix setting odr for activity time update

Dave Penkler <[email protected]>
usb: usbtmc: Fix erroneous generic_read ioctl return

Dave Penkler <[email protected]>
usb: usbtmc: Fix erroneous wait_srq ioctl return

Dave Penkler <[email protected]>
usb: usbtmc: Fix erroneous get_stb ioctl error returns

Oliver Neukum <[email protected]>
USB: usbtmc: use interruptible sleep in usbtmc_read

Andrei Kuchynski <[email protected]>
usb: typec: ucsi: displayport: Fix NULL pointer access

RD Babiera <[email protected]>
usb: typec: tcpm: delay SNK_TRY_WAIT_DEBOUNCE to SRC_TRYWAIT transition

Lukasz Czechowski <[email protected]>
usb: misc: onboard_usb_dev: fix support for Cypress HX3 hubs

Jim Lin <[email protected]>
usb: host: tegra: Prevent host controller crash when OTG port is used

Prashanth K <[email protected]>
usb: gadget: Use get_status callback to set remote wakeup capability

Wayne Chang <[email protected]>
usb: gadget: tegra-xudc: ACK ST_RC after clearing CTRL_RUN

Prashanth K <[email protected]>
usb: gadget: f_ecm: Add get_status callback

Pawel Laszczak <[email protected]>
usb: cdnsp: fix L1 resume issue for RTL_REVISION_NEW_LPM version

Pawel Laszczak <[email protected]>
usb: cdnsp: Fix issue with resuming from L1

Prashanth K <[email protected]>
usb: dwc3: gadget: Make gadget_wakeup asynchronous

Jan Kara <[email protected]>
ocfs2: stop quota recovery before disabling quotas

Jan Kara <[email protected]>
ocfs2: implement handshaking with ocfs2 recovery thread

Jan Kara <[email protected]>

     ocfs2: switch osb->disable_recovery to enum

Heming Zhao <[email protected]>
ocfs2: fix the issue with discontiguous allocation in the global_bitmap

Borislav Petkov (AMD) <[email protected]>
x86/microcode: Consolidate the loader enablement checking

Dmitry Antipov <[email protected]>
module: ensure that kobject_put() is safe for module type kobjects

Tom Lendacky <[email protected]>
memblock: Accept allocated memory before use in memblock_double_array()

Sebastian Andrzej Siewior <[email protected]>
clocksource/i8253: Use raw_spinlock_irqsave() in clockevent_i8253_disable()

Yeoreum Yun <[email protected]>
arm64: cpufeature: Move arm64_use_ng_mappings to the .data section to prevent wrong idmap generation

Jacek Lawrynowicz <[email protected]>
accel/ivpu: Increase state dump msg timeout

Jason Andryuk <[email protected]>
xenbus: Use kref to track req lifetime

John Ernberg <[email protected]>
xen: swiotlb: Use swiotlb bouncing if kmalloc allocation demands it

Paul Aurich <[email protected]>
smb: client: Avoid race in open_cached_dir with lease breaks

Alexey Charkov <[email protected]>
usb: uhci-platform: Make the clock really optional

Alex Deucher <[email protected]>
drm/amdgpu/hdp7: use memcfg register to post the write for HDP flush

Alex Deucher <[email protected]>
drm/amdgpu/hdp6: use memcfg register to post the write for HDP flush

Alex Deucher <[email protected]>
drm/amdgpu/hdp5: use memcfg register to post the write for HDP flush

Alex Deucher <[email protected]>
drm/amdgpu/hdp5.2: use memcfg register to post the write for HDP flush

Alex Deucher <[email protected]>
drm/amdgpu/hdp4: use memcfg register to post the write for HDP flush

Wayne Lin <[email protected]>
drm/amd/display: Copy AUX read reply data whenever length > 0

Wayne Lin <[email protected]>
drm/amd/display: Fix wrong handling for AUX_DEFER case

Wayne Lin <[email protected]>
drm/amd/display: Remove incorrect checking in dmub aux handler

Wayne Lin <[email protected]>
drm/amd/display: Fix the checking condition in dmub aux handling

Aurabindo Pillai <[email protected]>
drm/amd/display: more liberal vmin/vmax update for freesync

Roman Li <[email protected]>
drm/amd/display: Fix invalid context error in dml helper

Ruijing Dong <[email protected]>
drm/amdgpu/vcn: using separate VCN1_AON_SOC offset

Matthew Brost <[email protected]>
drm/xe: Add page queue multiplier

Maíra Canal <[email protected]>
drm/v3d: Add job to pending list if the reset was skipped

Silvano Seva <[email protected]>
iio: imu: st_lsm6dsx: fix possible lockup in st_lsm6dsx_read_tagged_fifo

Silvano Seva <[email protected]>
iio: imu: st_lsm6dsx: fix possible lockup in st_lsm6dsx_read_fifo

David Lechner <[email protected]>
iio: imu: inv_mpu6050: align buffer for timestamp

Gabriel Shahrouzi <[email protected]>
iio: adis16201: Correct inclinometer channel resolution

Simon Xue <[email protected]>
iio: adc: rockchip: Fix clock initialization sequence

Angelo Dureghello <[email protected]>
iio: adc: ad7606: fix serial register access

Jens Axboe <[email protected]>
io_uring: ensure deferred completions are flushed for multishot

Wayne Lin <[email protected]>
drm/amd/display: Shift DMUB AUX reply command if necessary

Mikhail Lobanov <[email protected]>
KVM: SVM: Forcibly leave SMM mode on SHUTDOWN interception

Nysal Jan K.A. <[email protected]>
selftests/mm: fix a build failure on powerpc

Feng Tang <[email protected]>
selftests/mm: compaction_test: support platform with huge mount of memory

Peter Xu <[email protected]>
mm/userfaultfd: fix uninitialized output field for -EAGAIN race

Gavin Guo <[email protected]>
mm/huge_memory: fix dereferencing invalid pmd migration entry

Kees Cook <[email protected]>
mm: vmalloc: support more granular vrealloc() sizing

Petr Vaněk <[email protected]>
mm: fix folio_pte_batch() on XEN PV

Dave Hansen <[email protected]>
x86/mm: Eliminate window where TLB flushes may be inadvertently skipped

Gabriel Shahrouzi <[email protected]>
staging: axis-fifo: Correct handling of tx_fifo_depth for size validation

Gabriel Shahrouzi <[email protected]>
staging: axis-fifo: Remove hardware resets for user errors

Dave Stevenson <[email protected]>
staging: bcm2835-camera: Initialise dev in v4l2_dev

Gabriel Shahrouzi <[email protected]>
staging: iio: adc: ad7816: Correct conditional logic for store mode

Miguel Ojeda <[email protected]>
rust: clean Rust 1.88.0's warning about clippy::disallowed_macros configuration

Miguel Ojeda <[email protected]>
objtool/rust: add one more noreturn Rust function for Rust 1.87.0

Miguel Ojeda <[email protected]>
rust: clean Rust 1.88.0's unnecessary_transmutes lint

Aditya Garg <[email protected]>
Input: synaptics - enable InterTouch on TUXEDO InfinityBook Pro 14 v5

Dmitry Torokhov <[email protected]>
Input: synaptics - enable SMBus for HP Elitebook 850 G1

Aditya Garg <[email protected]>
Input: synaptics - enable InterTouch on Dell Precision M3800

Aditya Garg <[email protected]>
Input: synaptics - enable InterTouch on Dynabook Portege X30L-G

Manuel Fombuena <[email protected]>
Input: synaptics - enable InterTouch on Dynabook Portege X30-D

Vicki Pfau <[email protected]>
Input: xpad - fix two controller table values

Lode Willems <[email protected]>
Input: xpad - add support for 8BitDo Ultimate 2 Wireless Controller

Vicki Pfau <[email protected]>
Input: xpad - fix Share button on Xbox One controllers

Gary Bisson <[email protected]>
Input: mtk-pmic-keys - fix possible null pointer dereference

Mikael Gonella-Bolduc <[email protected]>
Input: cyttsp5 - fix power control issue on wakeup

Hugo Villeneuve <[email protected]>
Input: cyttsp5 - ensure minimum reset pulse width

Jakub Kicinski <[email protected]>
virtio-net: fix total qstat values

Jakub Kicinski <[email protected]>
net: export a helper for adding up queue stats

Alexander Duyck <[email protected]>
fbnic: Do not allow mailbox to toggle to ready outside fbnic_mbx_poll_tx_ready

Alexander Duyck <[email protected]>
fbnic: Pull fbnic_fw_xmit_cap_msg use out of interrupt context

Alexander Duyck <[email protected]>
fbnic: Improve responsiveness of fbnic_mbx_poll_tx_ready

Alexander Duyck <[email protected]>
fbnic: Actually flush_tx instead of stalling out

Alexander Duyck <[email protected]>
fbnic: Gate AXI read/write enabling on FW mailbox

Alexander Duyck <[email protected]>
fbnic: Fix initialization of mailbox descriptor rings

Jonas Gorski <[email protected]>
net: dsa: b53: do not set learning and unicast/multicast on up

Jonas Gorski <[email protected]>
net: dsa: b53: fix learning on VLAN unaware bridges

Jonas Gorski <[email protected]>
net: dsa: b53: fix toggling vlan_filtering

Jonas Gorski <[email protected]>
net: dsa: b53: do not program vlans when vlan filtering is off

Jonas Gorski <[email protected]>
net: dsa: b53: do not allow to configure VLAN 0

Jonas Gorski <[email protected]>
net: dsa: b53: always rejoin default untagged VLAN on bridge leave

Jonas Gorski <[email protected]>
net: dsa: b53: fix VLAN ID for untagged vlan on bridge leave

Jonas Gorski <[email protected]>
net: dsa: b53: fix flushing old pvid VLAN on pvid change

Jonas Gorski <[email protected]>
net: dsa: b53: fix clearing PVID of a port

Jonas Gorski <[email protected]>
net: dsa: b53: keep CPU port always tagged again

Jonas Gorski <[email protected]>
net: dsa: b53: allow leaky reserved multicast

Paul Chaignon <[email protected]>
bpf: Scrub packet on bpf_redirect_peer

Jozsef Kadlecsik <[email protected]>
netfilter: ipset: fix region locking in hash types

Julian Anastasov <[email protected]>
ipvs: fix uninit-value for saddr in do_output_route4

Gao Xiang <[email protected]>
erofs: ensure the extra temporary copy is valid for shortened bvecs

Przemek Kitszel <[email protected]>
ice: use DSN instead of PCI BDF for ice_adapter index

Sergey Temerkhanov <[email protected]>
ice: Initial support for E825C hardware in ice_adapter

Michael-CY Lee <[email protected]>
wifi: mac80211: fix the type of status_code for negotiated TID to Link Mapping

Oliver Hartkopp <[email protected]>
can: gw: fix RCU/BH usage in cgw_create_job()

Kelsey Maes <[email protected]>
can: mcp251xfd: fix TDC setting for low data bit rates

Antonios Salios <[email protected]>
can: m_can: m_can_class_allocate_dev(): initialize spin lock on device probe

Frank Wunderlich <[email protected]>
net: ethernet: mtk_eth_soc: do not reset PSE when setting FE

Daniel Golle <[email protected]>
net: ethernet: mtk_eth_soc: reset all TX queues on DMA free

Guillaume Nault <[email protected]>
gre: Fix again IPv6 link-local address generation.

Jakub Kicinski <[email protected]>
virtio-net: free xsk_buffs on error in virtnet_xsk_pool_enable()

Xuan Zhuo <[email protected]>
virtio_net: xsk: bind/unbind xsk for tx

Cong Wang <[email protected]>
sch_htb: make htb_deactivate() idempotent

Heiko Carstens <[email protected]>
s390/entry: Fix last breaking event handling in case of stack corruption

Wang Zhaolong <[email protected]>
ksmbd: fix memory leak in parse_lease_state()

Eelco Chaudron <[email protected]>
openvswitch: Fix unsafe attribute parsing in output_userspace()

Sean Heelan <[email protected]>
ksmbd: Fix UAF in __close_file_table_ids

Norbert Szetei <[email protected]>
ksmbd: prevent out-of-bounds stream writes by validating *pos

Namjae Jeon <[email protected]>
ksmbd: prevent rename with empty string

Marc Kleine-Budde <[email protected]>
can: rockchip_canfd: rkcanfd_remove(): fix order of unregistration calls

Marc Kleine-Budde <[email protected]>
can: mcp251xfd: mcp251xfd_remove(): fix order of unregistration calls

Niklas Schnelle <[email protected]>
s390/pci: Fix duplicate pci_dev_put() in disable_slot() when PF has child VFs

Alex Williamson <[email protected]>
vfio/pci: Align huge faults to order

Veerendranath Jakkam <[email protected]>
wifi: cfg80211: fix out-of-bounds access during multi-link element defragmentation

Niklas Schnelle <[email protected]>
s390/pci: Fix missing check for zpci_create_device() error return

Marc Kleine-Budde <[email protected]>
can: mcan: m_can_class_unregister(): fix order of unregistration calls

Cristian Marussi <[email protected]>
firmware: arm_scmi: Fix timeout checks on polling path

Wojciech Dubowik <[email protected]>
arm64: dts: imx8mm-verdin: Link reg_usdhc2_vqmmc to usdhc2

Qu Wenruo <[email protected]>
Revert "btrfs: canonicalize the device path before adding it"

Max Kellermann <[email protected]>
fs/erofs/fileio: call erofs_onlinefolio_split() after bio_add_folio()

Dan Carpenter <[email protected]>
dm: add missing unlock on in dm_keyslot_evict()

-------------

Diffstat:

  .clippy.toml                                       |   2 +-
  Documentation/ABI/testing/sysfs-devices-system-cpu |   1 +
  Documentation/admin-guide/hw-vuln/index.rst        |   1 +
  .../hw-vuln/indirect-target-selection.rst          | 168 ++++++++++++++++
  Documentation/admin-guide/kernel-parameters.txt    |  18 ++
  Makefile                                           |   4 +-
  arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi   |  25 ++-
  arch/arm64/include/asm/cputype.h                   |   2 +
  arch/arm64/include/asm/insn.h                      |   1 +
  arch/arm64/include/asm/spectre.h                   |   3 +
  arch/arm64/kernel/cpufeature.c                     |   9 +-
  arch/arm64/kernel/proton-pack.c                    |  13 +-
  arch/arm64/lib/insn.c                              |  76 +++++---
  arch/arm64/net/bpf_jit_comp.c                      |  57 +++++-
  arch/mips/include/asm/idle.h                       |   3 +-
  arch/mips/include/asm/ptrace.h                     |   3 +-
  arch/mips/kernel/genex.S                           |  63 +++---
  arch/mips/kernel/idle.c                            |   7 -
  arch/riscv/kernel/traps.c                          |  64 ++++---
  arch/riscv/kernel/traps_misaligned.c               |  17 ++
  arch/s390/kernel/entry.S                           |   3 +-
  arch/s390/pci/pci_clp.c                            |   2 +
  arch/um/include/linux/time-internal.h              |   2 -
  arch/um/kernel/skas/syscall.c                      |  11 --
  arch/x86/Kconfig                                   |  12 ++
  arch/x86/entry/entry_64.S                          |  20 +-
  arch/x86/include/asm/alternative.h                 |  24 +++
  arch/x86/include/asm/cpufeatures.h                 |   3 +
  arch/x86/include/asm/microcode.h                   |   2 +
  arch/x86/include/asm/msr-index.h                   |   8 +
  arch/x86/include/asm/nospec-branch.h               |  38 ++--
  arch/x86/kernel/alternative.c                      | 195 ++++++++++++++++++-
  arch/x86/kernel/cpu/bugs.c                         | 176 ++++++++++++++++-
  arch/x86/kernel/cpu/common.c                       |  72 +++++--
  arch/x86/kernel/cpu/microcode/amd.c                |   6 +-
  arch/x86/kernel/cpu/microcode/core.c               |  60 +++---
  arch/x86/kernel/cpu/microcode/intel.c              |   2 +-
  arch/x86/kernel/cpu/microcode/internal.h           |   1 -
  arch/x86/kernel/ftrace.c                           |   2 +-
  arch/x86/kernel/head32.c                           |   4 -
  arch/x86/kernel/module.c                           |   6 +
  arch/x86/kernel/static_call.c                      |   4 +-
  arch/x86/kernel/vmlinux.lds.S                      |  10 +
  arch/x86/kvm/smm.c                                 |   1 +
  arch/x86/kvm/svm/svm.c                             |   4 +
  arch/x86/kvm/x86.c                                 |   4 +-
  arch/x86/lib/retpoline.S                           |  39 ++++
  arch/x86/mm/tlb.c                                  |  23 ++-
  arch/x86/net/bpf_jit_comp.c                        |  58 +++++-
  drivers/accel/ivpu/ivpu_hw.c                       |   2 +-
  drivers/base/cpu.c                                 |   3 +
  drivers/block/loop.c                               | 104 ++++++----
  drivers/bluetooth/btmtk.c                          |  12 +-
  drivers/clocksource/i8253.c                        |   4 +-
  drivers/firmware/arm_scmi/driver.c                 |  13 +-
  drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h            |   1 -
  drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c              |   7 +-
  drivers/gpu/drm/amd/amdgpu/hdp_v5_0.c              |   7 +-
  drivers/gpu/drm/amd/amdgpu/hdp_v5_2.c              |  12 +-
  drivers/gpu/drm/amd/amdgpu/hdp_v6_0.c              |   7 +-
  drivers/gpu/drm/amd/amdgpu/hdp_v7_0.c              |   7 +-
  drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c              |   1 +
  drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c              |   1 +
  drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c              |   1 +
  drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c              |   4 +-
  drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c            |   1 +
  drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c            |   1 +
  drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c            |   3 +-
  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |  36 ++--
  .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c    |  28 ++-
  .../amd/display/dc/dml2/dml2_translation_helper.c  |  14 +-
  drivers/gpu/drm/panel/panel-simple.c               |  25 +--
  drivers/gpu/drm/v3d/v3d_sched.c                    |  28 ++-
  drivers/gpu/drm/xe/tests/xe_mocs.c                 |  21 +-
  drivers/gpu/drm/xe/xe_gt_pagefault.c               |  11 +-
  drivers/iio/accel/adis16201.c                      |   4 +-
  drivers/iio/accel/adxl355_core.c                   |   2 +-
  drivers/iio/accel/adxl367.c                        |  10 +-
  drivers/iio/adc/ad7606_spi.c                       |   2 +-
  drivers/iio/adc/dln2-adc.c                         |   2 +-
  drivers/iio/adc/rockchip_saradc.c                  |  17 +-
  drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c         |   2 +-
  drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c     |   6 +
  drivers/iio/temperature/maxim_thermocouple.c       |   2 +-
  drivers/input/joystick/xpad.c                      |  40 ++--
  drivers/input/keyboard/mtk-pmic-keys.c             |   4 +-
  drivers/input/mouse/synaptics.c                    |   5 +
  drivers/input/touchscreen/cyttsp5.c                |   7 +-
  drivers/md/dm-table.c                              |   3 +-
  drivers/net/can/m_can/m_can.c                      |   3 +-
  drivers/net/can/rockchip/rockchip_canfd-core.c     |   2 +-
  drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c     |  42 +++-
  drivers/net/dsa/b53/b53_common.c                   | 213 +++++++++++++++------
  drivers/net/dsa/b53/b53_priv.h                     |   3 +
  drivers/net/dsa/bcm_sf2.c                          |   1 +
  drivers/net/ethernet/intel/ice/ice_adapter.c       |  39 ++--
  drivers/net/ethernet/intel/ice/ice_adapter.h       |   6 +-
  drivers/net/ethernet/mediatek/mtk_eth_soc.c        |  19 +-
  drivers/net/ethernet/meta/fbnic/fbnic_csr.h        |   2 +
  drivers/net/ethernet/meta/fbnic/fbnic_fw.c         | 180 +++++++++--------
  drivers/net/ethernet/meta/fbnic/fbnic_mac.c        |   6 -
  drivers/net/virtio_net.c                           |  61 ++++++
  drivers/nvme/host/core.c                           |   3 +-
  drivers/pci/hotplug/s390_pci_hpc.c                 |   1 -
  drivers/staging/axis-fifo/axis-fifo.c              |  14 +-
  drivers/staging/iio/adc/ad7816.c                   |   2 +-
  .../vc04_services/bcm2835-camera/bcm2835-camera.c  |   1 +
  drivers/usb/cdns3/cdnsp-gadget.c                   |  31 +++
  drivers/usb/cdns3/cdnsp-gadget.h                   |   6 +
  drivers/usb/cdns3/cdnsp-pci.c                      |  12 +-
  drivers/usb/cdns3/cdnsp-ring.c                     |   3 +-
  drivers/usb/cdns3/core.h                           |   3 +
  drivers/usb/class/usbtmc.c                         |  59 +++---
  drivers/usb/dwc3/core.h                            |   4 +
  drivers/usb/dwc3/gadget.c                          |  60 +++---
  drivers/usb/gadget/composite.c                     |  12 +-
  drivers/usb/gadget/function/f_ecm.c                |   7 +
  drivers/usb/gadget/udc/tegra-xudc.c                |   4 +
  drivers/usb/host/uhci-platform.c                   |   2 +-
  drivers/usb/host/xhci-tegra.c                      |   3 +
  drivers/usb/misc/onboard_usb_dev.c                 |  10 +-
  drivers/usb/typec/tcpm/tcpm.c                      |   2 +-
  drivers/usb/typec/ucsi/displayport.c               |   2 +
  drivers/vfio/pci/vfio_pci_core.c                   |  12 +-
  drivers/xen/swiotlb-xen.c                          |   1 +
  drivers/xen/xenbus/xenbus.h                        |   2 +
  drivers/xen/xenbus/xenbus_comms.c                  |   9 +-
  drivers/xen/xenbus/xenbus_dev_frontend.c           |   2 +-
  drivers/xen/xenbus/xenbus_xs.c                     |  18 +-
  fs/btrfs/volumes.c                                 |  91 +--------
  fs/erofs/fileio.c                                  |   4 +-
  fs/erofs/zdata.c                                   |  29 ++-
  fs/namespace.c                                     |   3 +-
  fs/ocfs2/journal.c                                 |  80 +++++---
  fs/ocfs2/journal.h                                 |   1 +
  fs/ocfs2/ocfs2.h                                   |  17 +-
  fs/ocfs2/quota_local.c                             |   9 +-
  fs/ocfs2/suballoc.c                                |  38 +++-
  fs/ocfs2/suballoc.h                                |   1 +
  fs/ocfs2/super.c                                   |   3 +
  fs/smb/client/cached_dir.c                         |  10 +-
  fs/smb/server/oplock.c                             |   7 +-
  fs/smb/server/smb2pdu.c                            |   5 +
  fs/smb/server/vfs.c                                |   7 +
  fs/smb/server/vfs_cache.c                          |  33 +++-
  fs/userfaultfd.c                                   |  28 ++-
  include/linux/cpu.h                                |   2 +
  include/linux/execmem.h                            |   3 +
  include/linux/ieee80211.h                          |   2 +-
  include/linux/module.h                             |   5 +
  include/linux/types.h                              |   3 +-
  include/linux/vmalloc.h                            |   1 +
  include/net/netdev_queues.h                        |   6 +
  include/uapi/linux/types.h                         |   1 +
  init/Kconfig                                       |   3 +
  io_uring/io_uring.c                                |  58 +++---
  io_uring/sqpoll.c                                  |   2 +-
  kernel/params.c                                    |   4 +-
  kernel/sched/fair.c                                |   4 +-
  mm/huge_memory.c                                   |  11 +-
  mm/internal.h                                      |  27 ++-
  mm/memblock.c                                      |   9 +-
  mm/page_alloc.c                                    | 159 +++++++++------
  mm/vmalloc.c                                       |  31 ++-
  net/can/gw.c                                       | 151 +++++++++------
  net/core/filter.c                                  |   1 +
  net/core/netdev-genl.c                             |  69 +++++--
  net/ipv6/addrconf.c                                |  15 +-
  net/mac80211/mlme.c                                |  12 +-
  net/netfilter/ipset/ip_set_hash_gen.h              |   2 +-
  net/netfilter/ipvs/ip_vs_xmit.c                    |  27 +--
  net/openvswitch/actions.c                          |   3 +-
  net/sched/sch_htb.c                                |  15 +-
  net/wireless/scan.c                                |   2 +-
  rust/bindings/lib.rs                               |   1 +
  rust/kernel/alloc/kvec.rs                          |   3 +
  rust/kernel/list.rs                                |   3 +
  rust/kernel/str.rs                                 |  46 ++---
  rust/macros/module.rs                              |  19 +-
  rust/macros/pinned_drop.rs                         |   3 +-
  rust/uapi/lib.rs                                   |   1 +
  tools/objtool/check.c                              |   1 +
  tools/testing/selftests/Makefile                   |   1 +
  tools/testing/selftests/mm/compaction_test.c       |  19 +-
  tools/testing/selftests/mm/pkey-powerpc.h          |  12 +-
  tools/testing/selftests/x86/bugs/Makefile          |   3 +
  tools/testing/selftests/x86/bugs/common.py         | 164 ++++++++++++++++
  .../selftests/x86/bugs/its_indirect_alignment.py   | 150 +++++++++++++++
  .../testing/selftests/x86/bugs/its_permutations.py | 109 +++++++++++
  .../selftests/x86/bugs/its_ret_alignment.py        | 139 ++++++++++++++
  tools/testing/selftests/x86/bugs/its_sysfs.py      |  65 +++++++
  191 files changed, 3250 insertions(+), 1134 deletions(-)