From: Sasha Levin Date: Sun, 18 May 2025 10:30:31 +0000 (-0400) Subject: Fixes for 6.6 X-Git-Tag: v5.15.184~60 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=888ae48d8a7efa4c0ee954a5dd58bb532619e764;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.6 Signed-off-by: Sasha Levin --- diff --git a/queue-6.6/alsa-seq-fix-delivery-of-ump-events-to-group-ports.patch b/queue-6.6/alsa-seq-fix-delivery-of-ump-events-to-group-ports.patch new file mode 100644 index 0000000000..d8157fd4b9 --- /dev/null +++ b/queue-6.6/alsa-seq-fix-delivery-of-ump-events-to-group-ports.patch @@ -0,0 +1,158 @@ +From b694a4f885f301931446467ae2667560b52a0aea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 11 May 2025 15:45:27 +0200 +Subject: ALSA: seq: Fix delivery of UMP events to group ports + +From: Takashi Iwai + +[ Upstream commit ff7b190aef6cccdb6f14d20c5753081fe6420e0b ] + +When an event with UMP message is sent to a UMP client, the EP port +receives always no matter where the event is sent to, as it's a +catch-all port. OTOH, if an event is sent to EP port, and if the +event has a certain UMP Group, it should have been delivered to the +associated UMP Group port, too, but this was ignored, so far. + +This patch addresses the behavior. Now a UMP event sent to the +Endpoint port will be delivered to the subscribers of the UMP group +port the event is associated with. + +The patch also does a bit of refactoring to simplify the code about +__deliver_to_subscribers(). + +Fixes: 177ccf811df4 ("ALSA: seq: Support MIDI 2.0 UMP Endpoint port") +Link: https://patch.msgid.link/20250511134528.6314-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/core/seq/seq_clientmgr.c | 52 ++++++++++++++++++++------------ + sound/core/seq/seq_ump_convert.c | 18 +++++++++++ + sound/core/seq/seq_ump_convert.h | 1 + + 3 files changed, 52 insertions(+), 19 deletions(-) + +diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c +index 6195fe9dda179..49f6763c3250d 100644 +--- a/sound/core/seq/seq_clientmgr.c ++++ b/sound/core/seq/seq_clientmgr.c +@@ -736,15 +736,21 @@ static int snd_seq_deliver_single_event(struct snd_seq_client *client, + */ + static int __deliver_to_subscribers(struct snd_seq_client *client, + struct snd_seq_event *event, +- struct snd_seq_client_port *src_port, +- int atomic, int hop) ++ int port, int atomic, int hop) + { ++ struct snd_seq_client_port *src_port; + struct snd_seq_subscribers *subs; + int err, result = 0, num_ev = 0; + union __snd_seq_event event_saved; + size_t saved_size; + struct snd_seq_port_subs_info *grp; + ++ if (port < 0) ++ return 0; ++ src_port = snd_seq_port_use_ptr(client, port); ++ if (!src_port) ++ return 0; ++ + /* save original event record */ + saved_size = snd_seq_event_packet_size(event); + memcpy(&event_saved, event, saved_size); +@@ -780,6 +786,7 @@ static int __deliver_to_subscribers(struct snd_seq_client *client, + read_unlock(&grp->list_lock); + else + up_read(&grp->list_mutex); ++ snd_seq_port_unlock(src_port); + memcpy(event, &event_saved, saved_size); + return (result < 0) ? result : num_ev; + } +@@ -788,25 +795,32 @@ static int deliver_to_subscribers(struct snd_seq_client *client, + struct snd_seq_event *event, + int atomic, int hop) + { +- struct snd_seq_client_port *src_port; +- int ret = 0, ret2; +- +- src_port = snd_seq_port_use_ptr(client, event->source.port); +- if (src_port) { +- ret = __deliver_to_subscribers(client, event, src_port, atomic, hop); +- snd_seq_port_unlock(src_port); +- } +- +- if (client->ump_endpoint_port < 0 || +- event->source.port == client->ump_endpoint_port) +- return ret; ++ int ret; ++#if IS_ENABLED(CONFIG_SND_SEQ_UMP) ++ int ret2; ++#endif + +- src_port = snd_seq_port_use_ptr(client, client->ump_endpoint_port); +- if (!src_port) ++ ret = __deliver_to_subscribers(client, event, ++ event->source.port, atomic, hop); ++#if IS_ENABLED(CONFIG_SND_SEQ_UMP) ++ if (!snd_seq_client_is_ump(client) || client->ump_endpoint_port < 0) + return ret; +- ret2 = __deliver_to_subscribers(client, event, src_port, atomic, hop); +- snd_seq_port_unlock(src_port); +- return ret2 < 0 ? ret2 : ret; ++ /* If it's an event from EP port (and with a UMP group), ++ * deliver to subscribers of the corresponding UMP group port, too. ++ * Or, if it's from non-EP port, deliver to subscribers of EP port, too. ++ */ ++ if (event->source.port == client->ump_endpoint_port) ++ ret2 = __deliver_to_subscribers(client, event, ++ snd_seq_ump_group_port(event), ++ atomic, hop); ++ else ++ ret2 = __deliver_to_subscribers(client, event, ++ client->ump_endpoint_port, ++ atomic, hop); ++ if (ret2 < 0) ++ return ret2; ++#endif ++ return ret; + } + + /* deliver an event to the destination port(s). +diff --git a/sound/core/seq/seq_ump_convert.c b/sound/core/seq/seq_ump_convert.c +index 4dd540cbb1cbb..83a27362b7a06 100644 +--- a/sound/core/seq/seq_ump_convert.c ++++ b/sound/core/seq/seq_ump_convert.c +@@ -1284,3 +1284,21 @@ int snd_seq_deliver_to_ump(struct snd_seq_client *source, + else + return cvt_to_ump_midi1(dest, dest_port, event, atomic, hop); + } ++ ++/* return the UMP group-port number of the event; ++ * return -1 if groupless or non-UMP event ++ */ ++int snd_seq_ump_group_port(const struct snd_seq_event *event) ++{ ++ const struct snd_seq_ump_event *ump_ev = ++ (const struct snd_seq_ump_event *)event; ++ unsigned char type; ++ ++ if (!snd_seq_ev_is_ump(event)) ++ return -1; ++ type = ump_message_type(ump_ev->ump[0]); ++ if (ump_is_groupless_msg(type)) ++ return -1; ++ /* group-port number starts from 1 */ ++ return ump_message_group(ump_ev->ump[0]) + 1; ++} +diff --git a/sound/core/seq/seq_ump_convert.h b/sound/core/seq/seq_ump_convert.h +index 6c146d8032804..4abf0a7637d70 100644 +--- a/sound/core/seq/seq_ump_convert.h ++++ b/sound/core/seq/seq_ump_convert.h +@@ -18,5 +18,6 @@ int snd_seq_deliver_to_ump(struct snd_seq_client *source, + struct snd_seq_client_port *dest_port, + struct snd_seq_event *event, + int atomic, int hop); ++int snd_seq_ump_group_port(const struct snd_seq_event *event); + + #endif /* __SEQ_UMP_CONVERT_H */ +-- +2.39.5 + diff --git a/queue-6.6/alsa-sh-snd_aica-should-depend-on-sh_dma_api.patch b/queue-6.6/alsa-sh-snd_aica-should-depend-on-sh_dma_api.patch new file mode 100644 index 0000000000..37f0070079 --- /dev/null +++ b/queue-6.6/alsa-sh-snd_aica-should-depend-on-sh_dma_api.patch @@ -0,0 +1,46 @@ +From 0fbf54024841ac567bf3b59bdc3fd3dff97eb710 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 May 2025 09:31:04 +0200 +Subject: ALSA: sh: SND_AICA should depend on SH_DMA_API + +From: Geert Uytterhoeven + +[ Upstream commit 66e48ef6ef506c89ec1b3851c6f9f5f80b5835ff ] + +If CONFIG_SH_DMA_API=n: + + WARNING: unmet direct dependencies detected for G2_DMA + Depends on [n]: SH_DREAMCAST [=y] && SH_DMA_API [=n] + Selected by [y]: + - SND_AICA [=y] && SOUND [=y] && SND [=y] && SND_SUPERH [=y] && SH_DREAMCAST [=y] + +SND_AICA selects G2_DMA. As the latter depends on SH_DMA_API, the +former should depend on SH_DMA_API, too. + +Fixes: f477a538c14d07f8 ("sh: dma: fix kconfig dependency for G2_DMA") +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202505131320.PzgTtl9H-lkp@intel.com/ +Signed-off-by: Geert Uytterhoeven +Link: https://patch.msgid.link/b90625f8a9078d0d304bafe862cbe3a3fab40082.1747121335.git.geert+renesas@glider.be +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/sh/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/sh/Kconfig b/sound/sh/Kconfig +index b75fbb3236a7b..f5fa09d740b4c 100644 +--- a/sound/sh/Kconfig ++++ b/sound/sh/Kconfig +@@ -14,7 +14,7 @@ if SND_SUPERH + + config SND_AICA + tristate "Dreamcast Yamaha AICA sound" +- depends on SH_DREAMCAST ++ depends on SH_DREAMCAST && SH_DMA_API + select SND_PCM + select G2_DMA + help +-- +2.39.5 + diff --git a/queue-6.6/alsa-ump-fix-a-typo-of-snd_ump_stream_msg_device_inf.patch b/queue-6.6/alsa-ump-fix-a-typo-of-snd_ump_stream_msg_device_inf.patch new file mode 100644 index 0000000000..375f7f540b --- /dev/null +++ b/queue-6.6/alsa-ump-fix-a-typo-of-snd_ump_stream_msg_device_inf.patch @@ -0,0 +1,61 @@ +From 41dbe6f82d1295b5b74f7f279c71ec2c1741ac06 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 11 May 2025 16:11:45 +0200 +Subject: ALSA: ump: Fix a typo of snd_ump_stream_msg_device_info + +From: Takashi Iwai + +[ Upstream commit dd33993a9721ab1dae38bd37c9f665987d554239 ] + +s/devince/device/ + +It's used only internally, so no any behavior changes. + +Fixes: 37e0e14128e0 ("ALSA: ump: Support UMP Endpoint and Function Block parsing") +Acked-by: Greg Kroah-Hartman +Link: https://patch.msgid.link/20250511141147.10246-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + drivers/usb/gadget/function/f_midi2.c | 2 +- + include/sound/ump_msg.h | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c +index b7dada064890b..90536f47906c3 100644 +--- a/drivers/usb/gadget/function/f_midi2.c ++++ b/drivers/usb/gadget/function/f_midi2.c +@@ -475,7 +475,7 @@ static void reply_ump_stream_ep_info(struct f_midi2_ep *ep) + /* reply a UMP EP device info */ + static void reply_ump_stream_ep_device(struct f_midi2_ep *ep) + { +- struct snd_ump_stream_msg_devince_info rep = { ++ struct snd_ump_stream_msg_device_info rep = { + .type = UMP_MSG_TYPE_STREAM, + .status = UMP_STREAM_MSG_STATUS_DEVICE_INFO, + .manufacture_id = ep->info.manufacturer, +diff --git a/include/sound/ump_msg.h b/include/sound/ump_msg.h +index 72f60ddfea753..9556b4755a1ed 100644 +--- a/include/sound/ump_msg.h ++++ b/include/sound/ump_msg.h +@@ -604,7 +604,7 @@ struct snd_ump_stream_msg_ep_info { + } __packed; + + /* UMP Stream Message: Device Info Notification (128bit) */ +-struct snd_ump_stream_msg_devince_info { ++struct snd_ump_stream_msg_device_info { + #ifdef __BIG_ENDIAN_BITFIELD + /* 0 */ + u32 type:4; +@@ -754,7 +754,7 @@ struct snd_ump_stream_msg_fb_name { + union snd_ump_stream_msg { + struct snd_ump_stream_msg_ep_discovery ep_discovery; + struct snd_ump_stream_msg_ep_info ep_info; +- struct snd_ump_stream_msg_devince_info device_info; ++ struct snd_ump_stream_msg_device_info device_info; + struct snd_ump_stream_msg_stream_cfg stream_cfg; + struct snd_ump_stream_msg_fb_discovery fb_discovery; + struct snd_ump_stream_msg_fb_info fb_info; +-- +2.39.5 + diff --git a/queue-6.6/binfmt_elf-calculate-total_size-earlier.patch b/queue-6.6/binfmt_elf-calculate-total_size-earlier.patch new file mode 100644 index 0000000000..e3bf4397e0 --- /dev/null +++ b/queue-6.6/binfmt_elf-calculate-total_size-earlier.patch @@ -0,0 +1,97 @@ +From fd0e11608b86b5bcce2fd852c583fe7ec5d13c16 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 May 2024 10:31:47 -0700 +Subject: binfmt_elf: Calculate total_size earlier + +From: Kees Cook + +[ Upstream commit 2d4cf7b190bbfadd4986bf5c34da17c1a88adf8e ] + +In preparation to support PT_LOAD with large p_align values on +non-PT_INTERP ET_DYN executables (i.e. "static pie"), we'll need to use +the total_size details earlier. Move this separately now to make the +next patch more readable. As total_size and load_bias are currently +calculated separately, this has no behavioral impact. + +Link: https://lore.kernel.org/r/20240508173149.677910-2-keescook@chromium.org +Signed-off-by: Kees Cook +Stable-dep-of: 11854fe263eb ("binfmt_elf: Move brk for static PIE even if ASLR disabled") +Signed-off-by: Sasha Levin +--- + fs/binfmt_elf.c | 52 +++++++++++++++++++++++++------------------------ + 1 file changed, 27 insertions(+), 25 deletions(-) + +diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c +index 700d93e73f6e0..58c43a572df8b 100644 +--- a/fs/binfmt_elf.c ++++ b/fs/binfmt_elf.c +@@ -1092,7 +1092,34 @@ static int load_elf_binary(struct linux_binprm *bprm) + * Header for ET_DYN binaries to calculate the + * randomization (load_bias) for all the LOAD + * Program Headers. ++ */ ++ ++ /* ++ * Calculate the entire size of the ELF mapping ++ * (total_size), used for the initial mapping, ++ * due to load_addr_set which is set to true later ++ * once the initial mapping is performed. ++ * ++ * Note that this is only sensible when the LOAD ++ * segments are contiguous (or overlapping). If ++ * used for LOADs that are far apart, this would ++ * cause the holes between LOADs to be mapped, ++ * running the risk of having the mapping fail, ++ * as it would be larger than the ELF file itself. + * ++ * As a result, only ET_DYN does this, since ++ * some ET_EXEC (e.g. ia64) may have large virtual ++ * memory holes between LOADs. ++ * ++ */ ++ total_size = total_mapping_size(elf_phdata, ++ elf_ex->e_phnum); ++ if (!total_size) { ++ retval = -EINVAL; ++ goto out_free_dentry; ++ } ++ ++ /* + * There are effectively two types of ET_DYN + * binaries: programs (i.e. PIE: ET_DYN with INTERP) + * and loaders (ET_DYN without INTERP, since they +@@ -1133,31 +1160,6 @@ static int load_elf_binary(struct linux_binprm *bprm) + * is then page aligned. + */ + load_bias = ELF_PAGESTART(load_bias - vaddr); +- +- /* +- * Calculate the entire size of the ELF mapping +- * (total_size), used for the initial mapping, +- * due to load_addr_set which is set to true later +- * once the initial mapping is performed. +- * +- * Note that this is only sensible when the LOAD +- * segments are contiguous (or overlapping). If +- * used for LOADs that are far apart, this would +- * cause the holes between LOADs to be mapped, +- * running the risk of having the mapping fail, +- * as it would be larger than the ELF file itself. +- * +- * As a result, only ET_DYN does this, since +- * some ET_EXEC (e.g. ia64) may have large virtual +- * memory holes between LOADs. +- * +- */ +- total_size = total_mapping_size(elf_phdata, +- elf_ex->e_phnum); +- if (!total_size) { +- retval = -EINVAL; +- goto out_free_dentry; +- } + } + + error = elf_load(bprm->file, load_bias + vaddr, elf_ppnt, +-- +2.39.5 + diff --git a/queue-6.6/binfmt_elf-elf_bss-no-longer-used-by-load_elf_binary.patch b/queue-6.6/binfmt_elf-elf_bss-no-longer-used-by-load_elf_binary.patch new file mode 100644 index 0000000000..cdf0a38808 --- /dev/null +++ b/queue-6.6/binfmt_elf-elf_bss-no-longer-used-by-load_elf_binary.patch @@ -0,0 +1,70 @@ +From 69e2790a063e5c79c2eb04c09124aedc50bf47b3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Sep 2023 20:24:30 -0700 +Subject: binfmt_elf: elf_bss no longer used by load_elf_binary() + +From: Kees Cook + +[ Upstream commit 8ed2ef21ff564cf4a25c098ace510ee6513c9836 ] + +With the BSS handled generically via the new filesz/memsz mismatch +handling logic in elf_load(), elf_bss no longer needs to be tracked. +Drop the variable. + +Cc: Eric Biederman +Cc: Alexander Viro +Cc: Christian Brauner +Cc: linux-fsdevel@vger.kernel.org +Cc: linux-mm@kvack.org +Suggested-by: Eric Biederman +Tested-by: Pedro Falcato +Signed-off-by: Sebastian Ott +Link: https://lore.kernel.org/r/20230929032435.2391507-2-keescook@chromium.org +Signed-off-by: Kees Cook +Stable-dep-of: 11854fe263eb ("binfmt_elf: Move brk for static PIE even if ASLR disabled") +Signed-off-by: Sasha Levin +--- + fs/binfmt_elf.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c +index d59bca23c4bd9..02258b28e370e 100644 +--- a/fs/binfmt_elf.c ++++ b/fs/binfmt_elf.c +@@ -854,7 +854,7 @@ static int load_elf_binary(struct linux_binprm *bprm) + unsigned long error; + struct elf_phdr *elf_ppnt, *elf_phdata, *interp_elf_phdata = NULL; + struct elf_phdr *elf_property_phdata = NULL; +- unsigned long elf_bss, elf_brk; ++ unsigned long elf_brk; + int retval, i; + unsigned long elf_entry; + unsigned long e_entry; +@@ -1046,7 +1046,6 @@ static int load_elf_binary(struct linux_binprm *bprm) + if (retval < 0) + goto out_free_dentry; + +- elf_bss = 0; + elf_brk = 0; + + start_code = ~0UL; +@@ -1209,8 +1208,6 @@ static int load_elf_binary(struct linux_binprm *bprm) + + k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz; + +- if (k > elf_bss) +- elf_bss = k; + if ((elf_ppnt->p_flags & PF_X) && end_code < k) + end_code = k; + if (end_data < k) +@@ -1222,7 +1219,6 @@ static int load_elf_binary(struct linux_binprm *bprm) + + e_entry = elf_ex->e_entry + load_bias; + phdr_addr += load_bias; +- elf_bss += load_bias; + elf_brk += load_bias; + start_code += load_bias; + end_code += load_bias; +-- +2.39.5 + diff --git a/queue-6.6/binfmt_elf-honor-pt_load-alignment-for-static-pie.patch b/queue-6.6/binfmt_elf-honor-pt_load-alignment-for-static-pie.patch new file mode 100644 index 0000000000..874c198245 --- /dev/null +++ b/queue-6.6/binfmt_elf-honor-pt_load-alignment-for-static-pie.patch @@ -0,0 +1,131 @@ +From c9f4f97744857a9f72b5cf847edea9db09b42a07 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 May 2024 10:31:48 -0700 +Subject: binfmt_elf: Honor PT_LOAD alignment for static PIE + +From: Kees Cook + +[ Upstream commit 3545deff0ec7a37de7ed9632e262598582b140e9 ] + +The p_align values in PT_LOAD were ignored for static PIE executables +(i.e. ET_DYN without PT_INTERP). This is because there is no way to +request a non-fixed mmap region with a specific alignment. ET_DYN with +PT_INTERP uses a separate base address (ELF_ET_DYN_BASE) and binfmt_elf +performs the ASLR itself, which means it can also apply alignment. For +the mmap region, the address selection happens deep within the vm_mmap() +implementation (when the requested address is 0). + +The earlier attempt to implement this: + + commit 9630f0d60fec ("fs/binfmt_elf: use PT_LOAD p_align values for static PIE") + commit 925346c129da ("fs/binfmt_elf: fix PT_LOAD p_align values for loaders") + +did not take into account the different base address origins, and were +eventually reverted: + + aeb7923733d1 ("revert "fs/binfmt_elf: use PT_LOAD p_align values for static PIE"") + +In order to get the correct alignment from an mmap base, binfmt_elf must +perform a 0-address load first, then tear down the mapping and perform +alignment on the resulting address. Since this is slightly more overhead, +only do this when it is needed (i.e. the alignment is not the default +ELF alignment). This does, however, have the benefit of being able to +use MAP_FIXED_NOREPLACE, to avoid potential collisions. + +With this fixed, enable the static PIE self tests again. + +Reported-by: H.J. Lu +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=215275 +Link: https://lore.kernel.org/r/20240508173149.677910-3-keescook@chromium.org +Signed-off-by: Kees Cook +Stable-dep-of: 11854fe263eb ("binfmt_elf: Move brk for static PIE even if ASLR disabled") +Signed-off-by: Sasha Levin +--- + fs/binfmt_elf.c | 42 +++++++++++++++++++++++---- + tools/testing/selftests/exec/Makefile | 2 +- + 2 files changed, 38 insertions(+), 6 deletions(-) + +diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c +index 58c43a572df8b..2fa276e7da1b1 100644 +--- a/fs/binfmt_elf.c ++++ b/fs/binfmt_elf.c +@@ -1119,10 +1119,13 @@ static int load_elf_binary(struct linux_binprm *bprm) + goto out_free_dentry; + } + ++ /* Calculate any requested alignment. */ ++ alignment = maximum_alignment(elf_phdata, elf_ex->e_phnum); ++ + /* + * There are effectively two types of ET_DYN +- * binaries: programs (i.e. PIE: ET_DYN with INTERP) +- * and loaders (ET_DYN without INTERP, since they ++ * binaries: programs (i.e. PIE: ET_DYN with PT_INTERP) ++ * and loaders (ET_DYN without PT_INTERP, since they + * _are_ the ELF interpreter). The loaders must + * be loaded away from programs since the program + * may otherwise collide with the loader (especially +@@ -1142,15 +1145,44 @@ static int load_elf_binary(struct linux_binprm *bprm) + * without MAP_FIXED nor MAP_FIXED_NOREPLACE). + */ + if (interpreter) { ++ /* On ET_DYN with PT_INTERP, we do the ASLR. */ + load_bias = ELF_ET_DYN_BASE; + if (current->flags & PF_RANDOMIZE) + load_bias += arch_mmap_rnd(); +- alignment = maximum_alignment(elf_phdata, elf_ex->e_phnum); ++ /* Adjust alignment as requested. */ + if (alignment) + load_bias &= ~(alignment - 1); + elf_flags |= MAP_FIXED_NOREPLACE; +- } else +- load_bias = 0; ++ } else { ++ /* ++ * For ET_DYN without PT_INTERP, we rely on ++ * the architectures's (potentially ASLR) mmap ++ * base address (via a load_bias of 0). ++ * ++ * When a large alignment is requested, we ++ * must do the allocation at address "0" right ++ * now to discover where things will load so ++ * that we can adjust the resulting alignment. ++ * In this case (load_bias != 0), we can use ++ * MAP_FIXED_NOREPLACE to make sure the mapping ++ * doesn't collide with anything. ++ */ ++ if (alignment > ELF_MIN_ALIGN) { ++ load_bias = elf_load(bprm->file, 0, elf_ppnt, ++ elf_prot, elf_flags, total_size); ++ if (BAD_ADDR(load_bias)) { ++ retval = IS_ERR_VALUE(load_bias) ? ++ PTR_ERR((void*)load_bias) : -EINVAL; ++ goto out_free_dentry; ++ } ++ vm_munmap(load_bias, total_size); ++ /* Adjust alignment as requested. */ ++ if (alignment) ++ load_bias &= ~(alignment - 1); ++ elf_flags |= MAP_FIXED_NOREPLACE; ++ } else ++ load_bias = 0; ++ } + + /* + * Since load_bias is used for all subsequent loading +diff --git a/tools/testing/selftests/exec/Makefile b/tools/testing/selftests/exec/Makefile +index b54986078d7ea..a705493c04bb7 100644 +--- a/tools/testing/selftests/exec/Makefile ++++ b/tools/testing/selftests/exec/Makefile +@@ -6,7 +6,7 @@ CFLAGS += -D_GNU_SOURCE + ALIGNS := 0x1000 0x200000 0x1000000 + ALIGN_PIES := $(patsubst %,load_address.%,$(ALIGNS)) + ALIGN_STATIC_PIES := $(patsubst %,load_address.static.%,$(ALIGNS)) +-ALIGNMENT_TESTS := $(ALIGN_PIES) ++ALIGNMENT_TESTS := $(ALIGN_PIES) $(ALIGN_STATIC_PIES) + + TEST_PROGS := binfmt_script.py + TEST_GEN_PROGS := execveat non-regular $(ALIGNMENT_TESTS) +-- +2.39.5 + diff --git a/queue-6.6/binfmt_elf-leave-a-gap-between-.bss-and-brk.patch b/queue-6.6/binfmt_elf-leave-a-gap-between-.bss-and-brk.patch new file mode 100644 index 0000000000..468f2e380f --- /dev/null +++ b/queue-6.6/binfmt_elf-leave-a-gap-between-.bss-and-brk.patch @@ -0,0 +1,42 @@ +From f7b0d1cf496fad783b1a83eb3fcbe4ee9a72539f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 16 Feb 2024 22:25:44 -0800 +Subject: binfmt_elf: Leave a gap between .bss and brk + +From: Kees Cook + +[ Upstream commit 2a5eb9995528441447d33838727f6ec1caf08139 ] + +Currently the brk starts its randomization immediately after .bss, +which means there is a chance that when the random offset is 0, linear +overflows from .bss can reach into the brk area. Leave at least a single +page gap between .bss and brk (when it has not already been explicitly +relocated into the mmap range). + +Reported-by: +Closes: https://lore.kernel.org/linux-hardening/CA+2EKTVLvc8hDZc+2Yhwmus=dzOUG5E4gV7ayCbu0MPJTZzWkw@mail.gmail.com/ +Link: https://lore.kernel.org/r/20240217062545.1631668-2-keescook@chromium.org +Signed-off-by: Kees Cook +Stable-dep-of: 11854fe263eb ("binfmt_elf: Move brk for static PIE even if ASLR disabled") +Signed-off-by: Sasha Levin +--- + fs/binfmt_elf.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c +index 02258b28e370e..700d93e73f6e0 100644 +--- a/fs/binfmt_elf.c ++++ b/fs/binfmt_elf.c +@@ -1293,6 +1293,9 @@ static int load_elf_binary(struct linux_binprm *bprm) + if (IS_ENABLED(CONFIG_ARCH_HAS_ELF_RANDOMIZE) && + elf_ex->e_type == ET_DYN && !interpreter) { + mm->brk = mm->start_brk = ELF_ET_DYN_BASE; ++ } else { ++ /* Otherwise leave a gap between .bss and brk. */ ++ mm->brk = mm->start_brk = mm->brk + PAGE_SIZE; + } + + mm->brk = mm->start_brk = arch_randomize_brk(mm); +-- +2.39.5 + diff --git a/queue-6.6/binfmt_elf-move-brk-for-static-pie-even-if-aslr-disa.patch b/queue-6.6/binfmt_elf-move-brk-for-static-pie-even-if-aslr-disa.patch new file mode 100644 index 0000000000..2440e1d680 --- /dev/null +++ b/queue-6.6/binfmt_elf-move-brk-for-static-pie-even-if-aslr-disa.patch @@ -0,0 +1,198 @@ +From aa4e9348c5b91079dc0b3996b99fb74cf5f95c10 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 15:45:06 -0700 +Subject: binfmt_elf: Move brk for static PIE even if ASLR disabled + +From: Kees Cook + +[ Upstream commit 11854fe263eb1b9a8efa33b0c087add7719ea9b4 ] + +In commit bbdc6076d2e5 ("binfmt_elf: move brk out of mmap when doing +direct loader exec"), the brk was moved out of the mmap region when +loading static PIE binaries (ET_DYN without INTERP). The common case +for these binaries was testing new ELF loaders, so the brk needed to +be away from mmap to avoid colliding with stack, future mmaps (of the +loader-loaded binary), etc. But this was only done when ASLR was enabled, +in an attempt to minimize changes to memory layouts. + +After adding support to respect alignment requirements for static PIE +binaries in commit 3545deff0ec7 ("binfmt_elf: Honor PT_LOAD alignment +for static PIE"), it became possible to have a large gap after the +final PT_LOAD segment and the top of the mmap region. This means that +future mmap allocations might go after the last PT_LOAD segment (where +brk might be if ASLR was disabled) instead of before them (where they +traditionally ended up). + +On arm64, running with ASLR disabled, Ubuntu 22.04's "ldconfig" binary, +a static PIE, has alignment requirements that leaves a gap large enough +after the last PT_LOAD segment to fit the vdso and vvar, but still leave +enough space for the brk (which immediately follows the last PT_LOAD +segment) to be allocated by the binary. + +fffff7f20000-fffff7fde000 r-xp 00000000 fe:02 8110426 /sbin/ldconfig.real +fffff7fee000-fffff7ff5000 rw-p 000be000 fe:02 8110426 /sbin/ldconfig.real +fffff7ff5000-fffff7ffa000 rw-p 00000000 00:00 0 +***[brk will go here at fffff7ffa000]*** +fffff7ffc000-fffff7ffe000 r--p 00000000 00:00 0 [vvar] +fffff7ffe000-fffff8000000 r-xp 00000000 00:00 0 [vdso] +fffffffdf000-1000000000000 rw-p 00000000 00:00 0 [stack] + +After commit 0b3bc3354eb9 ("arm64: vdso: Switch to generic storage +implementation"), the arm64 vvar grew slightly, and suddenly the brk +collided with the allocation. + +fffff7f20000-fffff7fde000 r-xp 00000000 fe:02 8110426 /sbin/ldconfig.real +fffff7fee000-fffff7ff5000 rw-p 000be000 fe:02 8110426 /sbin/ldconfig.real +fffff7ff5000-fffff7ffa000 rw-p 00000000 00:00 0 +***[oops, no room any more, vvar is at fffff7ffa000!]*** +fffff7ffa000-fffff7ffe000 r--p 00000000 00:00 0 [vvar] +fffff7ffe000-fffff8000000 r-xp 00000000 00:00 0 [vdso] +fffffffdf000-1000000000000 rw-p 00000000 00:00 0 [stack] + +The solution is to unconditionally move the brk out of the mmap region +for static PIE binaries. Whether ASLR is enabled or not does not change if +there may be future mmap allocation collisions with a growing brk region. + +Update memory layout comments (with kernel-doc headings), consolidate +the setting of mm->brk to later (it isn't needed early), move static PIE +brk out of mmap unconditionally, and make sure brk(2) knows to base brk +position off of mm->start_brk not mm->end_data no matter what the cause of +moving it is (via current->brk_randomized). + +For the CONFIG_COMPAT_BRK case, though, leave the logic unchanged, as we +can never safely move the brk. These systems, however, are not using +specially aligned static PIE binaries. + +Reported-by: Ryan Roberts +Closes: https://lore.kernel.org/lkml/f93db308-4a0e-4806-9faf-98f890f5a5e6@arm.com/ +Fixes: bbdc6076d2e5 ("binfmt_elf: move brk out of mmap when doing direct loader exec") +Link: https://lore.kernel.org/r/20250425224502.work.520-kees@kernel.org +Reviewed-by: Ryan Roberts +Tested-by: Ryan Roberts +Signed-off-by: Kees Cook +Signed-off-by: Sasha Levin +--- + fs/binfmt_elf.c | 71 ++++++++++++++++++++++++++++++++----------------- + 1 file changed, 47 insertions(+), 24 deletions(-) + +diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c +index 2fa276e7da1b1..3ff7d2e47c7e9 100644 +--- a/fs/binfmt_elf.c ++++ b/fs/binfmt_elf.c +@@ -855,6 +855,7 @@ static int load_elf_binary(struct linux_binprm *bprm) + struct elf_phdr *elf_ppnt, *elf_phdata, *interp_elf_phdata = NULL; + struct elf_phdr *elf_property_phdata = NULL; + unsigned long elf_brk; ++ bool brk_moved = false; + int retval, i; + unsigned long elf_entry; + unsigned long e_entry; +@@ -1122,15 +1123,19 @@ static int load_elf_binary(struct linux_binprm *bprm) + /* Calculate any requested alignment. */ + alignment = maximum_alignment(elf_phdata, elf_ex->e_phnum); + +- /* +- * There are effectively two types of ET_DYN +- * binaries: programs (i.e. PIE: ET_DYN with PT_INTERP) +- * and loaders (ET_DYN without PT_INTERP, since they +- * _are_ the ELF interpreter). The loaders must +- * be loaded away from programs since the program +- * may otherwise collide with the loader (especially +- * for ET_EXEC which does not have a randomized +- * position). For example to handle invocations of ++ /** ++ * DOC: PIE handling ++ * ++ * There are effectively two types of ET_DYN ELF ++ * binaries: programs (i.e. PIE: ET_DYN with ++ * PT_INTERP) and loaders (i.e. static PIE: ET_DYN ++ * without PT_INTERP, usually the ELF interpreter ++ * itself). Loaders must be loaded away from programs ++ * since the program may otherwise collide with the ++ * loader (especially for ET_EXEC which does not have ++ * a randomized position). ++ * ++ * For example, to handle invocations of + * "./ld.so someprog" to test out a new version of + * the loader, the subsequent program that the + * loader loads must avoid the loader itself, so +@@ -1143,6 +1148,9 @@ static int load_elf_binary(struct linux_binprm *bprm) + * ELF_ET_DYN_BASE and loaders are loaded into the + * independently randomized mmap region (0 load_bias + * without MAP_FIXED nor MAP_FIXED_NOREPLACE). ++ * ++ * See below for "brk" handling details, which is ++ * also affected by program vs loader and ASLR. + */ + if (interpreter) { + /* On ET_DYN with PT_INTERP, we do the ASLR. */ +@@ -1259,8 +1267,6 @@ static int load_elf_binary(struct linux_binprm *bprm) + start_data += load_bias; + end_data += load_bias; + +- current->mm->start_brk = current->mm->brk = ELF_PAGEALIGN(elf_brk); +- + if (interpreter) { + elf_entry = load_elf_interp(interp_elf_ex, + interpreter, +@@ -1316,27 +1322,44 @@ static int load_elf_binary(struct linux_binprm *bprm) + mm->end_data = end_data; + mm->start_stack = bprm->p; + +- if ((current->flags & PF_RANDOMIZE) && (snapshot_randomize_va_space > 1)) { ++ /** ++ * DOC: "brk" handling ++ * ++ * For architectures with ELF randomization, when executing a ++ * loader directly (i.e. static PIE: ET_DYN without PT_INTERP), ++ * move the brk area out of the mmap region and into the unused ++ * ELF_ET_DYN_BASE region. Since "brk" grows up it may collide ++ * early with the stack growing down or other regions being put ++ * into the mmap region by the kernel (e.g. vdso). ++ * ++ * In the CONFIG_COMPAT_BRK case, though, everything is turned ++ * off because we're not allowed to move the brk at all. ++ */ ++ if (!IS_ENABLED(CONFIG_COMPAT_BRK) && ++ IS_ENABLED(CONFIG_ARCH_HAS_ELF_RANDOMIZE) && ++ elf_ex->e_type == ET_DYN && !interpreter) { ++ elf_brk = ELF_ET_DYN_BASE; ++ /* This counts as moving the brk, so let brk(2) know. */ ++ brk_moved = true; ++ } ++ mm->start_brk = mm->brk = ELF_PAGEALIGN(elf_brk); ++ ++ if ((current->flags & PF_RANDOMIZE) && snapshot_randomize_va_space > 1) { + /* +- * For architectures with ELF randomization, when executing +- * a loader directly (i.e. no interpreter listed in ELF +- * headers), move the brk area out of the mmap region +- * (since it grows up, and may collide early with the stack +- * growing down), and into the unused ELF_ET_DYN_BASE region. ++ * If we didn't move the brk to ELF_ET_DYN_BASE (above), ++ * leave a gap between .bss and brk. + */ +- if (IS_ENABLED(CONFIG_ARCH_HAS_ELF_RANDOMIZE) && +- elf_ex->e_type == ET_DYN && !interpreter) { +- mm->brk = mm->start_brk = ELF_ET_DYN_BASE; +- } else { +- /* Otherwise leave a gap between .bss and brk. */ ++ if (!brk_moved) + mm->brk = mm->start_brk = mm->brk + PAGE_SIZE; +- } + + mm->brk = mm->start_brk = arch_randomize_brk(mm); ++ brk_moved = true; ++ } ++ + #ifdef compat_brk_randomized ++ if (brk_moved) + current->brk_randomized = 1; + #endif +- } + + if (current->personality & MMAP_PAGE_ZERO) { + /* Why this, you ask??? Well SVr4 maps page 0 as read-only, +-- +2.39.5 + diff --git a/queue-6.6/binfmt_elf-support-segments-with-0-filesz-and-misali.patch b/queue-6.6/binfmt_elf-support-segments-with-0-filesz-and-misali.patch new file mode 100644 index 0000000000..f3467cbd42 --- /dev/null +++ b/queue-6.6/binfmt_elf-support-segments-with-0-filesz-and-misali.patch @@ -0,0 +1,245 @@ +From 96cf0404ff3e559b5a0780a5380a25c12bace3bd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Sep 2023 20:24:29 -0700 +Subject: binfmt_elf: Support segments with 0 filesz and misaligned starts +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Eric W. Biederman + +[ Upstream commit 585a018627b4d7ed37387211f667916840b5c5ea ] + +Implement a helper elf_load() that wraps elf_map() and performs all +of the necessary work to ensure that when "memsz > filesz" the bytes +described by "memsz > filesz" are zeroed. + +An outstanding issue is if the first segment has filesz 0, and has a +randomized location. But that is the same as today. + +In this change I replaced an open coded padzero() that did not clear +all of the way to the end of the page, with padzero() that does. + +I also stopped checking the return of padzero() as there is at least +one known case where testing for failure is the wrong thing to do. +It looks like binfmt_elf_fdpic may have the proper set of tests +for when error handling can be safely completed. + +I found a couple of commits in the old history +https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git, +that look very interesting in understanding this code. + +commit 39b56d902bf3 ("[PATCH] binfmt_elf: clearing bss may fail") +commit c6e2227e4a3e ("[SPARC64]: Missing user access return value checks in fs/binfmt_elf.c and fs/compat.c") +commit 5bf3be033f50 ("v2.4.10.1 -> v2.4.10.2") + +Looking at commit 39b56d902bf3 ("[PATCH] binfmt_elf: clearing bss may fail"): +> commit 39b56d902bf35241e7cba6cc30b828ed937175ad +> Author: Pavel Machek +> Date: Wed Feb 9 22:40:30 2005 -0800 +> +> [PATCH] binfmt_elf: clearing bss may fail +> +> So we discover that Borland's Kylix application builder emits weird elf +> files which describe a non-writeable bss segment. +> +> So remove the clear_user() check at the place where we zero out the bss. I +> don't _think_ there are any security implications here (plus we've never +> checked that clear_user() return value, so whoops if it is a problem). +> +> Signed-off-by: Pavel Machek +> Signed-off-by: Andrew Morton +> Signed-off-by: Linus Torvalds + +It seems pretty clear that binfmt_elf_fdpic with skipping clear_user() for +non-writable segments and otherwise calling clear_user(), aka padzero(), +and checking it's return code is the right thing to do. + +I just skipped the error checking as that avoids breaking things. + +And notably, it looks like Borland's Kylix died in 2005 so it might be +safe to just consider read-only segments with memsz > filesz an error. + +Reported-by: Sebastian Ott +Reported-by: Thomas Weißschuh +Closes: https://lkml.kernel.org/r/20230914-bss-alloc-v1-1-78de67d2c6dd@weissschuh.net +Signed-off-by: "Eric W. Biederman" +Link: https://lore.kernel.org/r/87sf71f123.fsf@email.froward.int.ebiederm.org +Tested-by: Pedro Falcato +Signed-off-by: Sebastian Ott +Link: https://lore.kernel.org/r/20230929032435.2391507-1-keescook@chromium.org +Signed-off-by: Kees Cook +Stable-dep-of: 11854fe263eb ("binfmt_elf: Move brk for static PIE even if ASLR disabled") +Signed-off-by: Sasha Levin +--- + fs/binfmt_elf.c | 111 +++++++++++++++++++++--------------------------- + 1 file changed, 48 insertions(+), 63 deletions(-) + +diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c +index fb2c8d14327ae..d59bca23c4bd9 100644 +--- a/fs/binfmt_elf.c ++++ b/fs/binfmt_elf.c +@@ -110,25 +110,6 @@ static struct linux_binfmt elf_format = { + + #define BAD_ADDR(x) (unlikely((unsigned long)(x) >= TASK_SIZE)) + +-static int set_brk(unsigned long start, unsigned long end, int prot) +-{ +- start = ELF_PAGEALIGN(start); +- end = ELF_PAGEALIGN(end); +- if (end > start) { +- /* +- * Map the last of the bss segment. +- * If the header is requesting these pages to be +- * executable, honour that (ppc32 needs this). +- */ +- int error = vm_brk_flags(start, end - start, +- prot & PROT_EXEC ? VM_EXEC : 0); +- if (error) +- return error; +- } +- current->mm->start_brk = current->mm->brk = end; +- return 0; +-} +- + /* We need to explicitly zero any fractional pages + after the data section (i.e. bss). This would + contain the junk from the file that should not +@@ -406,6 +387,51 @@ static unsigned long elf_map(struct file *filep, unsigned long addr, + return(map_addr); + } + ++static unsigned long elf_load(struct file *filep, unsigned long addr, ++ const struct elf_phdr *eppnt, int prot, int type, ++ unsigned long total_size) ++{ ++ unsigned long zero_start, zero_end; ++ unsigned long map_addr; ++ ++ if (eppnt->p_filesz) { ++ map_addr = elf_map(filep, addr, eppnt, prot, type, total_size); ++ if (BAD_ADDR(map_addr)) ++ return map_addr; ++ if (eppnt->p_memsz > eppnt->p_filesz) { ++ zero_start = map_addr + ELF_PAGEOFFSET(eppnt->p_vaddr) + ++ eppnt->p_filesz; ++ zero_end = map_addr + ELF_PAGEOFFSET(eppnt->p_vaddr) + ++ eppnt->p_memsz; ++ ++ /* Zero the end of the last mapped page */ ++ padzero(zero_start); ++ } ++ } else { ++ map_addr = zero_start = ELF_PAGESTART(addr); ++ zero_end = zero_start + ELF_PAGEOFFSET(eppnt->p_vaddr) + ++ eppnt->p_memsz; ++ } ++ if (eppnt->p_memsz > eppnt->p_filesz) { ++ /* ++ * Map the last of the segment. ++ * If the header is requesting these pages to be ++ * executable, honour that (ppc32 needs this). ++ */ ++ int error; ++ ++ zero_start = ELF_PAGEALIGN(zero_start); ++ zero_end = ELF_PAGEALIGN(zero_end); ++ ++ error = vm_brk_flags(zero_start, zero_end - zero_start, ++ prot & PROT_EXEC ? VM_EXEC : 0); ++ if (error) ++ map_addr = error; ++ } ++ return map_addr; ++} ++ ++ + static unsigned long total_mapping_size(const struct elf_phdr *phdr, int nr) + { + elf_addr_t min_addr = -1; +@@ -829,7 +855,6 @@ static int load_elf_binary(struct linux_binprm *bprm) + struct elf_phdr *elf_ppnt, *elf_phdata, *interp_elf_phdata = NULL; + struct elf_phdr *elf_property_phdata = NULL; + unsigned long elf_bss, elf_brk; +- int bss_prot = 0; + int retval, i; + unsigned long elf_entry; + unsigned long e_entry; +@@ -1041,33 +1066,6 @@ static int load_elf_binary(struct linux_binprm *bprm) + if (elf_ppnt->p_type != PT_LOAD) + continue; + +- if (unlikely (elf_brk > elf_bss)) { +- unsigned long nbyte; +- +- /* There was a PT_LOAD segment with p_memsz > p_filesz +- before this one. Map anonymous pages, if needed, +- and clear the area. */ +- retval = set_brk(elf_bss + load_bias, +- elf_brk + load_bias, +- bss_prot); +- if (retval) +- goto out_free_dentry; +- nbyte = ELF_PAGEOFFSET(elf_bss); +- if (nbyte) { +- nbyte = ELF_MIN_ALIGN - nbyte; +- if (nbyte > elf_brk - elf_bss) +- nbyte = elf_brk - elf_bss; +- if (clear_user((void __user *)elf_bss + +- load_bias, nbyte)) { +- /* +- * This bss-zeroing can fail if the ELF +- * file specifies odd protections. So +- * we don't check the return value +- */ +- } +- } +- } +- + elf_prot = make_prot(elf_ppnt->p_flags, &arch_state, + !!interpreter, false); + +@@ -1163,7 +1161,7 @@ static int load_elf_binary(struct linux_binprm *bprm) + } + } + +- error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, ++ error = elf_load(bprm->file, load_bias + vaddr, elf_ppnt, + elf_prot, elf_flags, total_size); + if (BAD_ADDR(error)) { + retval = IS_ERR_VALUE(error) ? +@@ -1218,10 +1216,8 @@ static int load_elf_binary(struct linux_binprm *bprm) + if (end_data < k) + end_data = k; + k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz; +- if (k > elf_brk) { +- bss_prot = elf_prot; ++ if (k > elf_brk) + elf_brk = k; +- } + } + + e_entry = elf_ex->e_entry + load_bias; +@@ -1233,18 +1229,7 @@ static int load_elf_binary(struct linux_binprm *bprm) + start_data += load_bias; + end_data += load_bias; + +- /* Calling set_brk effectively mmaps the pages that we need +- * for the bss and break sections. We must do this before +- * mapping in the interpreter, to make sure it doesn't wind +- * up getting placed where the bss needs to go. +- */ +- retval = set_brk(elf_bss, elf_brk, bss_prot); +- if (retval) +- goto out_free_dentry; +- if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) { +- retval = -EFAULT; /* Nobody gets to see this, but.. */ +- goto out_free_dentry; +- } ++ current->mm->start_brk = current->mm->brk = ELF_PAGEALIGN(elf_brk); + + if (interpreter) { + elf_entry = load_elf_interp(interp_elf_ex, +-- +2.39.5 + diff --git a/queue-6.6/bluetooth-mgmt-fix-mgmt_op_add_device-invalid-device.patch b/queue-6.6/bluetooth-mgmt-fix-mgmt_op_add_device-invalid-device.patch new file mode 100644 index 0000000000..5e1d334b42 --- /dev/null +++ b/queue-6.6/bluetooth-mgmt-fix-mgmt_op_add_device-invalid-device.patch @@ -0,0 +1,55 @@ +From 46362819a8d279280dcc1d7f10032e1cc8feefcb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Apr 2025 15:05:59 -0400 +Subject: Bluetooth: MGMT: Fix MGMT_OP_ADD_DEVICE invalid device flags + +From: Luiz Augusto von Dentz + +[ Upstream commit 1e2e3044c1bc64a64aa0eaf7c17f7832c26c9775 ] + +Device flags could be updated in the meantime while MGMT_OP_ADD_DEVICE +is pending on hci_update_passive_scan_sync so instead of setting the +current_flags as cmd->user_data just do a lookup using +hci_conn_params_lookup and use the latest stored flags. + +Fixes: a182d9c84f9c ("Bluetooth: MGMT: Fix Add Device to responding before completing") +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/mgmt.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c +index 29e420e9754bb..589c3a481e4c1 100644 +--- a/net/bluetooth/mgmt.c ++++ b/net/bluetooth/mgmt.c +@@ -7605,11 +7605,16 @@ static void add_device_complete(struct hci_dev *hdev, void *data, int err) + struct mgmt_cp_add_device *cp = cmd->param; + + if (!err) { ++ struct hci_conn_params *params; ++ ++ params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr, ++ le_addr_type(cp->addr.type)); ++ + device_added(cmd->sk, hdev, &cp->addr.bdaddr, cp->addr.type, + cp->action); + device_flags_changed(NULL, hdev, &cp->addr.bdaddr, + cp->addr.type, hdev->conn_flags, +- PTR_UINT(cmd->user_data)); ++ params ? params->flags : 0); + } + + mgmt_cmd_complete(cmd->sk, hdev->id, MGMT_OP_ADD_DEVICE, +@@ -7712,8 +7717,6 @@ static int add_device(struct sock *sk, struct hci_dev *hdev, + goto unlock; + } + +- cmd->user_data = UINT_PTR(current_flags); +- + err = hci_cmd_sync_queue(hdev, add_device_sync, cmd, + add_device_complete); + if (err < 0) { +-- +2.39.5 + diff --git a/queue-6.6/cgroup-cpuset-extend-kthread_is_per_cpu-check-to-all.patch b/queue-6.6/cgroup-cpuset-extend-kthread_is_per_cpu-check-to-all.patch new file mode 100644 index 0000000000..68a9fc20d8 --- /dev/null +++ b/queue-6.6/cgroup-cpuset-extend-kthread_is_per_cpu-check-to-all.patch @@ -0,0 +1,53 @@ +From 959c03fde5fd5af0a0bede27265ff339c55b6bac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 May 2025 15:24:13 -0400 +Subject: cgroup/cpuset: Extend kthread_is_per_cpu() check to all + PF_NO_SETAFFINITY tasks + +From: Waiman Long + +[ Upstream commit 39b5ef791d109dd54c7c2e6e87933edfcc0ad1ac ] + +Commit ec5fbdfb99d1 ("cgroup/cpuset: Enable update_tasks_cpumask() +on top_cpuset") enabled us to pull CPUs dedicated to child partitions +from tasks in top_cpuset by ignoring per cpu kthreads. However, there +can be other kthreads that are not per cpu but have PF_NO_SETAFFINITY +flag set to indicate that we shouldn't mess with their CPU affinity. +For other kthreads, their affinity will be changed to skip CPUs dedicated +to child partitions whether it is an isolating or a scheduling one. + +As all the per cpu kthreads have PF_NO_SETAFFINITY set, the +PF_NO_SETAFFINITY tasks are essentially a superset of per cpu kthreads. +Fix this issue by dropping the kthread_is_per_cpu() check and checking +the PF_NO_SETAFFINITY flag instead. + +Fixes: ec5fbdfb99d1 ("cgroup/cpuset: Enable update_tasks_cpumask() on top_cpuset") +Signed-off-by: Waiman Long +Acked-by: Frederic Weisbecker +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/cgroup/cpuset.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c +index 3646426c69e25..ad8b62202bdc4 100644 +--- a/kernel/cgroup/cpuset.c ++++ b/kernel/cgroup/cpuset.c +@@ -1229,9 +1229,11 @@ static void update_tasks_cpumask(struct cpuset *cs, struct cpumask *new_cpus) + + if (top_cs) { + /* +- * Percpu kthreads in top_cpuset are ignored ++ * PF_NO_SETAFFINITY tasks are ignored. ++ * All per cpu kthreads should have PF_NO_SETAFFINITY ++ * flag set, see kthread_set_per_cpu(). + */ +- if (kthread_is_per_cpu(task)) ++ if (task->flags & PF_NO_SETAFFINITY) + continue; + cpumask_andnot(new_cpus, possible_mask, cs->subparts_cpus); + } else { +-- +2.39.5 + diff --git a/queue-6.6/drm-amd-add-suspend-hibernate-notification-callback-.patch b/queue-6.6/drm-amd-add-suspend-hibernate-notification-callback-.patch new file mode 100644 index 0000000000..4387c96ec2 --- /dev/null +++ b/queue-6.6/drm-amd-add-suspend-hibernate-notification-callback-.patch @@ -0,0 +1,149 @@ +From 92fa56de778377f3574c0a79b19a9ebf921edd2a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Nov 2024 21:26:56 -0600 +Subject: drm/amd: Add Suspend/Hibernate notification callback support + +From: Mario Limonciello + +[ Upstream commit 2965e6355dcdf157b5fafa25a2715f00064da8bf ] + +As part of the suspend sequence VRAM needs to be evicted on dGPUs. +In order to make suspend/resume more reliable we moved this into +the pmops prepare() callback so that the suspend sequence would fail +but the system could remain operational under high memory usage suspend. + +Another class of issues exist though where due to memory fragementation +there isn't a large enough contiguous space and swap isn't accessible. + +Add support for a suspend/hibernate notification callback that could +evict VRAM before tasks are frozen. This should allow paging out to swap +if necessary. + +Link: https://github.com/ROCm/ROCK-Kernel-Driver/issues/174 +Link: https://gitlab.freedesktop.org/drm/amd/-/issues/3476 +Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/2362 +Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3781 +Reviewed-by: Lijo Lazar +Link: https://lore.kernel.org/r/20241128032656.2090059-2-superm1@kernel.org +Signed-off-by: Mario Limonciello +Signed-off-by: Alex Deucher +Stable-dep-of: d0ce1aaa8531 ("Revert "drm/amd: Stop evicting resources on APUs in suspend"") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 46 +++++++++++++++++++++- + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 1 - + 3 files changed, 46 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +index ed4ebc6d32695..9cda2ecaf69b5 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +@@ -788,6 +788,7 @@ struct amdgpu_device { + bool need_swiotlb; + bool accel_working; + struct notifier_block acpi_nb; ++ struct notifier_block pm_nb; + struct amdgpu_i2c_chan *i2c_bus[AMDGPU_MAX_I2C_BUS]; + struct debugfs_blob_wrapper debugfs_vbios_blob; + struct debugfs_blob_wrapper debugfs_discovery_blob; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index e22e2a1df730c..9fd9424ec8f71 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -142,6 +142,8 @@ const char *amdgpu_asic_name[] = { + }; + + static inline void amdgpu_device_stop_pending_resets(struct amdgpu_device *adev); ++static int amdgpu_device_pm_notifier(struct notifier_block *nb, unsigned long mode, ++ void *data); + + /** + * DOC: pcie_replay_count +@@ -3922,6 +3924,11 @@ int amdgpu_device_init(struct amdgpu_device *adev, + + amdgpu_device_check_iommu_direct_map(adev); + ++ adev->pm_nb.notifier_call = amdgpu_device_pm_notifier; ++ r = register_pm_notifier(&adev->pm_nb); ++ if (r) ++ goto failed; ++ + return 0; + + release_ras_con: +@@ -3983,6 +3990,8 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev) + flush_delayed_work(&adev->delayed_init_work); + adev->shutdown = true; + ++ unregister_pm_notifier(&adev->pm_nb); ++ + /* make sure IB test finished before entering exclusive mode + * to avoid preemption on IB test + */ +@@ -4109,6 +4118,41 @@ static int amdgpu_device_evict_resources(struct amdgpu_device *adev) + /* + * Suspend & resume. + */ ++/** ++ * amdgpu_device_pm_notifier - Notification block for Suspend/Hibernate events ++ * @nb: notifier block ++ * @mode: suspend mode ++ * @data: data ++ * ++ * This function is called when the system is about to suspend or hibernate. ++ * It is used to evict resources from the device before the system goes to ++ * sleep while there is still access to swap. ++ */ ++static int amdgpu_device_pm_notifier(struct notifier_block *nb, unsigned long mode, ++ void *data) ++{ ++ struct amdgpu_device *adev = container_of(nb, struct amdgpu_device, pm_nb); ++ int r; ++ ++ switch (mode) { ++ case PM_HIBERNATION_PREPARE: ++ adev->in_s4 = true; ++ fallthrough; ++ case PM_SUSPEND_PREPARE: ++ r = amdgpu_device_evict_resources(adev); ++ /* ++ * This is considered non-fatal at this time because ++ * amdgpu_device_prepare() will also fatally evict resources. ++ * See https://gitlab.freedesktop.org/drm/amd/-/issues/3781 ++ */ ++ if (r) ++ drm_warn(adev_to_drm(adev), "Failed to evict resources, freeze active processes if problems occur: %d\n", r); ++ break; ++ } ++ ++ return NOTIFY_DONE; ++} ++ + /** + * amdgpu_device_prepare - prepare for device suspend + * +@@ -4148,7 +4192,7 @@ int amdgpu_device_prepare(struct drm_device *dev) + return 0; + + unprepare: +- adev->in_s0ix = adev->in_s3 = false; ++ adev->in_s0ix = adev->in_s3 = adev->in_s4 = false; + + return r; + } +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +index bacf2e5de2abc..c5727c0e6ce1c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -2463,7 +2463,6 @@ static int amdgpu_pmops_freeze(struct device *dev) + struct amdgpu_device *adev = drm_to_adev(drm_dev); + int r; + +- adev->in_s4 = true; + r = amdgpu_device_suspend(drm_dev, true); + if (r) + return r; +-- +2.39.5 + diff --git a/queue-6.6/drm-amd-stop-evicting-resources-on-apus-in-suspend.patch b/queue-6.6/drm-amd-stop-evicting-resources-on-apus-in-suspend.patch new file mode 100644 index 0000000000..5403d5d8b3 --- /dev/null +++ b/queue-6.6/drm-amd-stop-evicting-resources-on-apus-in-suspend.patch @@ -0,0 +1,118 @@ +From e1f934cc44ca71a0367445c41438486aa6910cc9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Feb 2024 23:52:55 -0600 +Subject: drm/amd: Stop evicting resources on APUs in suspend +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mario Limonciello + +[ Upstream commit 226db36032c61d8717dfdd052adac351b22d3e83 ] + +commit 5095d5418193 ("drm/amd: Evict resources during PM ops prepare() +callback") intentionally moved the eviction of resources to earlier in +the suspend process, but this introduced a subtle change that it occurs +before adev->in_s0ix or adev->in_s3 are set. This meant that APUs +actually started to evict resources at suspend time as well. + +Explicitly set s0ix or s3 in the prepare() stage, and unset them if the +prepare() stage failed. + +v2: squash in warning fix from Stephen Rothwell + +Reported-by: Jürg Billeter +Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3132#note_2271038 +Fixes: 5095d5418193 ("drm/amd: Evict resources during PM ops prepare() callback") +Acked-by: Alex Deucher +Signed-off-by: Mario Limonciello +Signed-off-by: Alex Deucher +Stable-dep-of: d0ce1aaa8531 ("Revert "drm/amd: Stop evicting resources on APUs in suspend"") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 ++ + drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 15 +++++++++++++++ + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 11 +++++++++-- + 3 files changed, 26 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +index d59e8536192ca..ed4ebc6d32695 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +@@ -1458,9 +1458,11 @@ static inline int amdgpu_acpi_smart_shift_update(struct drm_device *dev, + #if defined(CONFIG_ACPI) && defined(CONFIG_SUSPEND) + bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev); + bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev); ++void amdgpu_choose_low_power_state(struct amdgpu_device *adev); + #else + static inline bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) { return false; } + static inline bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev) { return false; } ++static inline void amdgpu_choose_low_power_state(struct amdgpu_device *adev) { } + #endif + + #if defined(CONFIG_DRM_AMD_DC) +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +index 8b2f2b921d9de..8b8e273662b39 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +@@ -1525,4 +1525,19 @@ bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) + #endif /* CONFIG_AMD_PMC */ + } + ++/** ++ * amdgpu_choose_low_power_state ++ * ++ * @adev: amdgpu_device_pointer ++ * ++ * Choose the target low power state for the GPU ++ */ ++void amdgpu_choose_low_power_state(struct amdgpu_device *adev) ++{ ++ if (amdgpu_acpi_is_s0ix_active(adev)) ++ adev->in_s0ix = true; ++ else if (amdgpu_acpi_is_s3_active(adev)) ++ adev->in_s3 = true; ++} ++ + #endif /* CONFIG_SUSPEND */ +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index 10f5a3d0f5916..b2056228e8699 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -4121,13 +4121,15 @@ int amdgpu_device_prepare(struct drm_device *dev) + struct amdgpu_device *adev = drm_to_adev(dev); + int i, r; + ++ amdgpu_choose_low_power_state(adev); ++ + if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) + return 0; + + /* Evict the majority of BOs before starting suspend sequence */ + r = amdgpu_device_evict_resources(adev); + if (r) +- return r; ++ goto unprepare; + + flush_delayed_work(&adev->gfx.gfx_off_delay_work); + +@@ -4138,10 +4140,15 @@ int amdgpu_device_prepare(struct drm_device *dev) + continue; + r = adev->ip_blocks[i].version->funcs->prepare_suspend((void *)adev); + if (r) +- return r; ++ goto unprepare; + } + + return 0; ++ ++unprepare: ++ adev->in_s0ix = adev->in_s3 = false; ++ ++ return r; + } + + /** +-- +2.39.5 + diff --git a/queue-6.6/drm-amdgpu-fix-the-runtime-resume-failure-issue.patch b/queue-6.6/drm-amdgpu-fix-the-runtime-resume-failure-issue.patch new file mode 100644 index 0000000000..39315c9672 --- /dev/null +++ b/queue-6.6/drm-amdgpu-fix-the-runtime-resume-failure-issue.patch @@ -0,0 +1,40 @@ +From fe4dec07dd44ef92b44b4e0374cf3fa4dd70c5d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Feb 2024 17:16:49 +0800 +Subject: drm/amdgpu: Fix the runtime resume failure issue + +From: Ma Jun + +[ Upstream commit bbfaf2aea7164db59739728d62d9cc91d64ff856 ] + +Don't set power state flag when system enter runtime suspend, +or it may cause runtime resume failure issue. + +Fixes: 3a9626c816db ("drm/amd: Stop evicting resources on APUs in suspend") +Signed-off-by: Ma Jun +Reviewed-by: Mario Limonciello +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Stable-dep-of: d0ce1aaa8531 ("Revert "drm/amd: Stop evicting resources on APUs in suspend"") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +index 8b8e273662b39..a6fd52aed91ab 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +@@ -1534,6 +1534,9 @@ bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) + */ + void amdgpu_choose_low_power_state(struct amdgpu_device *adev) + { ++ if (adev->in_runpm) ++ return; ++ + if (amdgpu_acpi_is_s0ix_active(adev)) + adev->in_s0ix = true; + else if (amdgpu_acpi_is_s3_active(adev)) +-- +2.39.5 + diff --git a/queue-6.6/drm-amdgpu-trigger-flr_work-if-reading-pf2vf-data-fa.patch b/queue-6.6/drm-amdgpu-trigger-flr_work-if-reading-pf2vf-data-fa.patch new file mode 100644 index 0000000000..25315e6328 --- /dev/null +++ b/queue-6.6/drm-amdgpu-trigger-flr_work-if-reading-pf2vf-data-fa.patch @@ -0,0 +1,202 @@ +From b13123cfa66aeb2171ca881c365def228948ed35 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Feb 2024 16:04:35 -0500 +Subject: drm/amdgpu: trigger flr_work if reading pf2vf data failed + +From: Zhigang Luo + +[ Upstream commit ab66c832847fcdffc97d4591ba5547e3990d9d33 ] + +if reading pf2vf data failed 30 times continuously, it means something is +wrong. Need to trigger flr_work to recover the issue. + +also use dev_err to print the error message to get which device has +issue and add warning message if waiting IDH_FLR_NOTIFICATION_CMPL +timeout. + +Signed-off-by: Zhigang Luo +Acked-by: Hawking Zhang +Signed-off-by: Alex Deucher +Stable-dep-of: d0ce1aaa8531 ("Revert "drm/amd: Stop evicting resources on APUs in suspend"") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 15 +++++++---- + drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 29 ++++++++++++++++++---- + drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h | 3 +++ + drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c | 2 ++ + drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c | 2 ++ + 5 files changed, 41 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index b2056228e8699..e22e2a1df730c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -141,6 +141,8 @@ const char *amdgpu_asic_name[] = { + "LAST", + }; + ++static inline void amdgpu_device_stop_pending_resets(struct amdgpu_device *adev); ++ + /** + * DOC: pcie_replay_count + * +@@ -4558,6 +4560,8 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev, + retry: + amdgpu_amdkfd_pre_reset(adev); + ++ amdgpu_device_stop_pending_resets(adev); ++ + if (from_hypervisor) + r = amdgpu_virt_request_full_gpu(adev, true); + else +@@ -5354,11 +5358,12 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, + tmp_adev->asic_reset_res = r; + } + +- /* +- * Drop all pending non scheduler resets. Scheduler resets +- * were already dropped during drm_sched_stop +- */ +- amdgpu_device_stop_pending_resets(tmp_adev); ++ if (!amdgpu_sriov_vf(tmp_adev)) ++ /* ++ * Drop all pending non scheduler resets. Scheduler resets ++ * were already dropped during drm_sched_stop ++ */ ++ amdgpu_device_stop_pending_resets(tmp_adev); + } + + /* Actual ASIC resets if needed.*/ +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +index 22575422ca7ec..7cb4b4118335a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +@@ -32,6 +32,7 @@ + + #include "amdgpu.h" + #include "amdgpu_ras.h" ++#include "amdgpu_reset.h" + #include "vi.h" + #include "soc15.h" + #include "nv.h" +@@ -468,7 +469,7 @@ static int amdgpu_virt_read_pf2vf_data(struct amdgpu_device *adev) + return -EINVAL; + + if (pf2vf_info->size > 1024) { +- DRM_ERROR("invalid pf2vf message size\n"); ++ dev_err(adev->dev, "invalid pf2vf message size: 0x%x\n", pf2vf_info->size); + return -EINVAL; + } + +@@ -479,7 +480,9 @@ static int amdgpu_virt_read_pf2vf_data(struct amdgpu_device *adev) + adev->virt.fw_reserve.p_pf2vf, pf2vf_info->size, + adev->virt.fw_reserve.checksum_key, checksum); + if (checksum != checkval) { +- DRM_ERROR("invalid pf2vf message\n"); ++ dev_err(adev->dev, ++ "invalid pf2vf message: header checksum=0x%x calculated checksum=0x%x\n", ++ checksum, checkval); + return -EINVAL; + } + +@@ -493,7 +496,9 @@ static int amdgpu_virt_read_pf2vf_data(struct amdgpu_device *adev) + adev->virt.fw_reserve.p_pf2vf, pf2vf_info->size, + 0, checksum); + if (checksum != checkval) { +- DRM_ERROR("invalid pf2vf message\n"); ++ dev_err(adev->dev, ++ "invalid pf2vf message: header checksum=0x%x calculated checksum=0x%x\n", ++ checksum, checkval); + return -EINVAL; + } + +@@ -529,7 +534,7 @@ static int amdgpu_virt_read_pf2vf_data(struct amdgpu_device *adev) + ((struct amd_sriov_msg_pf2vf_info *)pf2vf_info)->uuid; + break; + default: +- DRM_ERROR("invalid pf2vf version\n"); ++ dev_err(adev->dev, "invalid pf2vf version: 0x%x\n", pf2vf_info->version); + return -EINVAL; + } + +@@ -628,8 +633,21 @@ static void amdgpu_virt_update_vf2pf_work_item(struct work_struct *work) + int ret; + + ret = amdgpu_virt_read_pf2vf_data(adev); +- if (ret) ++ if (ret) { ++ adev->virt.vf2pf_update_retry_cnt++; ++ if ((adev->virt.vf2pf_update_retry_cnt >= AMDGPU_VF2PF_UPDATE_MAX_RETRY_LIMIT) && ++ amdgpu_sriov_runtime(adev) && !amdgpu_in_reset(adev)) { ++ if (amdgpu_reset_domain_schedule(adev->reset_domain, ++ &adev->virt.flr_work)) ++ return; ++ else ++ dev_err(adev->dev, "Failed to queue work! at %s", __func__); ++ } ++ + goto out; ++ } ++ ++ adev->virt.vf2pf_update_retry_cnt = 0; + amdgpu_virt_write_vf2pf_data(adev); + + out: +@@ -650,6 +668,7 @@ void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev) + adev->virt.fw_reserve.p_pf2vf = NULL; + adev->virt.fw_reserve.p_vf2pf = NULL; + adev->virt.vf2pf_update_interval_ms = 0; ++ adev->virt.vf2pf_update_retry_cnt = 0; + + if (adev->mman.fw_vram_usage_va && adev->mman.drv_vram_usage_va) { + DRM_WARN("Currently fw_vram and drv_vram should not have values at the same time!"); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +index 23b6efa9d25df..891713757a8f5 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +@@ -51,6 +51,8 @@ + /* tonga/fiji use this offset */ + #define mmBIF_IOV_FUNC_IDENTIFIER 0x1503 + ++#define AMDGPU_VF2PF_UPDATE_MAX_RETRY_LIMIT 30 ++ + enum amdgpu_sriov_vf_mode { + SRIOV_VF_MODE_BARE_METAL = 0, + SRIOV_VF_MODE_ONE_VF, +@@ -253,6 +255,7 @@ struct amdgpu_virt { + /* vf2pf message */ + struct delayed_work vf2pf_work; + uint32_t vf2pf_update_interval_ms; ++ int vf2pf_update_retry_cnt; + + /* multimedia bandwidth config */ + bool is_mm_bw_enabled; +diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c +index 63725b2ebc037..37ac6d8ff8136 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c ++++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c +@@ -276,6 +276,8 @@ static void xgpu_ai_mailbox_flr_work(struct work_struct *work) + timeout -= 10; + } while (timeout > 1); + ++ dev_warn(adev->dev, "waiting IDH_FLR_NOTIFICATION_CMPL timeout\n"); ++ + flr_done: + atomic_set(&adev->reset_domain->in_gpu_reset, 0); + up_write(&adev->reset_domain->sem); +diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c +index 6a68ee946f1cc..96edd5d11326d 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c ++++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c +@@ -298,6 +298,8 @@ static void xgpu_nv_mailbox_flr_work(struct work_struct *work) + timeout -= 10; + } while (timeout > 1); + ++ dev_warn(adev->dev, "waiting IDH_FLR_NOTIFICATION_CMPL timeout\n"); ++ + flr_done: + atomic_set(&adev->reset_domain->in_gpu_reset, 0); + up_write(&adev->reset_domain->sem); +-- +2.39.5 + diff --git a/queue-6.6/firmware-arm_scmi-add-helper-to-trace-bad-messages.patch b/queue-6.6/firmware-arm_scmi-add-helper-to-trace-bad-messages.patch new file mode 100644 index 0000000000..7c087540ce --- /dev/null +++ b/queue-6.6/firmware-arm_scmi-add-helper-to-trace-bad-messages.patch @@ -0,0 +1,101 @@ +From d3e23f5c196ad5cae4f1b601c67caeb04caeef4b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Mar 2024 20:46:17 +0000 +Subject: firmware: arm_scmi: Add helper to trace bad messages + +From: Cristian Marussi + +[ Upstream commit 5dc0e0b1f0ea2b55031f84a365962b9b45869b98 ] + +Upon reception of malformed and unexpected timed-out SCMI messages, it is +not possible to trace those bad messages in their entirety, because usually +we cannot even retrieve the payload, or it is just not reliable. + +Add a helper to trace at least the content of the header of the received +message while associating a meaningful tag and error code. + +Signed-off-by: Cristian Marussi +Link: https://lore.kernel.org/r/20240325204620.1437237-3-cristian.marussi@arm.com +Signed-off-by: Sudeep Holla +Stable-dep-of: c23c03bf1faa ("firmware: arm_scmi: Fix timeout checks on polling path") +Signed-off-by: Sasha Levin +--- + drivers/firmware/arm_scmi/common.h | 11 +++++++++ + drivers/firmware/arm_scmi/driver.c | 39 ++++++++++++++++++++++++++++++ + 2 files changed, 50 insertions(+) + +diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h +index 039f686f4580d..e26a2856a0e3d 100644 +--- a/drivers/firmware/arm_scmi/common.h ++++ b/drivers/firmware/arm_scmi/common.h +@@ -303,6 +303,17 @@ extern const struct scmi_desc scmi_optee_desc; + + void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *priv); + ++enum scmi_bad_msg { ++ MSG_UNEXPECTED = -1, ++ MSG_INVALID = -2, ++ MSG_UNKNOWN = -3, ++ MSG_NOMEM = -4, ++ MSG_MBOX_SPURIOUS = -5, ++}; ++ ++void scmi_bad_message_trace(struct scmi_chan_info *cinfo, u32 msg_hdr, ++ enum scmi_bad_msg err); ++ + /* shmem related declarations */ + struct scmi_shared_mem; + +diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c +index efa9698c876a0..b3c2a199b2afb 100644 +--- a/drivers/firmware/arm_scmi/driver.c ++++ b/drivers/firmware/arm_scmi/driver.c +@@ -687,6 +687,45 @@ scmi_xfer_lookup_unlocked(struct scmi_xfers_info *minfo, u16 xfer_id) + return xfer ?: ERR_PTR(-EINVAL); + } + ++/** ++ * scmi_bad_message_trace - A helper to trace weird messages ++ * ++ * @cinfo: A reference to the channel descriptor on which the message was ++ * received ++ * @msg_hdr: Message header to track ++ * @err: A specific error code used as a status value in traces. ++ * ++ * This helper can be used to trace any kind of weird, incomplete, unexpected, ++ * timed-out message that arrives and as such, can be traced only referring to ++ * the header content, since the payload is missing/unreliable. ++ */ ++void scmi_bad_message_trace(struct scmi_chan_info *cinfo, u32 msg_hdr, ++ enum scmi_bad_msg err) ++{ ++ char *tag; ++ struct scmi_info *info = handle_to_scmi_info(cinfo->handle); ++ ++ switch (MSG_XTRACT_TYPE(msg_hdr)) { ++ case MSG_TYPE_COMMAND: ++ tag = "!RESP"; ++ break; ++ case MSG_TYPE_DELAYED_RESP: ++ tag = "!DLYD"; ++ break; ++ case MSG_TYPE_NOTIFICATION: ++ tag = "!NOTI"; ++ break; ++ default: ++ tag = "!UNKN"; ++ break; ++ } ++ ++ trace_scmi_msg_dump(info->id, cinfo->id, ++ MSG_XTRACT_PROT_ID(msg_hdr), ++ MSG_XTRACT_ID(msg_hdr), tag, ++ MSG_XTRACT_TOKEN(msg_hdr), err, NULL, 0); ++} ++ + /** + * scmi_msg_response_validate - Validate message type against state of related + * xfer +-- +2.39.5 + diff --git a/queue-6.6/firmware-arm_scmi-add-message-dump-traces-for-bad-an.patch b/queue-6.6/firmware-arm_scmi-add-message-dump-traces-for-bad-an.patch new file mode 100644 index 0000000000..7157f633f4 --- /dev/null +++ b/queue-6.6/firmware-arm_scmi-add-message-dump-traces-for-bad-an.patch @@ -0,0 +1,83 @@ +From c1e3b061fae9edd31e30e2422d873949dd6e0ea3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Mar 2024 20:46:18 +0000 +Subject: firmware: arm_scmi: Add message dump traces for bad and unexpected + replies + +From: Cristian Marussi + +[ Upstream commit 5076ab66db1671a5cd9ecfb857d1949e36a33142 ] + +It is useful to have message dump traces for any invalid/bad/unexpected +replies. Let us add traces for the same as well as late-timed-out, +out-of-order and unexpected/spurious messages. + +Signed-off-by: Cristian Marussi +Link: https://lore.kernel.org/r/20240325204620.1437237-4-cristian.marussi@arm.com +Signed-off-by: Sudeep Holla +Stable-dep-of: c23c03bf1faa ("firmware: arm_scmi: Fix timeout checks on polling path") +Signed-off-by: Sasha Levin +--- + drivers/firmware/arm_scmi/driver.c | 10 ++++++++++ + drivers/firmware/arm_scmi/mailbox.c | 3 +++ + 2 files changed, 13 insertions(+) + +diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c +index b3c2a199b2afb..f66a16d3671f1 100644 +--- a/drivers/firmware/arm_scmi/driver.c ++++ b/drivers/firmware/arm_scmi/driver.c +@@ -852,6 +852,9 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr) + "Message for %d type %d is not expected!\n", + xfer_id, msg_type); + spin_unlock_irqrestore(&minfo->xfer_lock, flags); ++ ++ scmi_bad_message_trace(cinfo, msg_hdr, MSG_UNEXPECTED); ++ + return xfer; + } + refcount_inc(&xfer->users); +@@ -876,6 +879,9 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr) + dev_err(cinfo->dev, + "Invalid message type:%d for %d - HDR:0x%X state:%d\n", + msg_type, xfer_id, msg_hdr, xfer->state); ++ ++ scmi_bad_message_trace(cinfo, msg_hdr, MSG_INVALID); ++ + /* On error the refcount incremented above has to be dropped */ + __scmi_xfer_put(minfo, xfer); + xfer = ERR_PTR(-EINVAL); +@@ -917,6 +923,9 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, + if (IS_ERR(xfer)) { + dev_err(dev, "failed to get free message slot (%ld)\n", + PTR_ERR(xfer)); ++ ++ scmi_bad_message_trace(cinfo, msg_hdr, MSG_NOMEM); ++ + scmi_clear_channel(info, cinfo); + return; + } +@@ -1036,6 +1045,7 @@ void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *priv) + break; + default: + WARN_ONCE(1, "received unknown msg_type:%d\n", msg_type); ++ scmi_bad_message_trace(cinfo, msg_hdr, MSG_UNKNOWN); + break; + } + } +diff --git a/drivers/firmware/arm_scmi/mailbox.c b/drivers/firmware/arm_scmi/mailbox.c +index 8e513f70b75d4..f1d5e3fba35e0 100644 +--- a/drivers/firmware/arm_scmi/mailbox.c ++++ b/drivers/firmware/arm_scmi/mailbox.c +@@ -58,6 +58,9 @@ static void rx_callback(struct mbox_client *cl, void *m) + */ + if (cl->knows_txdone && !shmem_channel_free(smbox->shmem)) { + dev_warn(smbox->cinfo->dev, "Ignoring spurious A2P IRQ !\n"); ++ scmi_bad_message_trace(smbox->cinfo, ++ shmem_read_header(smbox->shmem), ++ MSG_MBOX_SPURIOUS); + return; + } + +-- +2.39.5 + diff --git a/queue-6.6/firmware-arm_scmi-add-support-for-debug-metrics-at-t.patch b/queue-6.6/firmware-arm_scmi-add-support-for-debug-metrics-at-t.patch new file mode 100644 index 0000000000..b2b12cc504 --- /dev/null +++ b/queue-6.6/firmware-arm_scmi-add-support-for-debug-metrics-at-t.patch @@ -0,0 +1,98 @@ +From b0825bba9ef54d8984c51309590b0c7f53eb3c58 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Aug 2024 14:10:09 +0100 +Subject: firmware: arm_scmi: Add support for debug metrics at the interface + +From: Luke Parkin + +[ Upstream commit 1b18d4295f9d1125bc7a799fc12924cd45fc04b1 ] + +Since SCMI involves interaction with the entity(software, firmware and/or +hardware) providing services or features, it is quite useful to track +certain metrics(for pure debugging purposes) like how many messages were +sent or received, were there any failures, what kind of failures, ..etc. + +Add a new optional config option for the above purpose and the initial +support for counting such key debug metrics. + +Signed-off-by: Luke Parkin +Reviewed-by: Cristian Marussi +Tested-by: Cristian Marussi +Message-Id: <20240805131013.587016-3-sudeep.holla@arm.com> +Signed-off-by: Sudeep Holla +Stable-dep-of: c23c03bf1faa ("firmware: arm_scmi: Fix timeout checks on polling path") +Signed-off-by: Sasha Levin +--- + drivers/firmware/arm_scmi/Kconfig | 14 ++++++++++++++ + drivers/firmware/arm_scmi/common.h | 10 ++++++++++ + drivers/firmware/arm_scmi/driver.c | 2 ++ + 3 files changed, 26 insertions(+) + +diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig +index ea0f5083ac47f..9a41c1c91f71a 100644 +--- a/drivers/firmware/arm_scmi/Kconfig ++++ b/drivers/firmware/arm_scmi/Kconfig +@@ -55,6 +55,20 @@ config ARM_SCMI_RAW_MODE_SUPPORT_COEX + operate normally, thing which could make an SCMI test suite using the + SCMI Raw mode support unreliable. If unsure, say N. + ++config ARM_SCMI_DEBUG_COUNTERS ++ bool "Enable SCMI communication debug metrics tracking" ++ select ARM_SCMI_NEED_DEBUGFS ++ depends on DEBUG_FS ++ default n ++ help ++ Enables tracking of some key communication metrics for debug ++ purposes. It may track metrics like how many messages were sent ++ or received, were there any failures, what kind of failures, ..etc. ++ ++ Enable this option to create a new debugfs directory which contains ++ such useful debug counters. This can be helpful for debugging and ++ SCMI monitoring. ++ + config ARM_SCMI_HAVE_TRANSPORT + bool + help +diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h +index e26a2856a0e3d..e3a9217f29d39 100644 +--- a/drivers/firmware/arm_scmi/common.h ++++ b/drivers/firmware/arm_scmi/common.h +@@ -303,6 +303,16 @@ extern const struct scmi_desc scmi_optee_desc; + + void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *priv); + ++enum debug_counters { ++ SCMI_DEBUG_COUNTERS_LAST ++}; ++ ++static inline void scmi_inc_count(atomic_t *arr, int stat) ++{ ++ if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) ++ atomic_inc(&arr[stat]); ++} ++ + enum scmi_bad_msg { + MSG_UNEXPECTED = -1, + MSG_INVALID = -2, +diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c +index f66a16d3671f1..3bc41a9920294 100644 +--- a/drivers/firmware/arm_scmi/driver.c ++++ b/drivers/firmware/arm_scmi/driver.c +@@ -108,12 +108,14 @@ struct scmi_protocol_instance { + * @name: Name of this SCMI instance + * @type: Type of this SCMI instance + * @is_atomic: Flag to state if the transport of this instance is atomic ++ * @counters: An array of atomic_c's used for tracking statistics (if enabled) + */ + struct scmi_debug_info { + struct dentry *top_dentry; + const char *name; + const char *type; + bool is_atomic; ++ atomic_t counters[SCMI_DEBUG_COUNTERS_LAST]; + }; + + /** +-- +2.39.5 + diff --git a/queue-6.6/firmware-arm_scmi-fix-timeout-checks-on-polling-path.patch b/queue-6.6/firmware-arm_scmi-fix-timeout-checks-on-polling-path.patch new file mode 100644 index 0000000000..064c611c97 --- /dev/null +++ b/queue-6.6/firmware-arm_scmi-fix-timeout-checks-on-polling-path.patch @@ -0,0 +1,78 @@ +From 9e6ad9153e2538440f89e3f3de84944c0d92faed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Mar 2025 17:58:00 +0000 +Subject: firmware: arm_scmi: Fix timeout checks on polling path + +From: Cristian Marussi + +[ Upstream commit c23c03bf1faa1e76be1eba35bad6da6a2a7c95ee ] + +Polling mode transactions wait for a reply busy-looping without holding a +spinlock, but currently the timeout checks are based only on elapsed time: +as a result we could hit a false positive whenever our busy-looping thread +is pre-empted and scheduled out for a time greater than the polling +timeout. + +Change the checks at the end of the busy-loop to make sure that the polling +wasn't indeed successful or an out-of-order reply caused the polling to be +forcibly terminated. + +Fixes: 31d2f803c19c ("firmware: arm_scmi: Add sync_cmds_completed_on_ret transport flag") +Reported-by: Huangjie +Closes: https://lore.kernel.org/arm-scmi/20250123083323.2363749-1-jackhuang021@gmail.com/ +Signed-off-by: Cristian Marussi +Cc: stable@vger.kernel.org # 5.18.x +Message-Id: <20250310175800.1444293-1-cristian.marussi@arm.com> +Signed-off-by: Sudeep Holla +Signed-off-by: Sasha Levin +--- + drivers/firmware/arm_scmi/driver.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c +index 09aaad6dce043..65d1e66a347d7 100644 +--- a/drivers/firmware/arm_scmi/driver.c ++++ b/drivers/firmware/arm_scmi/driver.c +@@ -1075,7 +1075,8 @@ static void xfer_put(const struct scmi_protocol_handle *ph, + } + + static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo, +- struct scmi_xfer *xfer, ktime_t stop) ++ struct scmi_xfer *xfer, ktime_t stop, ++ bool *ooo) + { + struct scmi_info *info = handle_to_scmi_info(cinfo->handle); + +@@ -1084,7 +1085,7 @@ static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo, + * in case of out-of-order receptions of delayed responses + */ + return info->desc->ops->poll_done(cinfo, xfer) || +- try_wait_for_completion(&xfer->done) || ++ (*ooo = try_wait_for_completion(&xfer->done)) || + ktime_after(ktime_get(), stop); + } + +@@ -1101,15 +1102,17 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, + * itself to support synchronous commands replies. + */ + if (!desc->sync_cmds_completed_on_ret) { ++ bool ooo = false; ++ + /* + * Poll on xfer using transport provided .poll_done(); + * assumes no completion interrupt was available. + */ + ktime_t stop = ktime_add_ms(ktime_get(), timeout_ms); + +- spin_until_cond(scmi_xfer_done_no_timeout(cinfo, +- xfer, stop)); +- if (ktime_after(ktime_get(), stop)) { ++ spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer, ++ stop, &ooo)); ++ if (!ooo && !info->desc->ops->poll_done(cinfo, xfer)) { + dev_err(dev, + "timed out in resp(caller: %pS) - polling\n", + (void *)_RET_IP_); +-- +2.39.5 + diff --git a/queue-6.6/firmware-arm_scmi-track-basic-scmi-communication-deb.patch b/queue-6.6/firmware-arm_scmi-track-basic-scmi-communication-deb.patch new file mode 100644 index 0000000000..94c751e79a --- /dev/null +++ b/queue-6.6/firmware-arm_scmi-track-basic-scmi-communication-deb.patch @@ -0,0 +1,186 @@ +From 208e6c8f085adde1048a50c683a263f864e5e198 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Aug 2024 14:10:10 +0100 +Subject: firmware: arm_scmi: Track basic SCMI communication debug metrics + +From: Luke Parkin + +[ Upstream commit 0b3d48c4726e1b20dffd2ff81a9d94d5d930220b ] + +Add the support for counting some of the SCMI communication debug metrics +like how many were sent successfully or with some errors, responses +received, notifications and delayed responses, transfer timeouts and +errors from the firmware/platform. + +In many cases, the traces exists. But the traces are not always necessarily +enabled and getting such cumulative SCMI communication debug metrics helps +in understanding if there are any possible improvements that can be made +on either side of SCMI communication. + +Signed-off-by: Luke Parkin +Reviewed-by: Cristian Marussi +Tested-by: Cristian Marussi +Message-Id: <20240805131013.587016-4-sudeep.holla@arm.com> +Signed-off-by: Sudeep Holla +Stable-dep-of: c23c03bf1faa ("firmware: arm_scmi: Fix timeout checks on polling path") +Signed-off-by: Sasha Levin +--- + drivers/firmware/arm_scmi/common.h | 14 ++++++++++++++ + drivers/firmware/arm_scmi/driver.c | 25 ++++++++++++++++++++----- + 2 files changed, 34 insertions(+), 5 deletions(-) + +diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h +index e3a9217f29d39..6c22348712154 100644 +--- a/drivers/firmware/arm_scmi/common.h ++++ b/drivers/firmware/arm_scmi/common.h +@@ -304,6 +304,20 @@ extern const struct scmi_desc scmi_optee_desc; + void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *priv); + + enum debug_counters { ++ SENT_OK, ++ SENT_FAIL, ++ SENT_FAIL_POLLING_UNSUPPORTED, ++ SENT_FAIL_CHANNEL_NOT_FOUND, ++ RESPONSE_OK, ++ NOTIFICATION_OK, ++ DELAYED_RESPONSE_OK, ++ XFERS_RESPONSE_TIMEOUT, ++ XFERS_RESPONSE_POLLED_TIMEOUT, ++ RESPONSE_POLLED_OK, ++ ERR_MSG_UNEXPECTED, ++ ERR_MSG_INVALID, ++ ERR_MSG_NOMEM, ++ ERR_PROTOCOL, + SCMI_DEBUG_COUNTERS_LAST + }; + +diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c +index 3bc41a9920294..09aaad6dce043 100644 +--- a/drivers/firmware/arm_scmi/driver.c ++++ b/drivers/firmware/arm_scmi/driver.c +@@ -856,6 +856,7 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr) + spin_unlock_irqrestore(&minfo->xfer_lock, flags); + + scmi_bad_message_trace(cinfo, msg_hdr, MSG_UNEXPECTED); ++ scmi_inc_count(info->dbg->counters, ERR_MSG_UNEXPECTED); + + return xfer; + } +@@ -883,6 +884,8 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr) + msg_type, xfer_id, msg_hdr, xfer->state); + + scmi_bad_message_trace(cinfo, msg_hdr, MSG_INVALID); ++ scmi_inc_count(info->dbg->counters, ERR_MSG_INVALID); ++ + + /* On error the refcount incremented above has to be dropped */ + __scmi_xfer_put(minfo, xfer); +@@ -927,6 +930,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, + PTR_ERR(xfer)); + + scmi_bad_message_trace(cinfo, msg_hdr, MSG_NOMEM); ++ scmi_inc_count(info->dbg->counters, ERR_MSG_NOMEM); + + scmi_clear_channel(info, cinfo); + return; +@@ -942,6 +946,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, + trace_scmi_msg_dump(info->id, cinfo->id, xfer->hdr.protocol_id, + xfer->hdr.id, "NOTI", xfer->hdr.seq, + xfer->hdr.status, xfer->rx.buf, xfer->rx.len); ++ scmi_inc_count(info->dbg->counters, NOTIFICATION_OK); + + scmi_notify(cinfo->handle, xfer->hdr.protocol_id, + xfer->hdr.id, xfer->rx.buf, xfer->rx.len, ts); +@@ -1001,8 +1006,10 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo, + if (xfer->hdr.type == MSG_TYPE_DELAYED_RESP) { + scmi_clear_channel(info, cinfo); + complete(xfer->async_done); ++ scmi_inc_count(info->dbg->counters, DELAYED_RESPONSE_OK); + } else { + complete(&xfer->done); ++ scmi_inc_count(info->dbg->counters, RESPONSE_OK); + } + + if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) { +@@ -1086,6 +1093,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, + struct scmi_xfer *xfer, unsigned int timeout_ms) + { + int ret = 0; ++ struct scmi_info *info = handle_to_scmi_info(cinfo->handle); + + if (xfer->hdr.poll_completion) { + /* +@@ -1106,13 +1114,12 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, + "timed out in resp(caller: %pS) - polling\n", + (void *)_RET_IP_); + ret = -ETIMEDOUT; ++ scmi_inc_count(info->dbg->counters, XFERS_RESPONSE_POLLED_TIMEOUT); + } + } + + if (!ret) { + unsigned long flags; +- struct scmi_info *info = +- handle_to_scmi_info(cinfo->handle); + + /* + * Do not fetch_response if an out-of-order delayed +@@ -1132,6 +1139,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, + "RESP" : "resp", + xfer->hdr.seq, xfer->hdr.status, + xfer->rx.buf, xfer->rx.len); ++ scmi_inc_count(info->dbg->counters, RESPONSE_POLLED_OK); + + if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) { + struct scmi_info *info = +@@ -1149,6 +1157,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, + dev_err(dev, "timed out in resp(caller: %pS)\n", + (void *)_RET_IP_); + ret = -ETIMEDOUT; ++ scmi_inc_count(info->dbg->counters, XFERS_RESPONSE_TIMEOUT); + } + } + +@@ -1232,13 +1241,15 @@ static int do_xfer(const struct scmi_protocol_handle *ph, + !is_transport_polling_capable(info->desc)) { + dev_warn_once(dev, + "Polling mode is not supported by transport.\n"); ++ scmi_inc_count(info->dbg->counters, SENT_FAIL_POLLING_UNSUPPORTED); + return -EINVAL; + } + + cinfo = idr_find(&info->tx_idr, pi->proto->id); +- if (unlikely(!cinfo)) ++ if (unlikely(!cinfo)) { ++ scmi_inc_count(info->dbg->counters, SENT_FAIL_CHANNEL_NOT_FOUND); + return -EINVAL; +- ++ } + /* True ONLY if also supported by transport. */ + if (is_polling_enabled(cinfo, info->desc)) + xfer->hdr.poll_completion = true; +@@ -1270,16 +1281,20 @@ static int do_xfer(const struct scmi_protocol_handle *ph, + ret = info->desc->ops->send_message(cinfo, xfer); + if (ret < 0) { + dev_dbg(dev, "Failed to send message %d\n", ret); ++ scmi_inc_count(info->dbg->counters, SENT_FAIL); + return ret; + } + + trace_scmi_msg_dump(info->id, cinfo->id, xfer->hdr.protocol_id, + xfer->hdr.id, "CMND", xfer->hdr.seq, + xfer->hdr.status, xfer->tx.buf, xfer->tx.len); ++ scmi_inc_count(info->dbg->counters, SENT_OK); + + ret = scmi_wait_for_message_response(cinfo, xfer); +- if (!ret && xfer->hdr.status) ++ if (!ret && xfer->hdr.status) { + ret = scmi_to_linux_errno(xfer->hdr.status); ++ scmi_inc_count(info->dbg->counters, ERR_PROTOCOL); ++ } + + if (info->desc->ops->mark_txdone) + info->desc->ops->mark_txdone(cinfo, ret, xfer); +-- +2.39.5 + diff --git a/queue-6.6/fs-xattr.c-fix-simple_xattr_list-to-always-include-s.patch b/queue-6.6/fs-xattr.c-fix-simple_xattr_list-to-always-include-s.patch new file mode 100644 index 0000000000..132b17c38b --- /dev/null +++ b/queue-6.6/fs-xattr.c-fix-simple_xattr_list-to-always-include-s.patch @@ -0,0 +1,102 @@ +From e3b976608b8afda21b403d84bfb574f58442eb78 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Apr 2025 11:28:20 -0400 +Subject: fs/xattr.c: fix simple_xattr_list to always include security.* xattrs + +From: Stephen Smalley + +[ Upstream commit 8b0ba61df5a1c44e2b3cf683831a4fc5e24ea99d ] + +The vfs has long had a fallback to obtain the security.* xattrs from the +LSM when the filesystem does not implement its own listxattr, but +shmem/tmpfs and kernfs later gained their own xattr handlers to support +other xattrs. Unfortunately, as a side effect, tmpfs and kernfs-based +filesystems like sysfs no longer return the synthetic security.* xattr +names via listxattr unless they are explicitly set by userspace or +initially set upon inode creation after policy load. coreutils has +recently switched from unconditionally invoking getxattr for security.* +for ls -Z via libselinux to only doing so if listxattr returns the xattr +name, breaking ls -Z of such inodes. + +Before: +$ getfattr -m.* /run/initramfs + +$ getfattr -m.* /sys/kernel/fscaps + +$ setfattr -n user.foo /run/initramfs +$ getfattr -m.* /run/initramfs +user.foo + +After: +$ getfattr -m.* /run/initramfs +security.selinux +$ getfattr -m.* /sys/kernel/fscaps +security.selinux +$ setfattr -n user.foo /run/initramfs +$ getfattr -m.* /run/initramfs +security.selinux +user.foo + +Link: https://lore.kernel.org/selinux/CAFqZXNtF8wDyQajPCdGn=iOawX4y77ph0EcfcqcUUj+T87FKyA@mail.gmail.com/ +Link: https://lore.kernel.org/selinux/20250423175728.3185-2-stephen.smalley.work@gmail.com/ +Signed-off-by: Stephen Smalley +Link: https://lore.kernel.org/20250424152822.2719-1-stephen.smalley.work@gmail.com +Fixes: b09e0fa4b4ea66266058ee ("tmpfs: implement generic xattr support") +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/xattr.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/fs/xattr.c b/fs/xattr.c +index c20046548f218..5fed22c22a2be 100644 +--- a/fs/xattr.c ++++ b/fs/xattr.c +@@ -1291,6 +1291,15 @@ static bool xattr_is_trusted(const char *name) + return !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN); + } + ++static bool xattr_is_maclabel(const char *name) ++{ ++ const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; ++ ++ return !strncmp(name, XATTR_SECURITY_PREFIX, ++ XATTR_SECURITY_PREFIX_LEN) && ++ security_ismaclabel(suffix); ++} ++ + /** + * simple_xattr_list - list all xattr objects + * @inode: inode from which to get the xattrs +@@ -1323,6 +1332,17 @@ ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs, + if (err) + return err; + ++ err = security_inode_listsecurity(inode, buffer, remaining_size); ++ if (err < 0) ++ return err; ++ ++ if (buffer) { ++ if (remaining_size < err) ++ return -ERANGE; ++ buffer += err; ++ } ++ remaining_size -= err; ++ + read_lock(&xattrs->lock); + for (rbp = rb_first(&xattrs->rb_root); rbp; rbp = rb_next(rbp)) { + xattr = rb_entry(rbp, struct simple_xattr, rb_node); +@@ -1331,6 +1351,10 @@ ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs, + if (!trusted && xattr_is_trusted(xattr->name)) + continue; + ++ /* skip MAC labels; these are provided by LSM above */ ++ if (xattr_is_maclabel(xattr->name)) ++ continue; ++ + err = xattr_list_one(&buffer, &remaining_size, xattr->name); + if (err) + break; +-- +2.39.5 + diff --git a/queue-6.6/hid-thrustmaster-fix-memory-leak-in-thrustmaster_int.patch b/queue-6.6/hid-thrustmaster-fix-memory-leak-in-thrustmaster_int.patch new file mode 100644 index 0000000000..ededbaf875 --- /dev/null +++ b/queue-6.6/hid-thrustmaster-fix-memory-leak-in-thrustmaster_int.patch @@ -0,0 +1,39 @@ +From dacec10609ca942a97038c80cb2478fb47fc0af0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Mar 2025 23:11:46 +0000 +Subject: HID: thrustmaster: fix memory leak in thrustmaster_interrupts() + +From: Qasim Ijaz + +[ Upstream commit 09d546303b370113323bfff456c4e8cff8756005 ] + +In thrustmaster_interrupts(), the allocated send_buf is not +freed if the usb_check_int_endpoints() check fails, leading +to a memory leak. + +Fix this by ensuring send_buf is freed before returning in +the error path. + +Fixes: 50420d7c79c3 ("HID: hid-thrustmaster: Fix warning in thrustmaster_probe by adding endpoint check") +Signed-off-by: Qasim Ijaz +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-thrustmaster.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/hid/hid-thrustmaster.c b/drivers/hid/hid-thrustmaster.c +index 3b81468a1df29..0bf70664c35ee 100644 +--- a/drivers/hid/hid-thrustmaster.c ++++ b/drivers/hid/hid-thrustmaster.c +@@ -174,6 +174,7 @@ static void thrustmaster_interrupts(struct hid_device *hdev) + u8 ep_addr[2] = {b_ep, 0}; + + if (!usb_check_int_endpoints(usbif, ep_addr)) { ++ kfree(send_buf); + hid_err(hdev, "Unexpected non-int endpoint\n"); + return; + } +-- +2.39.5 + diff --git a/queue-6.6/hid-uclogic-add-null-check-in-uclogic_input_configur.patch b/queue-6.6/hid-uclogic-add-null-check-in-uclogic_input_configur.patch new file mode 100644 index 0000000000..9e70ffdb15 --- /dev/null +++ b/queue-6.6/hid-uclogic-add-null-check-in-uclogic_input_configur.patch @@ -0,0 +1,46 @@ +From 9ddd0a50199a27b83b6bbf1f462a3d29761d4e95 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Apr 2025 17:48:53 +0800 +Subject: HID: uclogic: Add NULL check in uclogic_input_configured() + +From: Henry Martin + +[ Upstream commit bd07f751208ba190f9b0db5e5b7f35d5bb4a8a1e ] + +devm_kasprintf() returns NULL when memory allocation fails. Currently, +uclogic_input_configured() does not check for this case, which results +in a NULL pointer dereference. + +Add NULL check after devm_kasprintf() to prevent this issue. + +Fixes: dd613a4e45f8 ("HID: uclogic: Correct devm device reference for hidinput input_dev name") +Signed-off-by: Henry Martin +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-uclogic-core.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/hid/hid-uclogic-core.c b/drivers/hid/hid-uclogic-core.c +index ad74cbc9a0aa5..45de01dea4b1c 100644 +--- a/drivers/hid/hid-uclogic-core.c ++++ b/drivers/hid/hid-uclogic-core.c +@@ -142,11 +142,12 @@ static int uclogic_input_configured(struct hid_device *hdev, + suffix = "System Control"; + break; + } +- } +- +- if (suffix) ++ } else { + hi->input->name = devm_kasprintf(&hdev->dev, GFP_KERNEL, + "%s %s", hdev->name, suffix); ++ if (!hi->input->name) ++ return -ENOMEM; ++ } + + return 0; + } +-- +2.39.5 + diff --git a/queue-6.6/iio-adc-ad7266-fix-potential-timestamp-alignment-iss.patch b/queue-6.6/iio-adc-ad7266-fix-potential-timestamp-alignment-iss.patch new file mode 100644 index 0000000000..7c1b5ea379 --- /dev/null +++ b/queue-6.6/iio-adc-ad7266-fix-potential-timestamp-alignment-iss.patch @@ -0,0 +1,45 @@ +From d0420f0af1cd8847d837107b45cd095b45d0fdfc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 13 Apr 2025 11:34:24 +0100 +Subject: iio: adc: ad7266: Fix potential timestamp alignment issue. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jonathan Cameron + +[ Upstream commit 52d349884738c346961e153f195f4c7fe186fcf4 ] + +On architectures where an s64 is only 32-bit aligned insufficient padding +would be left between the earlier elements and the timestamp. Use +aligned_s64 to enforce the correct placement and ensure the storage is +large enough. + +Fixes: 54e018da3141 ("iio:ad7266: Mark transfer buffer as __be16") # aligned_s64 is much newer. +Reported-by: David Lechner +Reviewed-by: Nuno Sá +Reviewed-by: David Lechner +Link: https://patch.msgid.link/20250413103443.2420727-2-jic23@kernel.org +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/adc/ad7266.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c +index 98648c679a55c..2ace3aafe4978 100644 +--- a/drivers/iio/adc/ad7266.c ++++ b/drivers/iio/adc/ad7266.c +@@ -44,7 +44,7 @@ struct ad7266_state { + */ + struct { + __be16 sample[2]; +- s64 timestamp; ++ aligned_s64 timestamp; + } data __aligned(IIO_DMA_MINALIGN); + }; + +-- +2.39.5 + diff --git a/queue-6.6/iio-adc-ad7768-1-fix-insufficient-alignment-of-times.patch b/queue-6.6/iio-adc-ad7768-1-fix-insufficient-alignment-of-times.patch new file mode 100644 index 0000000000..220ea64177 --- /dev/null +++ b/queue-6.6/iio-adc-ad7768-1-fix-insufficient-alignment-of-times.patch @@ -0,0 +1,44 @@ +From 75184f405d18b269d148332c48b9f61391d6c81d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 13 Apr 2025 11:34:25 +0100 +Subject: iio: adc: ad7768-1: Fix insufficient alignment of timestamp. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jonathan Cameron + +[ Upstream commit ffbc26bc91c1f1eb3dcf5d8776e74cbae21ee13a ] + +On architectures where an s64 is not 64-bit aligned, this may result +insufficient alignment of the timestamp and the structure being too small. +Use aligned_s64 to force the alignment. + +Fixes: a1caeebab07e ("iio: adc: ad7768-1: Fix too small buffer passed to iio_push_to_buffers_with_timestamp()") # aligned_s64 newer +Reported-by: David Lechner +Reviewed-by: Nuno Sá +Reviewed-by: David Lechner +Link: https://patch.msgid.link/20250413103443.2420727-3-jic23@kernel.org +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/adc/ad7768-1.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c +index 74b0c85944bd6..967f06cd3f94e 100644 +--- a/drivers/iio/adc/ad7768-1.c ++++ b/drivers/iio/adc/ad7768-1.c +@@ -169,7 +169,7 @@ struct ad7768_state { + union { + struct { + __be32 chan; +- s64 timestamp; ++ aligned_s64 timestamp; + } scan; + __be32 d32; + u8 d8[2]; +-- +2.39.5 + diff --git a/queue-6.6/iio-chemical-sps30-use-aligned_s64-for-timestamp.patch b/queue-6.6/iio-chemical-sps30-use-aligned_s64-for-timestamp.patch new file mode 100644 index 0000000000..6d6855798b --- /dev/null +++ b/queue-6.6/iio-chemical-sps30-use-aligned_s64-for-timestamp.patch @@ -0,0 +1,43 @@ +From ea221fa0a2519c302f42b10ce7858e6e9d3b4c8b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Apr 2025 11:52:37 -0500 +Subject: iio: chemical: sps30: use aligned_s64 for timestamp +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: David Lechner + +[ Upstream commit bb49d940344bcb8e2b19e69d7ac86f567887ea9a ] + +Follow the pattern of other drivers and use aligned_s64 for the +timestamp. This will ensure that the timestamp is correctly aligned on +all architectures. + +Fixes: a5bf6fdd19c3 ("iio:chemical:sps30: Fix timestamp alignment") +Signed-off-by: David Lechner +Reviewed-by: Nuno Sá +Link: https://patch.msgid.link/20250417-iio-more-timestamp-alignment-v1-5-eafac1e22318@baylibre.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/chemical/sps30.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iio/chemical/sps30.c b/drivers/iio/chemical/sps30.c +index 814ce0aad1ccc..4085a36cd1db7 100644 +--- a/drivers/iio/chemical/sps30.c ++++ b/drivers/iio/chemical/sps30.c +@@ -108,7 +108,7 @@ static irqreturn_t sps30_trigger_handler(int irq, void *p) + int ret; + struct { + s32 data[4]; /* PM1, PM2P5, PM4, PM10 */ +- s64 ts; ++ aligned_s64 ts; + } scan; + + mutex_lock(&state->lock); +-- +2.39.5 + diff --git a/queue-6.6/kvm-svm-forcibly-leave-smm-mode-on-shutdown-intercep.patch b/queue-6.6/kvm-svm-forcibly-leave-smm-mode-on-shutdown-intercep.patch new file mode 100644 index 0000000000..b94a8a8c22 --- /dev/null +++ b/queue-6.6/kvm-svm-forcibly-leave-smm-mode-on-shutdown-intercep.patch @@ -0,0 +1,104 @@ +From 47353fb81d51fdf16a0c593daaf88b08091b0c01 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Apr 2025 20:12:06 +0300 +Subject: KVM: SVM: Forcibly leave SMM mode on SHUTDOWN interception + +From: Mikhail Lobanov + +[ Upstream commit a2620f8932fa9fdabc3d78ed6efb004ca409019f ] + +Previously, commit ed129ec9057f ("KVM: x86: forcibly leave nested mode +on vCPU reset") addressed an issue where a triple fault occurring in +nested mode could lead to use-after-free scenarios. However, the commit +did not handle the analogous situation for System Management Mode (SMM). + +This omission results in triggering a WARN when KVM forces a vCPU INIT +after SHUTDOWN interception while the vCPU is in SMM. This situation was +reprodused using Syzkaller by: + + 1) Creating a KVM VM and vCPU + 2) Sending a KVM_SMI ioctl to explicitly enter SMM + 3) Executing invalid instructions causing consecutive exceptions and + eventually a triple fault + +The issue manifests as follows: + + WARNING: CPU: 0 PID: 25506 at arch/x86/kvm/x86.c:12112 + kvm_vcpu_reset+0x1d2/0x1530 arch/x86/kvm/x86.c:12112 + Modules linked in: + CPU: 0 PID: 25506 Comm: syz-executor.0 Not tainted + 6.1.130-syzkaller-00157-g164fe5dde9b6 #0 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), + BIOS 1.12.0-1 04/01/2014 + RIP: 0010:kvm_vcpu_reset+0x1d2/0x1530 arch/x86/kvm/x86.c:12112 + Call Trace: + + shutdown_interception+0x66/0xb0 arch/x86/kvm/svm/svm.c:2136 + svm_invoke_exit_handler+0x110/0x530 arch/x86/kvm/svm/svm.c:3395 + svm_handle_exit+0x424/0x920 arch/x86/kvm/svm/svm.c:3457 + vcpu_enter_guest arch/x86/kvm/x86.c:10959 [inline] + vcpu_run+0x2c43/0x5a90 arch/x86/kvm/x86.c:11062 + kvm_arch_vcpu_ioctl_run+0x50f/0x1cf0 arch/x86/kvm/x86.c:11283 + kvm_vcpu_ioctl+0x570/0xf00 arch/x86/kvm/../../../virt/kvm/kvm_main.c:4122 + vfs_ioctl fs/ioctl.c:51 [inline] + __do_sys_ioctl fs/ioctl.c:870 [inline] + __se_sys_ioctl fs/ioctl.c:856 [inline] + __x64_sys_ioctl+0x19a/0x210 fs/ioctl.c:856 + do_syscall_x64 arch/x86/entry/common.c:51 [inline] + do_syscall_64+0x35/0x80 arch/x86/entry/common.c:81 + entry_SYSCALL_64_after_hwframe+0x6e/0xd8 + +Architecturally, INIT is blocked when the CPU is in SMM, hence KVM's WARN() +in kvm_vcpu_reset() to guard against KVM bugs, e.g. to detect improper +emulation of INIT. SHUTDOWN on SVM is a weird edge case where KVM needs to +do _something_ sane with the VMCB, since it's technically undefined, and +INIT is the least awful choice given KVM's ABI. + +So, double down on stuffing INIT on SHUTDOWN, and force the vCPU out of +SMM to avoid any weirdness (and the WARN). + +Found by Linux Verification Center (linuxtesting.org) with Syzkaller. + +Fixes: ed129ec9057f ("KVM: x86: forcibly leave nested mode on vCPU reset") +Cc: stable@vger.kernel.org +Suggested-by: Sean Christopherson +Signed-off-by: Mikhail Lobanov +Link: https://lore.kernel.org/r/20250414171207.155121-1-m.lobanov@rosa.ru +[sean: massage changelog, make it clear this isn't architectural behavior] +Signed-off-by: Sean Christopherson +Signed-off-by: Sasha Levin +--- + arch/x86/kvm/smm.c | 1 + + arch/x86/kvm/svm/svm.c | 4 ++++ + 2 files changed, 5 insertions(+) + +diff --git a/arch/x86/kvm/smm.c b/arch/x86/kvm/smm.c +index b42111a24cc28..8e38c51359d05 100644 +--- a/arch/x86/kvm/smm.c ++++ b/arch/x86/kvm/smm.c +@@ -131,6 +131,7 @@ void kvm_smm_changed(struct kvm_vcpu *vcpu, bool entering_smm) + + kvm_mmu_reset_context(vcpu); + } ++EXPORT_SYMBOL_GPL(kvm_smm_changed); + + void process_smi(struct kvm_vcpu *vcpu) + { +diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c +index 0c01887124b6c..c84a1451f194c 100644 +--- a/arch/x86/kvm/svm/svm.c ++++ b/arch/x86/kvm/svm/svm.c +@@ -2225,6 +2225,10 @@ static int shutdown_interception(struct kvm_vcpu *vcpu) + */ + if (!sev_es_guest(vcpu->kvm)) { + clear_page(svm->vmcb); ++#ifdef CONFIG_KVM_SMM ++ if (is_smm(vcpu)) ++ kvm_smm_changed(vcpu, false); ++#endif + kvm_vcpu_reset(vcpu, true); + } + +-- +2.39.5 + diff --git a/queue-6.6/kvm-svm-update-sev-es-shutdown-intercepts-with-more-.patch b/queue-6.6/kvm-svm-update-sev-es-shutdown-intercepts-with-more-.patch new file mode 100644 index 0000000000..ed79d0f286 --- /dev/null +++ b/queue-6.6/kvm-svm-update-sev-es-shutdown-intercepts-with-more-.patch @@ -0,0 +1,72 @@ +From 1b91035caa98a725df31dea7df4bd4f70e9d42b9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 09:24:49 -0700 +Subject: KVM: SVM: Update SEV-ES shutdown intercepts with more metadata + +From: Peter Gonda + +[ Upstream commit bc3d7c5570a03ab45bde4bae83697c80900fb714 ] + +Currently if an SEV-ES VM shuts down userspace sees KVM_RUN struct with +only errno=EINVAL. This is a very limited amount of information to debug +the situation. Instead return KVM_EXIT_SHUTDOWN to alert userspace the VM +is shutting down and is not usable any further. + +Signed-off-by: Peter Gonda +Suggested-by: Sean Christopherson +Suggested-by: Tom Lendacky +Cc: Paolo Bonzini +Cc: Sean Christopherson +Cc: Tom Lendacky +Cc: Joerg Roedel +Cc: Borislav Petkov +Cc: x86@kernel.org +Cc: kvm@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +Reviewed-by: Tom Lendacky +Link: https://lore.kernel.org/r/20230907162449.1739785-1-pgonda@google.com +[sean: tweak changelog] +Signed-off-by: Sean Christopherson +Stable-dep-of: a2620f8932fa ("KVM: SVM: Forcibly leave SMM mode on SHUTDOWN interception") +Signed-off-by: Sasha Levin +--- + arch/x86/kvm/svm/svm.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c +index 29c1be65cb71a..0c01887124b6c 100644 +--- a/arch/x86/kvm/svm/svm.c ++++ b/arch/x86/kvm/svm/svm.c +@@ -2211,12 +2211,6 @@ static int shutdown_interception(struct kvm_vcpu *vcpu) + struct kvm_run *kvm_run = vcpu->run; + struct vcpu_svm *svm = to_svm(vcpu); + +- /* +- * The VM save area has already been encrypted so it +- * cannot be reinitialized - just terminate. +- */ +- if (sev_es_guest(vcpu->kvm)) +- return -EINVAL; + + /* + * VMCB is undefined after a SHUTDOWN intercept. INIT the vCPU to put +@@ -2225,9 +2219,14 @@ static int shutdown_interception(struct kvm_vcpu *vcpu) + * userspace. At a platform view, INIT is acceptable behavior as + * there exist bare metal platforms that automatically INIT the CPU + * in response to shutdown. ++ * ++ * The VM save area for SEV-ES guests has already been encrypted so it ++ * cannot be reinitialized, i.e. synthesizing INIT is futile. + */ +- clear_page(svm->vmcb); +- kvm_vcpu_reset(vcpu, true); ++ if (!sev_es_guest(vcpu->kvm)) { ++ clear_page(svm->vmcb); ++ kvm_vcpu_reset(vcpu, true); ++ } + + kvm_run->exit_reason = KVM_EXIT_SHUTDOWN; + return 0; +-- +2.39.5 + diff --git a/queue-6.6/mctp-no-longer-rely-on-net-dev_index_head.patch b/queue-6.6/mctp-no-longer-rely-on-net-dev_index_head.patch new file mode 100644 index 0000000000..71463f743a --- /dev/null +++ b/queue-6.6/mctp-no-longer-rely-on-net-dev_index_head.patch @@ -0,0 +1,120 @@ +From 288396659886a3099b2545d0ad0edf58ca23ac53 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Dec 2024 22:38:11 +0000 +Subject: mctp: no longer rely on net->dev_index_head[] + +From: Eric Dumazet + +[ Upstream commit 2d20773aec14996b6cc4db92d885028319be683d ] + +mctp_dump_addrinfo() is one of the last users of +net->dev_index_head[] in the control path. + +Switch to for_each_netdev_dump() for better scalability. + +Use C99 for mctp_device_rtnl_msg_handlers[] to prepare +future RTNL removal from mctp_dump_addrinfo() + +(mdev->addrs is not yet RCU protected) + +Signed-off-by: Eric Dumazet +Cc: Matt Johnston +Reviewed-by: Kuniyuki Iwashima +Acked-by: Jeremy Kerr +Link: https://patch.msgid.link/20241206223811.1343076-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: f11cf946c0a9 ("net: mctp: Don't access ifa_index when missing") +Signed-off-by: Sasha Levin +--- + net/mctp/device.c | 50 ++++++++++++++++++----------------------------- + 1 file changed, 19 insertions(+), 31 deletions(-) + +diff --git a/net/mctp/device.c b/net/mctp/device.c +index 85cc5f31f1e7c..cdb18da96c4bc 100644 +--- a/net/mctp/device.c ++++ b/net/mctp/device.c +@@ -20,8 +20,7 @@ + #include + + struct mctp_dump_cb { +- int h; +- int idx; ++ unsigned long ifindex; + size_t a_idx; + }; + +@@ -115,43 +114,29 @@ static int mctp_dump_addrinfo(struct sk_buff *skb, struct netlink_callback *cb) + { + struct mctp_dump_cb *mcb = (void *)cb->ctx; + struct net *net = sock_net(skb->sk); +- struct hlist_head *head; + struct net_device *dev; + struct ifaddrmsg *hdr; + struct mctp_dev *mdev; +- int ifindex; +- int idx = 0, rc; ++ int ifindex, rc; + + hdr = nlmsg_data(cb->nlh); + // filter by ifindex if requested + ifindex = hdr->ifa_index; + + rcu_read_lock(); +- for (; mcb->h < NETDEV_HASHENTRIES; mcb->h++, mcb->idx = 0) { +- idx = 0; +- head = &net->dev_index_head[mcb->h]; +- hlist_for_each_entry_rcu(dev, head, index_hlist) { +- if (idx >= mcb->idx && +- (ifindex == 0 || ifindex == dev->ifindex)) { +- mdev = __mctp_dev_get(dev); +- if (mdev) { +- rc = mctp_dump_dev_addrinfo(mdev, +- skb, cb); +- mctp_dev_put(mdev); +- // Error indicates full buffer, this +- // callback will get retried. +- if (rc < 0) +- goto out; +- } +- } +- idx++; +- // reset for next iteration +- mcb->a_idx = 0; +- } ++ for_each_netdev_dump(net, dev, mcb->ifindex) { ++ if (ifindex && ifindex != dev->ifindex) ++ continue; ++ mdev = __mctp_dev_get(dev); ++ if (!mdev) ++ continue; ++ rc = mctp_dump_dev_addrinfo(mdev, skb, cb); ++ mctp_dev_put(mdev); ++ if (rc < 0) ++ break; ++ mcb->a_idx = 0; + } +-out: + rcu_read_unlock(); +- mcb->idx = idx; + + return skb->len; + } +@@ -525,9 +510,12 @@ static struct notifier_block mctp_dev_nb = { + }; + + static const struct rtnl_msg_handler mctp_device_rtnl_msg_handlers[] = { +- {THIS_MODULE, PF_MCTP, RTM_NEWADDR, mctp_rtm_newaddr, NULL, 0}, +- {THIS_MODULE, PF_MCTP, RTM_DELADDR, mctp_rtm_deladdr, NULL, 0}, +- {THIS_MODULE, PF_MCTP, RTM_GETADDR, NULL, mctp_dump_addrinfo, 0}, ++ {.owner = THIS_MODULE, .protocol = PF_MCTP, .msgtype = RTM_NEWADDR, ++ .doit = mctp_rtm_newaddr}, ++ {.owner = THIS_MODULE, .protocol = PF_MCTP, .msgtype = RTM_DELADDR, ++ .doit = mctp_rtm_deladdr}, ++ {.owner = THIS_MODULE, .protocol = PF_MCTP, .msgtype = RTM_GETADDR, ++ .dumpit = mctp_dump_addrinfo}, + }; + + int __init mctp_device_init(void) +-- +2.39.5 + diff --git a/queue-6.6/mlxsw-spectrum_router-fix-use-after-free-when-deleti.patch b/queue-6.6/mlxsw-spectrum_router-fix-use-after-free-when-deleti.patch new file mode 100644 index 0000000000..19718a459f --- /dev/null +++ b/queue-6.6/mlxsw-spectrum_router-fix-use-after-free-when-deleti.patch @@ -0,0 +1,100 @@ +From 60a1ff2ba652781b89c1616afd6aae827fed0160 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 May 2025 14:48:05 +0200 +Subject: mlxsw: spectrum_router: Fix use-after-free when deleting GRE net + devices + +From: Ido Schimmel + +[ Upstream commit 92ec4855034b2c4d13f117558dc73d20581fa9ff ] + +The driver only offloads neighbors that are constructed on top of net +devices registered by it or their uppers (which are all Ethernet). The +device supports GRE encapsulation and decapsulation of forwarded +traffic, but the driver will not offload dummy neighbors constructed on +top of GRE net devices as they are not uppers of its net devices: + + # ip link add name gre1 up type gre tos inherit local 192.0.2.1 remote 198.51.100.1 + # ip neigh add 0.0.0.0 lladdr 0.0.0.0 nud noarp dev gre1 + $ ip neigh show dev gre1 nud noarp + 0.0.0.0 lladdr 0.0.0.0 NOARP + +(Note that the neighbor is not marked with 'offload') + +When the driver is reloaded and the existing configuration is replayed, +the driver does not perform the same check regarding existing neighbors +and offloads the previously added one: + + # devlink dev reload pci/0000:01:00.0 + $ ip neigh show dev gre1 nud noarp + 0.0.0.0 lladdr 0.0.0.0 offload NOARP + +If the neighbor is later deleted, the driver will ignore the +notification (given the GRE net device is not its upper) and will +therefore keep referencing freed memory, resulting in a use-after-free +[1] when the net device is deleted: + + # ip neigh del 0.0.0.0 lladdr 0.0.0.0 dev gre1 + # ip link del dev gre1 + +Fix by skipping neighbor replay if the net device for which the replay +is performed is not our upper. + +[1] +BUG: KASAN: slab-use-after-free in mlxsw_sp_neigh_entry_update+0x1ea/0x200 +Read of size 8 at addr ffff888155b0e420 by task ip/2282 +[...] +Call Trace: + + dump_stack_lvl+0x6f/0xa0 + print_address_description.constprop.0+0x6f/0x350 + print_report+0x108/0x205 + kasan_report+0xdf/0x110 + mlxsw_sp_neigh_entry_update+0x1ea/0x200 + mlxsw_sp_router_rif_gone_sync+0x2a8/0x440 + mlxsw_sp_rif_destroy+0x1e9/0x750 + mlxsw_sp_netdevice_ipip_ol_event+0x3c9/0xdc0 + mlxsw_sp_router_netdevice_event+0x3ac/0x15e0 + notifier_call_chain+0xca/0x150 + call_netdevice_notifiers_info+0x7f/0x100 + unregister_netdevice_many_notify+0xc8c/0x1d90 + rtnl_dellink+0x34e/0xa50 + rtnetlink_rcv_msg+0x6fb/0xb70 + netlink_rcv_skb+0x131/0x360 + netlink_unicast+0x426/0x710 + netlink_sendmsg+0x75a/0xc20 + __sock_sendmsg+0xc1/0x150 + ____sys_sendmsg+0x5aa/0x7b0 + ___sys_sendmsg+0xfc/0x180 + __sys_sendmsg+0x121/0x1b0 + do_syscall_64+0xbb/0x1d0 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 + +Fixes: 8fdb09a7674c ("mlxsw: spectrum_router: Replay neighbours when RIF is made") +Signed-off-by: Ido Schimmel +Reviewed-by: Petr Machata +Signed-off-by: Petr Machata +Link: https://patch.msgid.link/c53c02c904fde32dad484657be3b1477884e9ad6.1747225701.git.petrm@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +index d15aa6b25a888..0534b10e29c5c 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +@@ -3013,6 +3013,9 @@ static int mlxsw_sp_neigh_rif_made_sync(struct mlxsw_sp *mlxsw_sp, + .rif = rif, + }; + ++ if (!mlxsw_sp_dev_lower_is_port(mlxsw_sp_rif_dev(rif))) ++ return 0; ++ + neigh_for_each(&arp_tbl, mlxsw_sp_neigh_rif_made_sync_each, &rms); + if (rms.err) + goto err_arp; +-- +2.39.5 + diff --git a/queue-6.6/net-cadence-macb-fix-a-possible-deadlock-in-macb_hal.patch b/queue-6.6/net-cadence-macb-fix-a-possible-deadlock-in-macb_hal.patch new file mode 100644 index 0000000000..cc0cd36ec6 --- /dev/null +++ b/queue-6.6/net-cadence-macb-fix-a-possible-deadlock-in-macb_hal.patch @@ -0,0 +1,64 @@ +From 2ecfa20afe7a190bca008fb3fd6b479dd70a297e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 May 2025 14:19:35 +0200 +Subject: net: cadence: macb: Fix a possible deadlock in macb_halt_tx. + +From: Mathieu Othacehe + +[ Upstream commit c92d6089d8ad7d4d815ebcedee3f3907b539ff1f ] + +There is a situation where after THALT is set high, TGO stays high as +well. Because jiffies are never updated, as we are in a context with +interrupts disabled, we never exit that loop and have a deadlock. + +That deadlock was noticed on a sama5d4 device that stayed locked for days. + +Use retries instead of jiffies so that the timeout really works and we do +not have a deadlock anymore. + +Fixes: e86cd53afc590 ("net/macb: better manage tx errors") +Signed-off-by: Mathieu Othacehe +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250509121935.16282-1-othacehe@gnu.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/cadence/macb_main.c | 19 ++++++------------- + 1 file changed, 6 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c +index 4325d0ace1f26..6f45f4d9fba71 100644 +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -1016,22 +1016,15 @@ static void macb_update_stats(struct macb *bp) + + static int macb_halt_tx(struct macb *bp) + { +- unsigned long halt_time, timeout; +- u32 status; ++ u32 status; + + macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(THALT)); + +- timeout = jiffies + usecs_to_jiffies(MACB_HALT_TIMEOUT); +- do { +- halt_time = jiffies; +- status = macb_readl(bp, TSR); +- if (!(status & MACB_BIT(TGO))) +- return 0; +- +- udelay(250); +- } while (time_before(halt_time, timeout)); +- +- return -ETIMEDOUT; ++ /* Poll TSR until TGO is cleared or timeout. */ ++ return read_poll_timeout_atomic(macb_readl, status, ++ !(status & MACB_BIT(TGO)), ++ 250, MACB_HALT_TIMEOUT, false, ++ bp, TSR); + } + + static void macb_tx_unmap(struct macb *bp, struct macb_tx_skb *tx_skb, int budget) +-- +2.39.5 + diff --git a/queue-6.6/net-dsa-sja1105-discard-incoming-frames-in-br_state_.patch b/queue-6.6/net-dsa-sja1105-discard-incoming-frames-in-br_state_.patch new file mode 100644 index 0000000000..7c1661527d --- /dev/null +++ b/queue-6.6/net-dsa-sja1105-discard-incoming-frames-in-br_state_.patch @@ -0,0 +1,92 @@ +From a01a2eb43cd866cb51e451922e1295e6d97a3209 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 May 2025 14:38:16 +0300 +Subject: net: dsa: sja1105: discard incoming frames in BR_STATE_LISTENING + +From: Vladimir Oltean + +[ Upstream commit 498625a8ab2c8e1c9ab5105744310e8d6952cc01 ] + +It has been reported that when under a bridge with stp_state=1, the logs +get spammed with this message: + +[ 251.734607] fsl_dpaa2_eth dpni.5 eth0: Couldn't decode source port + +Further debugging shows the following info associated with packets: +source_port=-1, switch_id=-1, vid=-1, vbid=1 + +In other words, they are data plane packets which are supposed to be +decoded by dsa_tag_8021q_find_port_by_vbid(), but the latter (correctly) +refuses to do so, because no switch port is currently in +BR_STATE_LEARNING or BR_STATE_FORWARDING - so the packet is effectively +unexpected. + +The error goes away after the port progresses to BR_STATE_LEARNING in 15 +seconds (the default forward_time of the bridge), because then, +dsa_tag_8021q_find_port_by_vbid() can correctly associate the data plane +packets with a plausible bridge port in a plausible STP state. + +Re-reading IEEE 802.1D-1990, I see the following: + +"4.4.2 Learning: (...) The Forwarding Process shall discard received +frames." + +IEEE 802.1D-2004 further clarifies: + +"DISABLED, BLOCKING, LISTENING, and BROKEN all correspond to the +DISCARDING port state. While those dot1dStpPortStates serve to +distinguish reasons for discarding frames, the operation of the +Forwarding and Learning processes is the same for all of them. (...) +LISTENING represents a port that the spanning tree algorithm has +selected to be part of the active topology (computing a Root Port or +Designated Port role) but is temporarily discarding frames to guard +against loops or incorrect learning." + +Well, this is not what the driver does - instead it sets +mac[port].ingress = true. + +To get rid of the log spam, prevent unexpected data plane packets to +be received by software by discarding them on ingress in the LISTENING +state. + +In terms of blame attribution: the prints only date back to commit +d7f9787a763f ("net: dsa: tag_8021q: add support for imprecise RX based +on the VBID"). However, the settings would permit a LISTENING port to +forward to a FORWARDING port, and the standard suggests that's not OK. + +Fixes: 640f763f98c2 ("net: dsa: sja1105: Add support for Spanning Tree Protocol") +Signed-off-by: Vladimir Oltean +Link: https://patch.msgid.link/20250509113816.2221992-1-vladimir.oltean@nxp.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/sja1105/sja1105_main.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c +index 1a367e64bc3b1..843e50b5a0ec5 100644 +--- a/drivers/net/dsa/sja1105/sja1105_main.c ++++ b/drivers/net/dsa/sja1105/sja1105_main.c +@@ -2076,6 +2076,7 @@ static void sja1105_bridge_stp_state_set(struct dsa_switch *ds, int port, + switch (state) { + case BR_STATE_DISABLED: + case BR_STATE_BLOCKING: ++ case BR_STATE_LISTENING: + /* From UM10944 description of DRPDTAG (why put this there?): + * "Management traffic flows to the port regardless of the state + * of the INGRESS flag". So BPDUs are still be allowed to pass. +@@ -2085,11 +2086,6 @@ static void sja1105_bridge_stp_state_set(struct dsa_switch *ds, int port, + mac[port].egress = false; + mac[port].dyn_learn = false; + break; +- case BR_STATE_LISTENING: +- mac[port].ingress = true; +- mac[port].egress = false; +- mac[port].dyn_learn = false; +- break; + case BR_STATE_LEARNING: + mac[port].ingress = true; + mac[port].egress = false; +-- +2.39.5 + diff --git a/queue-6.6/net-ethernet-mtk_eth_soc-fix-typo-for-declaration-mt.patch b/queue-6.6/net-ethernet-mtk_eth_soc-fix-typo-for-declaration-mt.patch new file mode 100644 index 0000000000..a7583ee239 --- /dev/null +++ b/queue-6.6/net-ethernet-mtk_eth_soc-fix-typo-for-declaration-mt.patch @@ -0,0 +1,41 @@ +From a62267a731b3851bf6ea7ad79d998399f96b2356 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 May 2025 05:27:30 +0100 +Subject: net: ethernet: mtk_eth_soc: fix typo for declaration MT7988 ESW + capability + +From: Bo-Cun Chen + +[ Upstream commit 1bdea6fad6fb985ff13828373c48e337c4e939f9 ] + +Since MTK_ESW_BIT is a bit number rather than a bitmap, it causes +MTK_HAS_CAPS to produce incorrect results. This leads to the ETH +driver not declaring MAC capabilities correctly for the MT7988 ESW. + +Fixes: 445eb6448ed3 ("net: ethernet: mtk_eth_soc: add basic support for MT7988 SoC") +Signed-off-by: Bo-Cun Chen +Signed-off-by: Daniel Golle +Reviewed-by: Michal Swiatkowski +Link: https://patch.msgid.link/b8b37f409d1280fad9c4d32521e6207f63cd3213.1747110258.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index c6ccfbd422657..cb8efc952dfda 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -4628,7 +4628,7 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) + } + + if (mtk_is_netsys_v3_or_greater(mac->hw) && +- MTK_HAS_CAPS(mac->hw->soc->caps, MTK_ESW_BIT) && ++ MTK_HAS_CAPS(mac->hw->soc->caps, MTK_ESW) && + id == MTK_GMAC1_ID) { + mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | + MAC_SYM_PAUSE | +-- +2.39.5 + diff --git a/queue-6.6/net-mctp-don-t-access-ifa_index-when-missing.patch b/queue-6.6/net-mctp-don-t-access-ifa_index-when-missing.patch new file mode 100644 index 0000000000..09e6a59a3a --- /dev/null +++ b/queue-6.6/net-mctp-don-t-access-ifa_index-when-missing.patch @@ -0,0 +1,68 @@ +From 1a7ecd95ecd05c6692c4c74ded8df8eaf1c385c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 May 2025 13:18:32 +0800 +Subject: net: mctp: Don't access ifa_index when missing + +From: Matt Johnston + +[ Upstream commit f11cf946c0a92c560a890d68e4775723353599e1 ] + +In mctp_dump_addrinfo, ifa_index can be used to filter interfaces, but +only when the struct ifaddrmsg is provided. Otherwise it will be +comparing to uninitialised memory - reproducible in the syzkaller case from +dhcpd, or busybox "ip addr show". + +The kernel MCTP implementation has always filtered by ifa_index, so +existing userspace programs expecting to dump MCTP addresses must +already be passing a valid ifa_index value (either 0 or a real index). + +BUG: KMSAN: uninit-value in mctp_dump_addrinfo+0x208/0xac0 net/mctp/device.c:128 + mctp_dump_addrinfo+0x208/0xac0 net/mctp/device.c:128 + rtnl_dump_all+0x3ec/0x5b0 net/core/rtnetlink.c:4380 + rtnl_dumpit+0xd5/0x2f0 net/core/rtnetlink.c:6824 + netlink_dump+0x97b/0x1690 net/netlink/af_netlink.c:2309 + +Fixes: 583be982d934 ("mctp: Add device handling and netlink interface") +Reported-by: syzbot+e76d52dadc089b9d197f@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/68135815.050a0220.3a872c.000e.GAE@google.com/ +Reported-by: syzbot+1065a199625a388fce60@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/681357d6.050a0220.14dd7d.000d.GAE@google.com/ +Signed-off-by: Matt Johnston +Link: https://patch.msgid.link/20250508-mctp-addr-dump-v2-1-c8a53fd2dd66@codeconstruct.com.au +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/mctp/device.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +diff --git a/net/mctp/device.c b/net/mctp/device.c +index cdb18da96c4bc..8d1386601bbe0 100644 +--- a/net/mctp/device.c ++++ b/net/mctp/device.c +@@ -117,11 +117,18 @@ static int mctp_dump_addrinfo(struct sk_buff *skb, struct netlink_callback *cb) + struct net_device *dev; + struct ifaddrmsg *hdr; + struct mctp_dev *mdev; +- int ifindex, rc; +- +- hdr = nlmsg_data(cb->nlh); +- // filter by ifindex if requested +- ifindex = hdr->ifa_index; ++ int ifindex = 0, rc; ++ ++ /* Filter by ifindex if a header is provided */ ++ if (cb->nlh->nlmsg_len >= nlmsg_msg_size(sizeof(*hdr))) { ++ hdr = nlmsg_data(cb->nlh); ++ ifindex = hdr->ifa_index; ++ } else { ++ if (cb->strict_check) { ++ NL_SET_ERR_MSG(cb->extack, "mctp: Invalid header for addr dump request"); ++ return -EINVAL; ++ } ++ } + + rcu_read_lock(); + for_each_netdev_dump(net, dev, mcb->ifindex) { +-- +2.39.5 + diff --git a/queue-6.6/net-mctp-ensure-keys-maintain-only-one-ref-to-corres.patch b/queue-6.6/net-mctp-ensure-keys-maintain-only-one-ref-to-corres.patch new file mode 100644 index 0000000000..c2c4673ec2 --- /dev/null +++ b/queue-6.6/net-mctp-ensure-keys-maintain-only-one-ref-to-corres.patch @@ -0,0 +1,57 @@ +From 67ddeed0d988736688f06e512f042e4d3f5578b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 May 2025 14:16:00 +0930 +Subject: net: mctp: Ensure keys maintain only one ref to corresponding dev + +From: Andrew Jeffery + +[ Upstream commit e4f349bd6e58051df698b82f94721f18a02a293d ] + +mctp_flow_prepare_output() is called in mctp_route_output(), which +places outbound packets onto a given interface. The packet may represent +a message fragment, in which case we provoke an unbalanced reference +count to the underlying device. This causes trouble if we ever attempt +to remove the interface: + + [ 48.702195] usb 1-1: USB disconnect, device number 2 + [ 58.883056] unregister_netdevice: waiting for mctpusb0 to become free. Usage count = 2 + [ 69.022548] unregister_netdevice: waiting for mctpusb0 to become free. Usage count = 2 + [ 79.172568] unregister_netdevice: waiting for mctpusb0 to become free. Usage count = 2 + ... + +Predicate the invocation of mctp_dev_set_key() in +mctp_flow_prepare_output() on not already having associated the device +with the key. It's not yet realistic to uphold the property that the key +maintains only one device reference earlier in the transmission sequence +as the route (and therefore the device) may not be known at the time the +key is associated with the socket. + +Fixes: 67737c457281 ("mctp: Pass flow data & flow release events to drivers") +Acked-by: Jeremy Kerr +Signed-off-by: Andrew Jeffery +Link: https://patch.msgid.link/20250508-mctp-dev-refcount-v1-1-d4f965c67bb5@codeconstruct.com.au +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/mctp/route.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/net/mctp/route.c b/net/mctp/route.c +index d3c1f54386efc..009ba5edbd525 100644 +--- a/net/mctp/route.c ++++ b/net/mctp/route.c +@@ -274,8 +274,10 @@ static void mctp_flow_prepare_output(struct sk_buff *skb, struct mctp_dev *dev) + + key = flow->key; + +- if (WARN_ON(key->dev && key->dev != dev)) ++ if (key->dev) { ++ WARN_ON(key->dev != dev); + return; ++ } + + mctp_dev_set_key(dev, key); + } +-- +2.39.5 + diff --git a/queue-6.6/net-mlx5e-disable-macsec-offload-for-uplink-represen.patch b/queue-6.6/net-mlx5e-disable-macsec-offload-for-uplink-represen.patch new file mode 100644 index 0000000000..6fa627e6c6 --- /dev/null +++ b/queue-6.6/net-mlx5e-disable-macsec-offload-for-uplink-represen.patch @@ -0,0 +1,156 @@ +From c81aff798606aee912c3ba0be3888b7abb000dbf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 11 May 2025 13:15:52 +0300 +Subject: net/mlx5e: Disable MACsec offload for uplink representor profile + +From: Carolina Jubran + +[ Upstream commit 588431474eb7572e57a927fa8558c9ba2f8af143 ] + +MACsec offload is not supported in switchdev mode for uplink +representors. When switching to the uplink representor profile, the +MACsec offload feature must be cleared from the netdevice's features. + +If left enabled, attempts to add offloads result in a null pointer +dereference, as the uplink representor does not support MACsec offload +even though the feature bit remains set. + +Clear NETIF_F_HW_MACSEC in mlx5e_fix_uplink_rep_features(). + +Kernel log: + +Oops: general protection fault, probably for non-canonical address 0xdffffc000000000f: 0000 [#1] SMP KASAN +KASAN: null-ptr-deref in range [0x0000000000000078-0x000000000000007f] +CPU: 29 UID: 0 PID: 4714 Comm: ip Not tainted 6.14.0-rc4_for_upstream_debug_2025_03_02_17_35 #1 +Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 +RIP: 0010:__mutex_lock+0x128/0x1dd0 +Code: d0 7c 08 84 d2 0f 85 ad 15 00 00 8b 35 91 5c fe 03 85 f6 75 29 49 8d 7e 60 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 a6 15 00 00 4d 3b 76 60 0f 85 fd 0b 00 00 65 ff +RSP: 0018:ffff888147a4f160 EFLAGS: 00010206 +RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000001 +RDX: 000000000000000f RSI: 0000000000000000 RDI: 0000000000000078 +RBP: ffff888147a4f2e0 R08: ffffffffa05d2c19 R09: 0000000000000000 +R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000 +R13: dffffc0000000000 R14: 0000000000000018 R15: ffff888152de0000 +FS: 00007f855e27d800(0000) GS:ffff88881ee80000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00000000004e5768 CR3: 000000013ae7c005 CR4: 0000000000372eb0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400 +Call Trace: + + ? die_addr+0x3d/0xa0 + ? exc_general_protection+0x144/0x220 + ? asm_exc_general_protection+0x22/0x30 + ? mlx5e_macsec_add_secy+0xf9/0x700 [mlx5_core] + ? __mutex_lock+0x128/0x1dd0 + ? lockdep_set_lock_cmp_fn+0x190/0x190 + ? mlx5e_macsec_add_secy+0xf9/0x700 [mlx5_core] + ? mutex_lock_io_nested+0x1ae0/0x1ae0 + ? lock_acquire+0x1c2/0x530 + ? macsec_upd_offload+0x145/0x380 + ? lockdep_hardirqs_on_prepare+0x400/0x400 + ? kasan_save_stack+0x30/0x40 + ? kasan_save_stack+0x20/0x40 + ? kasan_save_track+0x10/0x30 + ? __kasan_kmalloc+0x77/0x90 + ? __kmalloc_noprof+0x249/0x6b0 + ? genl_family_rcv_msg_attrs_parse.constprop.0+0xb5/0x240 + ? mlx5e_macsec_add_secy+0xf9/0x700 [mlx5_core] + mlx5e_macsec_add_secy+0xf9/0x700 [mlx5_core] + ? mlx5e_macsec_add_rxsa+0x11a0/0x11a0 [mlx5_core] + macsec_update_offload+0x26c/0x820 + ? macsec_set_mac_address+0x4b0/0x4b0 + ? lockdep_hardirqs_on_prepare+0x284/0x400 + ? _raw_spin_unlock_irqrestore+0x47/0x50 + macsec_upd_offload+0x2c8/0x380 + ? macsec_update_offload+0x820/0x820 + ? __nla_parse+0x22/0x30 + ? genl_family_rcv_msg_attrs_parse.constprop.0+0x15e/0x240 + genl_family_rcv_msg_doit+0x1cc/0x2a0 + ? genl_family_rcv_msg_attrs_parse.constprop.0+0x240/0x240 + ? cap_capable+0xd4/0x330 + genl_rcv_msg+0x3ea/0x670 + ? genl_family_rcv_msg_dumpit+0x2a0/0x2a0 + ? lockdep_set_lock_cmp_fn+0x190/0x190 + ? macsec_update_offload+0x820/0x820 + netlink_rcv_skb+0x12b/0x390 + ? genl_family_rcv_msg_dumpit+0x2a0/0x2a0 + ? netlink_ack+0xd80/0xd80 + ? rwsem_down_read_slowpath+0xf90/0xf90 + ? netlink_deliver_tap+0xcd/0xac0 + ? netlink_deliver_tap+0x155/0xac0 + ? _copy_from_iter+0x1bb/0x12c0 + genl_rcv+0x24/0x40 + netlink_unicast+0x440/0x700 + ? netlink_attachskb+0x760/0x760 + ? lock_acquire+0x1c2/0x530 + ? __might_fault+0xbb/0x170 + netlink_sendmsg+0x749/0xc10 + ? netlink_unicast+0x700/0x700 + ? __might_fault+0xbb/0x170 + ? netlink_unicast+0x700/0x700 + __sock_sendmsg+0xc5/0x190 + ____sys_sendmsg+0x53f/0x760 + ? import_iovec+0x7/0x10 + ? kernel_sendmsg+0x30/0x30 + ? __copy_msghdr+0x3c0/0x3c0 + ? filter_irq_stacks+0x90/0x90 + ? stack_depot_save_flags+0x28/0xa30 + ___sys_sendmsg+0xeb/0x170 + ? kasan_save_stack+0x30/0x40 + ? copy_msghdr_from_user+0x110/0x110 + ? do_syscall_64+0x6d/0x140 + ? lock_acquire+0x1c2/0x530 + ? __virt_addr_valid+0x116/0x3b0 + ? __virt_addr_valid+0x1da/0x3b0 + ? lock_downgrade+0x680/0x680 + ? __delete_object+0x21/0x50 + __sys_sendmsg+0xf7/0x180 + ? __sys_sendmsg_sock+0x20/0x20 + ? kmem_cache_free+0x14c/0x4e0 + ? __x64_sys_close+0x78/0xd0 + do_syscall_64+0x6d/0x140 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 +RIP: 0033:0x7f855e113367 +Code: 0e 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b9 0f 1f 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 89 54 24 1c 48 89 74 24 10 +RSP: 002b:00007ffd15e90c88 EFLAGS: 00000246 ORIG_RAX: 000000000000002e +RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007f855e113367 +RDX: 0000000000000000 RSI: 00007ffd15e90cf0 RDI: 0000000000000004 +RBP: 00007ffd15e90dbc R08: 0000000000000028 R09: 000000000045d100 +R10: 00007f855e011dd8 R11: 0000000000000246 R12: 0000000000000019 +R13: 0000000067c6b785 R14: 00000000004a1e80 R15: 0000000000000000 + +Modules linked in: 8021q garp mrp sch_ingress openvswitch nsh mlx5_ib mlx5_fwctl mlx5_dpll mlx5_core rpcrdma rdma_ucm ib_iser libiscsi scsi_transport_iscsi ib_umad rdma_cm ib_ipoib iw_cm ib_cm ib_uverbs ib_core xt_conntrack xt_MASQUERADE nf_conntrack_netlink nfnetlink xt_addrtype iptable_nat nf_nat br_netfilter rpcsec_gss_krb5 auth_rpcgss oid_registry overlay zram zsmalloc fuse [last unloaded: mlx5_core] +---[ end trace 0000000000000000 ]--- + +Fixes: 8ff0ac5be144 ("net/mlx5: Add MACsec offload Tx command support") +Signed-off-by: Carolina Jubran +Reviewed-by: Shahar Shitrit +Reviewed-by: Dragos Tatulea +Signed-off-by: Tariq Toukan +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/1746958552-561295-1-git-send-email-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +index 8a892614015cd..d9dc7280302eb 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +@@ -4136,6 +4136,10 @@ static netdev_features_t mlx5e_fix_uplink_rep_features(struct net_device *netdev + if (netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER) + netdev_warn(netdev, "Disabling HW_VLAN CTAG FILTERING, not supported in switchdev mode\n"); + ++ features &= ~NETIF_F_HW_MACSEC; ++ if (netdev->features & NETIF_F_HW_MACSEC) ++ netdev_warn(netdev, "Disabling HW MACsec offload, not supported in switchdev mode\n"); ++ + return features; + } + +-- +2.39.5 + diff --git a/queue-6.6/net-tls-fix-kernel-panic-when-alloc_page-failed.patch b/queue-6.6/net-tls-fix-kernel-panic-when-alloc_page-failed.patch new file mode 100644 index 0000000000..0ee87ead95 --- /dev/null +++ b/queue-6.6/net-tls-fix-kernel-panic-when-alloc_page-failed.patch @@ -0,0 +1,61 @@ +From 2e64e6db176b5ee44d1661aa61de8d0ed689fc35 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 May 2025 21:20:13 +0800 +Subject: net/tls: fix kernel panic when alloc_page failed + +From: Pengtao He + +[ Upstream commit 491deb9b8c4ad12fe51d554a69b8165b9ef9429f ] + +We cannot set frag_list to NULL pointer when alloc_page failed. +It will be used in tls_strp_check_queue_ok when the next time +tls_strp_read_sock is called. + +This is because we don't reset full_len in tls_strp_flush_anchor_copy() +so the recv path will try to continue handling the partial record +on the next call but we dettached the rcvq from the frag list. +Alternative fix would be to reset full_len. + +Unable to handle kernel NULL pointer dereference +at virtual address 0000000000000028 + Call trace: + tls_strp_check_rcv+0x128/0x27c + tls_strp_data_ready+0x34/0x44 + tls_data_ready+0x3c/0x1f0 + tcp_data_ready+0x9c/0xe4 + tcp_data_queue+0xf6c/0x12d0 + tcp_rcv_established+0x52c/0x798 + +Fixes: 84c61fe1a75b ("tls: rx: do not use the standard strparser") +Signed-off-by: Pengtao He +Link: https://patch.msgid.link/20250514132013.17274-1-hept.hept.hept@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/tls/tls_strp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/tls/tls_strp.c b/net/tls/tls_strp.c +index 5df08d848b5c9..1852fac3e72b7 100644 +--- a/net/tls/tls_strp.c ++++ b/net/tls/tls_strp.c +@@ -395,7 +395,6 @@ static int tls_strp_read_copy(struct tls_strparser *strp, bool qshort) + return 0; + + shinfo = skb_shinfo(strp->anchor); +- shinfo->frag_list = NULL; + + /* If we don't know the length go max plus page for cipher overhead */ + need_spc = strp->stm.full_len ?: TLS_MAX_PAYLOAD_SIZE + PAGE_SIZE; +@@ -411,6 +410,8 @@ static int tls_strp_read_copy(struct tls_strparser *strp, bool qshort) + page, 0, 0); + } + ++ shinfo->frag_list = NULL; ++ + strp->copy_mode = 1; + strp->stm.offset = 0; + +-- +2.39.5 + diff --git a/queue-6.6/net_sched-flush-gso_skb-list-too-during-change.patch b/queue-6.6/net_sched-flush-gso_skb-list-too-during-change.patch new file mode 100644 index 0000000000..7a661677f8 --- /dev/null +++ b/queue-6.6/net_sched-flush-gso_skb-list-too-during-change.patch @@ -0,0 +1,147 @@ +From a220d80a0e7fc5545098ba92c6f1c61f2ca37cd2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 May 2025 21:35:58 -0700 +Subject: net_sched: Flush gso_skb list too during ->change() + +From: Cong Wang + +[ Upstream commit 2d3cbfd6d54a2c39ce3244f33f85c595844bd7b8 ] + +Previously, when reducing a qdisc's limit via the ->change() operation, only +the main skb queue was trimmed, potentially leaving packets in the gso_skb +list. This could result in NULL pointer dereference when we only check +sch->limit against sch->q.qlen. + +This patch introduces a new helper, qdisc_dequeue_internal(), which ensures +both the gso_skb list and the main queue are properly flushed when trimming +excess packets. All relevant qdiscs (codel, fq, fq_codel, fq_pie, hhf, pie) +are updated to use this helper in their ->change() routines. + +Fixes: 76e3cc126bb2 ("codel: Controlled Delay AQM") +Fixes: 4b549a2ef4be ("fq_codel: Fair Queue Codel AQM") +Fixes: afe4fd062416 ("pkt_sched: fq: Fair Queue packet scheduler") +Fixes: ec97ecf1ebe4 ("net: sched: add Flow Queue PIE packet scheduler") +Fixes: 10239edf86f1 ("net-qdisc-hhf: Heavy-Hitter Filter (HHF) qdisc") +Fixes: d4b36210c2e6 ("net: pkt_sched: PIE AQM scheme") +Reported-by: Will +Reported-by: Savy +Signed-off-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/net/sch_generic.h | 15 +++++++++++++++ + net/sched/sch_codel.c | 2 +- + net/sched/sch_fq.c | 2 +- + net/sched/sch_fq_codel.c | 2 +- + net/sched/sch_fq_pie.c | 2 +- + net/sched/sch_hhf.c | 2 +- + net/sched/sch_pie.c | 2 +- + 7 files changed, 21 insertions(+), 6 deletions(-) + +diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h +index 4ec2a948ae3db..3287988a6a987 100644 +--- a/include/net/sch_generic.h ++++ b/include/net/sch_generic.h +@@ -1029,6 +1029,21 @@ static inline struct sk_buff *__qdisc_dequeue_head(struct qdisc_skb_head *qh) + return skb; + } + ++static inline struct sk_buff *qdisc_dequeue_internal(struct Qdisc *sch, bool direct) ++{ ++ struct sk_buff *skb; ++ ++ skb = __skb_dequeue(&sch->gso_skb); ++ if (skb) { ++ sch->q.qlen--; ++ return skb; ++ } ++ if (direct) ++ return __qdisc_dequeue_head(&sch->q); ++ else ++ return sch->dequeue(sch); ++} ++ + static inline struct sk_buff *qdisc_dequeue_head(struct Qdisc *sch) + { + struct sk_buff *skb = __qdisc_dequeue_head(&sch->q); +diff --git a/net/sched/sch_codel.c b/net/sched/sch_codel.c +index 5f2e068157456..63c02040b426a 100644 +--- a/net/sched/sch_codel.c ++++ b/net/sched/sch_codel.c +@@ -168,7 +168,7 @@ static int codel_change(struct Qdisc *sch, struct nlattr *opt, + + qlen = sch->q.qlen; + while (sch->q.qlen > sch->limit) { +- struct sk_buff *skb = __qdisc_dequeue_head(&sch->q); ++ struct sk_buff *skb = qdisc_dequeue_internal(sch, true); + + dropped += qdisc_pkt_len(skb); + qdisc_qstats_backlog_dec(sch, skb); +diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c +index f59a2cb2c803d..91f5ef6be0f23 100644 +--- a/net/sched/sch_fq.c ++++ b/net/sched/sch_fq.c +@@ -901,7 +901,7 @@ static int fq_change(struct Qdisc *sch, struct nlattr *opt, + sch_tree_lock(sch); + } + while (sch->q.qlen > sch->limit) { +- struct sk_buff *skb = fq_dequeue(sch); ++ struct sk_buff *skb = qdisc_dequeue_internal(sch, false); + + if (!skb) + break; +diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c +index 9330923a624c0..47b5a056165cb 100644 +--- a/net/sched/sch_fq_codel.c ++++ b/net/sched/sch_fq_codel.c +@@ -431,7 +431,7 @@ static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt, + + while (sch->q.qlen > sch->limit || + q->memory_usage > q->memory_limit) { +- struct sk_buff *skb = fq_codel_dequeue(sch); ++ struct sk_buff *skb = qdisc_dequeue_internal(sch, false); + + q->cstats.drop_len += qdisc_pkt_len(skb); + rtnl_kfree_skbs(skb, skb); +diff --git a/net/sched/sch_fq_pie.c b/net/sched/sch_fq_pie.c +index 68e6acd0f130d..607c580d75e4b 100644 +--- a/net/sched/sch_fq_pie.c ++++ b/net/sched/sch_fq_pie.c +@@ -357,7 +357,7 @@ static int fq_pie_change(struct Qdisc *sch, struct nlattr *opt, + + /* Drop excess packets if new limit is lower */ + while (sch->q.qlen > sch->limit) { +- struct sk_buff *skb = fq_pie_qdisc_dequeue(sch); ++ struct sk_buff *skb = qdisc_dequeue_internal(sch, false); + + len_dropped += qdisc_pkt_len(skb); + num_dropped += 1; +diff --git a/net/sched/sch_hhf.c b/net/sched/sch_hhf.c +index d26cd436cbe31..83fc44f20e31c 100644 +--- a/net/sched/sch_hhf.c ++++ b/net/sched/sch_hhf.c +@@ -560,7 +560,7 @@ static int hhf_change(struct Qdisc *sch, struct nlattr *opt, + qlen = sch->q.qlen; + prev_backlog = sch->qstats.backlog; + while (sch->q.qlen > sch->limit) { +- struct sk_buff *skb = hhf_dequeue(sch); ++ struct sk_buff *skb = qdisc_dequeue_internal(sch, false); + + rtnl_kfree_skbs(skb, skb); + } +diff --git a/net/sched/sch_pie.c b/net/sched/sch_pie.c +index 2da6250ec3463..48c5ab8ec143c 100644 +--- a/net/sched/sch_pie.c ++++ b/net/sched/sch_pie.c +@@ -190,7 +190,7 @@ static int pie_change(struct Qdisc *sch, struct nlattr *opt, + /* Drop excess packets if new limit is lower */ + qlen = sch->q.qlen; + while (sch->q.qlen > sch->limit) { +- struct sk_buff *skb = __qdisc_dequeue_head(&sch->q); ++ struct sk_buff *skb = qdisc_dequeue_internal(sch, true); + + dropped += qdisc_pkt_len(skb); + qdisc_qstats_backlog_dec(sch, skb); +-- +2.39.5 + diff --git a/queue-6.6/nfs-handle-failure-of-nfs_get_lock_context-in-unlock.patch b/queue-6.6/nfs-handle-failure-of-nfs_get_lock_context-in-unlock.patch new file mode 100644 index 0000000000..91f9901574 --- /dev/null +++ b/queue-6.6/nfs-handle-failure-of-nfs_get_lock_context-in-unlock.patch @@ -0,0 +1,97 @@ +From 109d8a12e3e4945e1a68055354d08361c6687854 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Apr 2025 15:25:08 +0800 +Subject: nfs: handle failure of nfs_get_lock_context in unlock path + +From: Li Lingfeng + +[ Upstream commit c457dc1ec770a22636b473ce5d35614adfe97636 ] + +When memory is insufficient, the allocation of nfs_lock_context in +nfs_get_lock_context() fails and returns -ENOMEM. If we mistakenly treat +an nfs4_unlockdata structure (whose l_ctx member has been set to -ENOMEM) +as valid and proceed to execute rpc_run_task(), this will trigger a NULL +pointer dereference in nfs4_locku_prepare. For example: + +BUG: kernel NULL pointer dereference, address: 000000000000000c +PGD 0 P4D 0 +Oops: Oops: 0000 [#1] SMP PTI +CPU: 15 UID: 0 PID: 12 Comm: kworker/u64:0 Not tainted 6.15.0-rc2-dirty #60 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-2.fc40 +Workqueue: rpciod rpc_async_schedule +RIP: 0010:nfs4_locku_prepare+0x35/0xc2 +Code: 89 f2 48 89 fd 48 c7 c7 68 69 ef b5 53 48 8b 8e 90 00 00 00 48 89 f3 +RSP: 0018:ffffbbafc006bdb8 EFLAGS: 00010246 +RAX: 000000000000004b RBX: ffff9b964fc1fa00 RCX: 0000000000000000 +RDX: 0000000000000000 RSI: fffffffffffffff4 RDI: ffff9ba53fddbf40 +RBP: ffff9ba539934000 R08: 0000000000000000 R09: ffffbbafc006bc38 +R10: ffffffffb6b689c8 R11: 0000000000000003 R12: ffff9ba539934030 +R13: 0000000000000001 R14: 0000000004248060 R15: ffffffffb56d1c30 +FS: 0000000000000000(0000) GS:ffff9ba5881f0000(0000) knlGS:00000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 000000000000000c CR3: 000000093f244000 CR4: 00000000000006f0 +Call Trace: + + __rpc_execute+0xbc/0x480 + rpc_async_schedule+0x2f/0x40 + process_one_work+0x232/0x5d0 + worker_thread+0x1da/0x3d0 + ? __pfx_worker_thread+0x10/0x10 + kthread+0x10d/0x240 + ? __pfx_kthread+0x10/0x10 + ret_from_fork+0x34/0x50 + ? __pfx_kthread+0x10/0x10 + ret_from_fork_asm+0x1a/0x30 + +Modules linked in: +CR2: 000000000000000c +---[ end trace 0000000000000000 ]--- + +Free the allocated nfs4_unlockdata when nfs_get_lock_context() fails and +return NULL to terminate subsequent rpc_run_task, preventing NULL pointer +dereference. + +Fixes: f30cb757f680 ("NFS: Always wait for I/O completion before unlock") +Signed-off-by: Li Lingfeng +Reviewed-by: Jeff Layton +Link: https://lore.kernel.org/r/20250417072508.3850532-1-lilingfeng3@huawei.com +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + fs/nfs/nfs4proc.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 4b12e45f57539..c140427e322ce 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -6880,10 +6880,18 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl, + struct nfs4_unlockdata *p; + struct nfs4_state *state = lsp->ls_state; + struct inode *inode = state->inode; ++ struct nfs_lock_context *l_ctx; + + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (p == NULL) + return NULL; ++ l_ctx = nfs_get_lock_context(ctx); ++ if (!IS_ERR(l_ctx)) { ++ p->l_ctx = l_ctx; ++ } else { ++ kfree(p); ++ return NULL; ++ } + p->arg.fh = NFS_FH(inode); + p->arg.fl = &p->fl; + p->arg.seqid = seqid; +@@ -6891,7 +6899,6 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl, + p->lsp = lsp; + /* Ensure we don't close file until we're done freeing locks! */ + p->ctx = get_nfs_open_context(ctx); +- p->l_ctx = nfs_get_lock_context(ctx); + locks_init_lock(&p->fl); + locks_copy_lock(&p->fl, fl); + p->server = NFS_SERVER(inode); +-- +2.39.5 + diff --git a/queue-6.6/nfsv4-pnfs-reset-the-layout-state-after-a-layoutretu.patch b/queue-6.6/nfsv4-pnfs-reset-the-layout-state-after-a-layoutretu.patch new file mode 100644 index 0000000000..124c44195f --- /dev/null +++ b/queue-6.6/nfsv4-pnfs-reset-the-layout-state-after-a-layoutretu.patch @@ -0,0 +1,50 @@ +From a46d15aa4b5d34103fc1ed83d8716f8820f24518 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 10 May 2025 10:50:13 -0400 +Subject: NFSv4/pnfs: Reset the layout state after a layoutreturn + +From: Trond Myklebust + +[ Upstream commit 6d6d7f91cc8c111d40416ac9240a3bb9396c5235 ] + +If there are still layout segments in the layout plh_return_lsegs list +after a layout return, we should be resetting the state to ensure they +eventually get returned as well. + +Fixes: 68f744797edd ("pNFS: Do not free layout segments that are marked for return") +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + fs/nfs/pnfs.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c +index fe83c681e3fe0..73aa5a63afe3f 100644 +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -732,6 +732,14 @@ pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, + return remaining; + } + ++static void pnfs_reset_return_info(struct pnfs_layout_hdr *lo) ++{ ++ struct pnfs_layout_segment *lseg; ++ ++ list_for_each_entry(lseg, &lo->plh_return_segs, pls_list) ++ pnfs_set_plh_return_info(lo, lseg->pls_range.iomode, 0); ++} ++ + static void + pnfs_free_returned_lsegs(struct pnfs_layout_hdr *lo, + struct list_head *free_me, +@@ -1180,6 +1188,7 @@ void pnfs_layoutreturn_free_lsegs(struct pnfs_layout_hdr *lo, + pnfs_mark_matching_lsegs_invalid(lo, &freeme, range, seq); + pnfs_free_returned_lsegs(lo, &freeme, range, seq); + pnfs_set_layout_stateid(lo, stateid, NULL, true); ++ pnfs_reset_return_info(lo); + } else + pnfs_mark_layout_stateid_invalid(lo, &freeme); + out_unlock: +-- +2.39.5 + diff --git a/queue-6.6/nvme-pci-acquire-cq_poll_lock-in-nvme_poll_irqdisabl.patch b/queue-6.6/nvme-pci-acquire-cq_poll_lock-in-nvme_poll_irqdisabl.patch new file mode 100644 index 0000000000..74db2a5320 --- /dev/null +++ b/queue-6.6/nvme-pci-acquire-cq_poll_lock-in-nvme_poll_irqdisabl.patch @@ -0,0 +1,40 @@ +From 6ce5037f856b46b46b0f99926da355899b1e255c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 May 2025 16:57:06 +0200 +Subject: nvme-pci: acquire cq_poll_lock in nvme_poll_irqdisable + +From: Keith Busch + +[ Upstream commit 3d8932133dcecbd9bef1559533c1089601006f45 ] + +We need to lock this queue for that condition because the timeout work +executes per-namespace and can poll the poll CQ. + +Reported-by: Hannes Reinecke +Closes: https://lore.kernel.org/all/20240902130728.1999-1-hare@kernel.org/ +Fixes: a0fa9647a54e ("NVMe: add blk polling support") +Signed-off-by: Keith Busch +Signed-off-by: Daniel Wagner +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 08280bd65d03d..1e5c8220e365c 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1107,7 +1107,9 @@ static void nvme_poll_irqdisable(struct nvme_queue *nvmeq) + WARN_ON_ONCE(test_bit(NVMEQ_POLLED, &nvmeq->flags)); + + disable_irq(pci_irq_vector(pdev, nvmeq->cq_vector)); ++ spin_lock(&nvmeq->cq_poll_lock); + nvme_poll_cq(nvmeq, NULL); ++ spin_unlock(&nvmeq->cq_poll_lock); + enable_irq(pci_irq_vector(pdev, nvmeq->cq_vector)); + } + +-- +2.39.5 + diff --git a/queue-6.6/nvme-pci-make-nvme_pci_npages_prp-__always_inline.patch b/queue-6.6/nvme-pci-make-nvme_pci_npages_prp-__always_inline.patch new file mode 100644 index 0000000000..cf00fac613 --- /dev/null +++ b/queue-6.6/nvme-pci-make-nvme_pci_npages_prp-__always_inline.patch @@ -0,0 +1,64 @@ +From dc35f73905c4fb2843a9a5fe4f048d69395d5f6d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 May 2025 20:35:40 -0700 +Subject: nvme-pci: make nvme_pci_npages_prp() __always_inline + +From: Kees Cook + +[ Upstream commit 40696426b8c8c4f13cf6ac52f0470eed144be4b2 ] + +The only reason nvme_pci_npages_prp() could be used as a compile-time +known result in BUILD_BUG_ON() is because the compiler was always choosing +to inline the function. Under special circumstances (sanitizer coverage +functions disabled for __init functions on ARCH=um), the compiler decided +to stop inlining it: + + drivers/nvme/host/pci.c: In function 'nvme_init': + include/linux/compiler_types.h:557:45: error: call to '__compiletime_assert_678' declared with attribute error: BUILD_BUG_ON failed: nvme_pci_npages_prp() > NVME_MAX_NR_ALLOCATIONS + 557 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) + | ^ + include/linux/compiler_types.h:538:25: note: in definition of macro '__compiletime_assert' + 538 | prefix ## suffix(); \ + | ^~~~~~ + include/linux/compiler_types.h:557:9: note: in expansion of macro '_compiletime_assert' + 557 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) + | ^~~~~~~~~~~~~~~~~~~ + include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert' + 39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg) + | ^~~~~~~~~~~~~~~~~~ + include/linux/build_bug.h:50:9: note: in expansion of macro 'BUILD_BUG_ON_MSG' + 50 | BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition) + | ^~~~~~~~~~~~~~~~ + drivers/nvme/host/pci.c:3804:9: note: in expansion of macro 'BUILD_BUG_ON' + 3804 | BUILD_BUG_ON(nvme_pci_npages_prp() > NVME_MAX_NR_ALLOCATIONS); + | ^~~~~~~~~~~~ + +Force it to be __always_inline to make sure it is always available for +use with BUILD_BUG_ON(). + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202505061846.12FMyRjj-lkp@intel.com/ +Fixes: c372cdd1efdf ("nvme-pci: iod npages fits in s8") +Signed-off-by: Kees Cook +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index fdde38903ebcd..08280bd65d03d 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -386,7 +386,7 @@ static bool nvme_dbbuf_update_and_check_event(u16 value, __le32 *dbbuf_db, + * as it only leads to a small amount of wasted memory for the lifetime of + * the I/O. + */ +-static int nvme_pci_npages_prp(void) ++static __always_inline int nvme_pci_npages_prp(void) + { + unsigned max_bytes = (NVME_MAX_KB_SZ * 1024) + NVME_CTRL_PAGE_SIZE; + unsigned nprps = DIV_ROUND_UP(max_bytes, NVME_CTRL_PAGE_SIZE); +-- +2.39.5 + diff --git a/queue-6.6/octeontx2-af-fix-cgx-receive-counters.patch b/queue-6.6/octeontx2-af-fix-cgx-receive-counters.patch new file mode 100644 index 0000000000..9a52952fab --- /dev/null +++ b/queue-6.6/octeontx2-af-fix-cgx-receive-counters.patch @@ -0,0 +1,43 @@ +From e9686738dae2227ff8a536a67983714506afc7e4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 May 2025 12:45:54 +0530 +Subject: octeontx2-af: Fix CGX Receive counters + +From: Hariprasad Kelam + +[ Upstream commit bf449f35e77fd44017abf991fac1f9ab7705bbe0 ] + +Each CGX block supports 4 logical MACs (LMACS). Receive +counters CGX_CMR_RX_STAT0-8 are per LMAC and CGX_CMR_RX_STAT9-12 +are per CGX. + +Due a bug in previous patch, stale Per CGX counters values observed. + +Fixes: 66208910e57a ("octeontx2-af: Support to retrieve CGX LMAC stats") +Signed-off-by: Hariprasad Kelam +Link: https://patch.msgid.link/20250513071554.728922-1-hkelam@marvell.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/marvell/octeontx2/af/cgx.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +index 52792546fe00d..339be6950c039 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +@@ -707,6 +707,11 @@ int cgx_get_rx_stats(void *cgxd, int lmac_id, int idx, u64 *rx_stat) + + if (!is_lmac_valid(cgx, lmac_id)) + return -ENODEV; ++ ++ /* pass lmac as 0 for CGX_CMR_RX_STAT9-12 */ ++ if (idx >= CGX_RX_STAT_GLOBAL_INDEX) ++ lmac_id = 0; ++ + *rx_stat = cgx_read(cgx, lmac_id, CGXX_CMRX_RX_STAT0 + (idx * 8)); + return 0; + } +-- +2.39.5 + diff --git a/queue-6.6/octeontx2-pf-macsec-fix-incorrect-max-transmit-size-.patch b/queue-6.6/octeontx2-pf-macsec-fix-incorrect-max-transmit-size-.patch new file mode 100644 index 0000000000..8b36ac8dab --- /dev/null +++ b/queue-6.6/octeontx2-pf-macsec-fix-incorrect-max-transmit-size-.patch @@ -0,0 +1,47 @@ +From 41343038bd113b8e8a2f5f9a573ae6b6598ecea2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 12 May 2025 18:12:36 +0530 +Subject: octeontx2-pf: macsec: Fix incorrect max transmit size in TX secy + +From: Subbaraya Sundeep + +[ Upstream commit 865ab2461375e3a5a2526f91f9a9f17b8931bc9e ] + +MASCEC hardware block has a field called maximum transmit size for +TX secy. Max packet size going out of MCS block has be programmed +taking into account full packet size which has L2 header,SecTag +and ICV. MACSEC offload driver is configuring max transmit size as +macsec interface MTU which is incorrect. Say with 1500 MTU of real +device, macsec interface created on top of real device will have MTU of +1468(1500 - (SecTag + ICV)). This is causing packets from macsec +interface of size greater than or equal to 1468 are not getting +transmitted out because driver programmed max transmit size as 1468 +instead of 1514(1500 + ETH_HDR_LEN). + +Fixes: c54ffc73601c ("octeontx2-pf: mcs: Introduce MACSEC hardware offloading") +Signed-off-by: Subbaraya Sundeep +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/1747053756-4529-1-git-send-email-sbhatta@marvell.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c +index 6cc7a78968fc1..74953f67a2bf9 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c +@@ -533,7 +533,8 @@ static int cn10k_mcs_write_tx_secy(struct otx2_nic *pfvf, + if (sw_tx_sc->encrypt) + sectag_tci |= (MCS_TCI_E | MCS_TCI_C); + +- policy = FIELD_PREP(MCS_TX_SECY_PLCY_MTU, secy->netdev->mtu); ++ policy = FIELD_PREP(MCS_TX_SECY_PLCY_MTU, ++ pfvf->netdev->mtu + OTX2_ETH_HLEN); + /* Write SecTag excluding AN bits(1..0) */ + policy |= FIELD_PREP(MCS_TX_SECY_PLCY_ST_TCI, sectag_tci >> 2); + policy |= FIELD_PREP(MCS_TX_SECY_PLCY_ST_OFFSET, tag_offset); +-- +2.39.5 + diff --git a/queue-6.6/platform-x86-amd-pmc-declare-quirk_spurious_8042-for.patch b/queue-6.6/platform-x86-amd-pmc-declare-quirk_spurious_8042-for.patch new file mode 100644 index 0000000000..37c813c240 --- /dev/null +++ b/queue-6.6/platform-x86-amd-pmc-declare-quirk_spurious_8042-for.patch @@ -0,0 +1,69 @@ +From 4f26251db999faa9ef58409f175c5a7de501830d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 May 2025 18:01:03 +0800 +Subject: platform/x86/amd/pmc: Declare quirk_spurious_8042 for MECHREVO Wujie + 14XA (GX4HRXL) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Runhua He + +[ Upstream commit 0887817e4953885fbd6a5c1bec2fdd339261eb19 ] + +MECHREVO Wujie 14XA (GX4HRXL) wakes up immediately after s2idle entry. +This happens regardless of whether the laptop is plugged into AC power, +or whether any peripheral is plugged into the laptop. + +Similar to commit a55bdad5dfd1 ("platform/x86/amd/pmc: Disable keyboard +wakeup on AMD Framework 13"), the MECHREVO Wujie 14XA wakes up almost +instantly after s2idle suspend entry (IRQ1 is the keyboard): + +2025-04-18 17:23:57,588 DEBUG: PM: Triggering wakeup from IRQ 9 +2025-04-18 17:23:57,588 DEBUG: PM: Triggering wakeup from IRQ 1 + +Add this model to the spurious_8042 quirk to workaround this. + +This patch does not affect the wake-up function of the built-in keyboard. +Because the firmware of this machine adds an insurance for keyboard +wake-up events, as it always triggers an additional IRQ 9 to wake up the +system. + +Suggested-by: Mingcong Bai +Suggested-by: Xinhui Yang +Suggested-by: Rong Zhang +Fixes: a55bdad5dfd1 ("platform/x86/amd/pmc: Disable keyboard wakeup on AMD Framework 13") +Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4166 +Cc: Mario Limonciello +Link: https://zhuanldan.zhihu.com/p/730538041 +Tested-by: Yemu Lu +Signed-off-by: Runhua He +Link: https://lore.kernel.org/r/20250507100103.995395-1-hua@aosc.io +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/amd/pmc/pmc-quirks.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/platform/x86/amd/pmc/pmc-quirks.c b/drivers/platform/x86/amd/pmc/pmc-quirks.c +index b4f49720c87f6..2e3f6fc67c568 100644 +--- a/drivers/platform/x86/amd/pmc/pmc-quirks.c ++++ b/drivers/platform/x86/amd/pmc/pmc-quirks.c +@@ -217,6 +217,13 @@ static const struct dmi_system_id fwbug_list[] = { + DMI_MATCH(DMI_BIOS_VERSION, "03.05"), + } + }, ++ { ++ .ident = "MECHREVO Wujie 14X (GX4HRXL)", ++ .driver_data = &quirk_spurious_8042, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "WUJIE14-GX4HRXL"), ++ } ++ }, + {} + }; + +-- +2.39.5 + diff --git a/queue-6.6/platform-x86-asus-wmi-fix-wlan_ctrl_by_user-detectio.patch b/queue-6.6/platform-x86-asus-wmi-fix-wlan_ctrl_by_user-detectio.patch new file mode 100644 index 0000000000..e39fd45d61 --- /dev/null +++ b/queue-6.6/platform-x86-asus-wmi-fix-wlan_ctrl_by_user-detectio.patch @@ -0,0 +1,76 @@ +From d878286aea88a6b28862299ca110a9e95e4f8903 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 May 2025 15:17:02 +0200 +Subject: platform/x86: asus-wmi: Fix wlan_ctrl_by_user detection +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Hans de Goede + +[ Upstream commit bfcfe6d335a967f8ea0c1980960e6f0205b5de6e ] + +The wlan_ctrl_by_user detection was introduced by commit a50bd128f28c +("asus-wmi: record wlan status while controlled by userapp"). + +Quoting from that commit's commit message: + +""" +When you call WMIMethod(DSTS, 0x00010011) to get WLAN status, it may return + +(1) 0x00050001 (On) +(2) 0x00050000 (Off) +(3) 0x00030001 (On) +(4) 0x00030000 (Off) +(5) 0x00000002 (Unknown) + +(1), (2) means that the model has hardware GPIO for WLAN, you can call +WMIMethod(DEVS, 0x00010011, 1 or 0) to turn WLAN on/off. +(3), (4) means that the model doesn’t have hardware GPIO, you need to use +API or driver library to turn WLAN on/off, and call +WMIMethod(DEVS, 0x00010012, 1 or 0) to set WLAN LED status. +After you set WLAN LED status, you can see the WLAN status is changed with +WMIMethod(DSTS, 0x00010011). Because the status is recorded lastly +(ex: Windows), you can use it for synchronization. +(5) means that the model doesn’t have WLAN device. + +WLAN is the ONLY special case with upper rule. +""" + +The wlan_ctrl_by_user flag should be set on 0x0003000? ((3), (4) above) +return values, but the flag mistakenly also gets set on laptops with +0x0005000? ((1), (2)) return values. This is causing rfkill problems on +laptops where 0x0005000? is returned. + +Fix the check to only set the wlan_ctrl_by_user flag for 0x0003000? +return values. + +Fixes: a50bd128f28c ("asus-wmi: record wlan status while controlled by userapp") +Link: https://bugzilla.kernel.org/show_bug.cgi?id=219786 +Signed-off-by: Hans de Goede +Reviewed-by: Armin Wolf +Link: https://lore.kernel.org/r/20250501131702.103360-2-hdegoede@redhat.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/asus-wmi.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c +index 222e429931ef9..2c894ea8aa817 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -4404,7 +4404,8 @@ static int asus_wmi_add(struct platform_device *pdev) + goto fail_leds; + + asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result); +- if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) ++ if ((result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) == ++ (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) + asus->driver->wlan_ctrl_by_user = 1; + + if (!(asus->driver->wlan_ctrl_by_user && ashs_present())) { +-- +2.39.5 + diff --git a/queue-6.6/qlcnic-fix-memory-leak-in-qlcnic_sriov_channel_cfg_c.patch b/queue-6.6/qlcnic-fix-memory-leak-in-qlcnic_sriov_channel_cfg_c.patch new file mode 100644 index 0000000000..63b7b394e2 --- /dev/null +++ b/queue-6.6/qlcnic-fix-memory-leak-in-qlcnic_sriov_channel_cfg_c.patch @@ -0,0 +1,45 @@ +From edc125732cb611d82b5c323016c3029642dec597 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 12 May 2025 10:18:27 +0530 +Subject: qlcnic: fix memory leak in qlcnic_sriov_channel_cfg_cmd() + +From: Abdun Nihaal + +[ Upstream commit 9d8a99c5a7c7f4f7eca2c168a4ec254409670035 ] + +In one of the error paths in qlcnic_sriov_channel_cfg_cmd(), the memory +allocated in qlcnic_sriov_alloc_bc_mbx_args() for mailbox arguments is +not freed. Fix that by jumping to the error path that frees them, by +calling qlcnic_free_mbx_args(). This was found using static analysis. + +Fixes: f197a7aa6288 ("qlcnic: VF-PF communication channel implementation") +Signed-off-by: Abdun Nihaal +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250512044829.36400-1-abdun.nihaal@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +index 28d24d59efb84..d57b976b90409 100644 +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +@@ -1484,8 +1484,11 @@ static int qlcnic_sriov_channel_cfg_cmd(struct qlcnic_adapter *adapter, u8 cmd_o + } + + cmd_op = (cmd.rsp.arg[0] & 0xff); +- if (cmd.rsp.arg[0] >> 25 == 2) +- return 2; ++ if (cmd.rsp.arg[0] >> 25 == 2) { ++ ret = 2; ++ goto out; ++ } ++ + if (cmd_op == QLCNIC_BC_CMD_CHANNEL_INIT) + set_bit(QLC_BC_VF_STATE, &vf->state); + else +-- +2.39.5 + diff --git a/queue-6.6/rdma-rxe-fix-slab-use-after-free-read-in-rxe_queue_c.patch b/queue-6.6/rdma-rxe-fix-slab-use-after-free-read-in-rxe_queue_c.patch new file mode 100644 index 0000000000..c2c08c0086 --- /dev/null +++ b/queue-6.6/rdma-rxe-fix-slab-use-after-free-read-in-rxe_queue_c.patch @@ -0,0 +1,69 @@ +From 73b9aceacfe7b87350b251a446f8544a9fec50b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Apr 2025 09:57:14 +0200 +Subject: RDMA/rxe: Fix slab-use-after-free Read in rxe_queue_cleanup bug + +From: Zhu Yanjun + +[ Upstream commit f81b33582f9339d2dc17c69b92040d3650bb4bae ] + +Call Trace: + + __dump_stack lib/dump_stack.c:94 [inline] + dump_stack_lvl+0x7d/0xa0 lib/dump_stack.c:120 + print_address_description mm/kasan/report.c:378 [inline] + print_report+0xcf/0x610 mm/kasan/report.c:489 + kasan_report+0xb5/0xe0 mm/kasan/report.c:602 + rxe_queue_cleanup+0xd0/0xe0 drivers/infiniband/sw/rxe/rxe_queue.c:195 + rxe_cq_cleanup+0x3f/0x50 drivers/infiniband/sw/rxe/rxe_cq.c:132 + __rxe_cleanup+0x168/0x300 drivers/infiniband/sw/rxe/rxe_pool.c:232 + rxe_create_cq+0x22e/0x3a0 drivers/infiniband/sw/rxe/rxe_verbs.c:1109 + create_cq+0x658/0xb90 drivers/infiniband/core/uverbs_cmd.c:1052 + ib_uverbs_create_cq+0xc7/0x120 drivers/infiniband/core/uverbs_cmd.c:1095 + ib_uverbs_write+0x969/0xc90 drivers/infiniband/core/uverbs_main.c:679 + vfs_write fs/read_write.c:677 [inline] + vfs_write+0x26a/0xcc0 fs/read_write.c:659 + ksys_write+0x1b8/0x200 fs/read_write.c:731 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xaa/0x1b0 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +In the function rxe_create_cq, when rxe_cq_from_init fails, the function +rxe_cleanup will be called to handle the allocated resources. In fact, +some memory resources have already been freed in the function +rxe_cq_from_init. Thus, this problem will occur. + +The solution is to let rxe_cleanup do all the work. + +Fixes: 8700e3e7c485 ("Soft RoCE driver") +Link: https://paste.ubuntu.com/p/tJgC42wDf6/ +Tested-by: liuyi +Signed-off-by: Zhu Yanjun +Link: https://patch.msgid.link/20250412075714.3257358-1-yanjun.zhu@linux.dev +Reviewed-by: Daisuke Matsuda +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/sw/rxe/rxe_cq.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/drivers/infiniband/sw/rxe/rxe_cq.c b/drivers/infiniband/sw/rxe/rxe_cq.c +index fec87c9030abd..fffd144d509eb 100644 +--- a/drivers/infiniband/sw/rxe/rxe_cq.c ++++ b/drivers/infiniband/sw/rxe/rxe_cq.c +@@ -56,11 +56,8 @@ int rxe_cq_from_init(struct rxe_dev *rxe, struct rxe_cq *cq, int cqe, + + err = do_mmap_info(rxe, uresp ? &uresp->mi : NULL, udata, + cq->queue->buf, cq->queue->buf_size, &cq->queue->ip); +- if (err) { +- vfree(cq->queue->buf); +- kfree(cq->queue); ++ if (err) + return err; +- } + + cq->is_user = uresp; + +-- +2.39.5 + diff --git a/queue-6.6/regulator-max20086-fix-invalid-memory-access.patch b/queue-6.6/regulator-max20086-fix-invalid-memory-access.patch new file mode 100644 index 0000000000..e1cb3481cc --- /dev/null +++ b/queue-6.6/regulator-max20086-fix-invalid-memory-access.patch @@ -0,0 +1,73 @@ +From f2177af9cd29098215368cb0bdf0597980a2daef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 May 2025 09:49:43 +0300 +Subject: regulator: max20086: fix invalid memory access + +From: Cosmin Tanislav + +[ Upstream commit 6b0cd72757c69bc2d45da42b41023e288d02e772 ] + +max20086_parse_regulators_dt() calls of_regulator_match() using an +array of struct of_regulator_match allocated on the stack for the +matches argument. + +of_regulator_match() calls devm_of_regulator_put_matches(), which calls +devres_alloc() to allocate a struct devm_of_regulator_matches which will +be de-allocated using devm_of_regulator_put_matches(). + +struct devm_of_regulator_matches is populated with the stack allocated +matches array. + +If the device fails to probe, devm_of_regulator_put_matches() will be +called and will try to call of_node_put() on that stack pointer, +generating the following dmesg entries: + +max20086 6-0028: Failed to read DEVICE_ID reg: -121 +kobject: '\xc0$\xa5\x03' (000000002cebcb7a): is not initialized, yet +kobject_put() is being called. + +Followed by a stack trace matching the call flow described above. + +Switch to allocating the matches array using devm_kcalloc() to +avoid accessing the stack pointer long after it's out of scope. + +This also has the advantage of allowing multiple max20086 to probe +without overriding the data stored inside the global of_regulator_match. + +Fixes: bfff546aae50 ("regulator: Add MAX20086-MAX20089 driver") +Signed-off-by: Cosmin Tanislav +Link: https://patch.msgid.link/20250508064947.2567255-1-demonsingur@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/max20086-regulator.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/regulator/max20086-regulator.c b/drivers/regulator/max20086-regulator.c +index 32f47b896fd1e..ebfbcadbca529 100644 +--- a/drivers/regulator/max20086-regulator.c ++++ b/drivers/regulator/max20086-regulator.c +@@ -132,7 +132,7 @@ static int max20086_regulators_register(struct max20086 *chip) + + static int max20086_parse_regulators_dt(struct max20086 *chip, bool *boot_on) + { +- struct of_regulator_match matches[MAX20086_MAX_REGULATORS] = { }; ++ struct of_regulator_match *matches; + struct device_node *node; + unsigned int i; + int ret; +@@ -143,6 +143,11 @@ static int max20086_parse_regulators_dt(struct max20086 *chip, bool *boot_on) + return -ENODEV; + } + ++ matches = devm_kcalloc(chip->dev, chip->info->num_outputs, ++ sizeof(*matches), GFP_KERNEL); ++ if (!matches) ++ return -ENOMEM; ++ + for (i = 0; i < chip->info->num_outputs; ++i) + matches[i].name = max20086_output_names[i]; + +-- +2.39.5 + diff --git a/queue-6.6/revert-drm-amd-stop-evicting-resources-on-apus-in-su.patch b/queue-6.6/revert-drm-amd-stop-evicting-resources-on-apus-in-su.patch new file mode 100644 index 0000000000..e425a815f1 --- /dev/null +++ b/queue-6.6/revert-drm-amd-stop-evicting-resources-on-apus-in-su.patch @@ -0,0 +1,114 @@ +From 0fec52988b3b588f00cb0c3a10dbb011c313cb24 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 May 2025 13:00:16 -0400 +Subject: Revert "drm/amd: Stop evicting resources on APUs in suspend" + +From: Alex Deucher + +[ Upstream commit d0ce1aaa8531a4a4707711cab5721374751c51b0 ] + +This reverts commit 3a9626c816db901def438dc2513622e281186d39. + +This breaks S4 because we end up setting the s3/s0ix flags +even when we are entering s4 since prepare is used by both +flows. The causes both the S3/s0ix and s4 flags to be set +which breaks several checks in the driver which assume they +are mutually exclusive. + +Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3634 +Cc: Mario Limonciello +Reviewed-by: Mario Limonciello +Signed-off-by: Alex Deucher +(cherry picked from commit ce8f7d95899c2869b47ea6ce0b3e5bf304b2fff4) +Cc: stable@vger.kernel.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 -- + drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 18 ------------------ + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 11 ++--------- + 3 files changed, 2 insertions(+), 29 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +index 9cda2ecaf69b5..c5d706a4c7b4a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +@@ -1459,11 +1459,9 @@ static inline int amdgpu_acpi_smart_shift_update(struct drm_device *dev, + #if defined(CONFIG_ACPI) && defined(CONFIG_SUSPEND) + bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev); + bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev); +-void amdgpu_choose_low_power_state(struct amdgpu_device *adev); + #else + static inline bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) { return false; } + static inline bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev) { return false; } +-static inline void amdgpu_choose_low_power_state(struct amdgpu_device *adev) { } + #endif + + #if defined(CONFIG_DRM_AMD_DC) +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +index a6fd52aed91ab..8b2f2b921d9de 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +@@ -1525,22 +1525,4 @@ bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) + #endif /* CONFIG_AMD_PMC */ + } + +-/** +- * amdgpu_choose_low_power_state +- * +- * @adev: amdgpu_device_pointer +- * +- * Choose the target low power state for the GPU +- */ +-void amdgpu_choose_low_power_state(struct amdgpu_device *adev) +-{ +- if (adev->in_runpm) +- return; +- +- if (amdgpu_acpi_is_s0ix_active(adev)) +- adev->in_s0ix = true; +- else if (amdgpu_acpi_is_s3_active(adev)) +- adev->in_s3 = true; +-} +- + #endif /* CONFIG_SUSPEND */ +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index 9fd9424ec8f71..814142844197a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -4167,15 +4167,13 @@ int amdgpu_device_prepare(struct drm_device *dev) + struct amdgpu_device *adev = drm_to_adev(dev); + int i, r; + +- amdgpu_choose_low_power_state(adev); +- + if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) + return 0; + + /* Evict the majority of BOs before starting suspend sequence */ + r = amdgpu_device_evict_resources(adev); + if (r) +- goto unprepare; ++ return r; + + flush_delayed_work(&adev->gfx.gfx_off_delay_work); + +@@ -4186,15 +4184,10 @@ int amdgpu_device_prepare(struct drm_device *dev) + continue; + r = adev->ip_blocks[i].version->funcs->prepare_suspend((void *)adev); + if (r) +- goto unprepare; ++ return r; + } + + return 0; +- +-unprepare: +- adev->in_s0ix = adev->in_s3 = adev->in_s4 = false; +- +- return r; + } + + /** +-- +2.39.5 + diff --git a/queue-6.6/selftests-exec-build-both-static-and-non-static-load.patch b/queue-6.6/selftests-exec-build-both-static-and-non-static-load.patch new file mode 100644 index 0000000000..0ea3cfcece --- /dev/null +++ b/queue-6.6/selftests-exec-build-both-static-and-non-static-load.patch @@ -0,0 +1,182 @@ +From 0e744359a44ed60080b746120f0fa0225bd248ff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 May 2024 10:31:46 -0700 +Subject: selftests/exec: Build both static and non-static load_address tests + +From: Kees Cook + +[ Upstream commit b57a2907c9d96c56494ef25f8ec821cd0b355dd6 ] + +After commit 4d1cd3b2c5c1 ("tools/testing/selftests/exec: fix link +error"), the load address alignment tests tried to build statically. +This was silently ignored in some cases. However, after attempting to +further fix the build by switching to "-static-pie", the test started +failing. This appears to be due to non-PT_INTERP ET_DYN execs ("static +PIE") not doing alignment correctly, which remains unfixed[1]. See commit +aeb7923733d1 ("revert "fs/binfmt_elf: use PT_LOAD p_align values for +static PIE"") for more details. + +Provide rules to build both static and non-static PIE binaries, improve +debug reporting, and perform several test steps instead of a single +all-or-nothing test. However, do not actually enable static-pie tests; +alignment specification is only supported for ET_DYN with PT_INTERP +("regular PIE"). + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=215275 [1] +Link: https://lore.kernel.org/r/20240508173149.677910-1-keescook@chromium.org +Signed-off-by: Kees Cook +Stable-dep-of: 11854fe263eb ("binfmt_elf: Move brk for static PIE even if ASLR disabled") +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/exec/Makefile | 19 +++--- + tools/testing/selftests/exec/load_address.c | 67 +++++++++++++++++---- + 2 files changed, 66 insertions(+), 20 deletions(-) + +diff --git a/tools/testing/selftests/exec/Makefile b/tools/testing/selftests/exec/Makefile +index a0b8688b08369..b54986078d7ea 100644 +--- a/tools/testing/selftests/exec/Makefile ++++ b/tools/testing/selftests/exec/Makefile +@@ -3,8 +3,13 @@ CFLAGS = -Wall + CFLAGS += -Wno-nonnull + CFLAGS += -D_GNU_SOURCE + ++ALIGNS := 0x1000 0x200000 0x1000000 ++ALIGN_PIES := $(patsubst %,load_address.%,$(ALIGNS)) ++ALIGN_STATIC_PIES := $(patsubst %,load_address.static.%,$(ALIGNS)) ++ALIGNMENT_TESTS := $(ALIGN_PIES) ++ + TEST_PROGS := binfmt_script.py +-TEST_GEN_PROGS := execveat load_address_4096 load_address_2097152 load_address_16777216 non-regular ++TEST_GEN_PROGS := execveat non-regular $(ALIGNMENT_TESTS) + TEST_GEN_FILES := execveat.symlink execveat.denatured script subdir + # Makefile is a run-time dependency, since it's accessed by the execveat test + TEST_FILES := Makefile +@@ -28,9 +33,9 @@ $(OUTPUT)/execveat.symlink: $(OUTPUT)/execveat + $(OUTPUT)/execveat.denatured: $(OUTPUT)/execveat + cp $< $@ + chmod -x $@ +-$(OUTPUT)/load_address_4096: load_address.c +- $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-z,max-page-size=0x1000 -pie -static $< -o $@ +-$(OUTPUT)/load_address_2097152: load_address.c +- $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-z,max-page-size=0x200000 -pie -static $< -o $@ +-$(OUTPUT)/load_address_16777216: load_address.c +- $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-z,max-page-size=0x1000000 -pie -static $< -o $@ ++$(OUTPUT)/load_address.0x%: load_address.c ++ $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-z,max-page-size=$(lastword $(subst ., ,$@)) \ ++ -fPIE -pie $< -o $@ ++$(OUTPUT)/load_address.static.0x%: load_address.c ++ $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-z,max-page-size=$(lastword $(subst ., ,$@)) \ ++ -fPIE -static-pie $< -o $@ +diff --git a/tools/testing/selftests/exec/load_address.c b/tools/testing/selftests/exec/load_address.c +index 17e3207d34ae7..8257fddba8c8d 100644 +--- a/tools/testing/selftests/exec/load_address.c ++++ b/tools/testing/selftests/exec/load_address.c +@@ -5,11 +5,13 @@ + #include + #include + #include ++#include + #include "../kselftest.h" + + struct Statistics { + unsigned long long load_address; + unsigned long long alignment; ++ bool interp; + }; + + int ExtractStatistics(struct dl_phdr_info *info, size_t size, void *data) +@@ -26,11 +28,20 @@ int ExtractStatistics(struct dl_phdr_info *info, size_t size, void *data) + stats->alignment = 0; + + for (i = 0; i < info->dlpi_phnum; i++) { ++ unsigned long long align; ++ ++ if (info->dlpi_phdr[i].p_type == PT_INTERP) { ++ stats->interp = true; ++ continue; ++ } ++ + if (info->dlpi_phdr[i].p_type != PT_LOAD) + continue; + +- if (info->dlpi_phdr[i].p_align > stats->alignment) +- stats->alignment = info->dlpi_phdr[i].p_align; ++ align = info->dlpi_phdr[i].p_align; ++ ++ if (align > stats->alignment) ++ stats->alignment = align; + } + + return 1; // Terminate dl_iterate_phdr. +@@ -38,27 +49,57 @@ int ExtractStatistics(struct dl_phdr_info *info, size_t size, void *data) + + int main(int argc, char **argv) + { +- struct Statistics extracted; +- unsigned long long misalign; ++ struct Statistics extracted = { }; ++ unsigned long long misalign, pow2; ++ bool interp_needed; ++ char buf[1024]; ++ FILE *maps; + int ret; + + ksft_print_header(); +- ksft_set_plan(1); ++ ksft_set_plan(4); ++ ++ /* Dump maps file for debugging reference. */ ++ maps = fopen("/proc/self/maps", "r"); ++ if (!maps) ++ ksft_exit_fail_msg("FAILED: /proc/self/maps: %s\n", strerror(errno)); ++ while (fgets(buf, sizeof(buf), maps)) { ++ ksft_print_msg("%s", buf); ++ } ++ fclose(maps); + ++ /* Walk the program headers. */ + ret = dl_iterate_phdr(ExtractStatistics, &extracted); + if (ret != 1) + ksft_exit_fail_msg("FAILED: dl_iterate_phdr\n"); + +- if (extracted.alignment == 0) +- ksft_exit_fail_msg("FAILED: No alignment found\n"); +- else if (extracted.alignment & (extracted.alignment - 1)) +- ksft_exit_fail_msg("FAILED: Alignment is not a power of 2\n"); ++ /* Report our findings. */ ++ ksft_print_msg("load_address=%#llx alignment=%#llx\n", ++ extracted.load_address, extracted.alignment); ++ ++ /* If we're named with ".static." we expect no INTERP. */ ++ interp_needed = strstr(argv[0], ".static.") == NULL; ++ ++ /* Were we built as expected? */ ++ ksft_test_result(interp_needed == extracted.interp, ++ "%s INTERP program header %s\n", ++ interp_needed ? "Wanted" : "Unwanted", ++ extracted.interp ? "seen" : "missing"); ++ ++ /* Did we find an alignment? */ ++ ksft_test_result(extracted.alignment != 0, ++ "Alignment%s found\n", extracted.alignment ? "" : " NOT"); ++ ++ /* Is the alignment sane? */ ++ pow2 = extracted.alignment & (extracted.alignment - 1); ++ ksft_test_result(pow2 == 0, ++ "Alignment is%s a power of 2: %#llx\n", ++ pow2 == 0 ? "" : " NOT", extracted.alignment); + ++ /* Is the load address aligned? */ + misalign = extracted.load_address & (extracted.alignment - 1); +- if (misalign) +- ksft_exit_fail_msg("FAILED: alignment = %llu, load_address = %llu\n", +- extracted.alignment, extracted.load_address); ++ ksft_test_result(misalign == 0, "Load Address is %saligned (%#llx)\n", ++ misalign ? "MIS" : "", misalign); + +- ksft_test_result_pass("Completed\n"); + ksft_finished(); + } +-- +2.39.5 + diff --git a/queue-6.6/selftests-exec-load_address-conform-test-to-tap-form.patch b/queue-6.6/selftests-exec-load_address-conform-test-to-tap-form.patch new file mode 100644 index 0000000000..3d91528e4a --- /dev/null +++ b/queue-6.6/selftests-exec-load_address-conform-test-to-tap-form.patch @@ -0,0 +1,79 @@ +From 8073d1922ca6e68a6de9abfed9b19b4ed2c84451 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Mar 2024 20:59:24 +0500 +Subject: selftests/exec: load_address: conform test to TAP format output + +From: Muhammad Usama Anjum + +[ Upstream commit c4095067736b7ed50316a2bc7c9577941e87ad45 ] + +Conform the layout, informational and status messages to TAP. No +functional change is intended other than the layout of output messages. + +Signed-off-by: Muhammad Usama Anjum +Link: https://lore.kernel.org/r/20240304155928.1818928-2-usama.anjum@collabora.com +Signed-off-by: Kees Cook +Stable-dep-of: 11854fe263eb ("binfmt_elf: Move brk for static PIE even if ASLR disabled") +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/exec/load_address.c | 34 +++++++++------------ + 1 file changed, 15 insertions(+), 19 deletions(-) + +diff --git a/tools/testing/selftests/exec/load_address.c b/tools/testing/selftests/exec/load_address.c +index d487c2f6a6150..17e3207d34ae7 100644 +--- a/tools/testing/selftests/exec/load_address.c ++++ b/tools/testing/selftests/exec/load_address.c +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include "../kselftest.h" + + struct Statistics { + unsigned long long load_address; +@@ -41,28 +42,23 @@ int main(int argc, char **argv) + unsigned long long misalign; + int ret; + ++ ksft_print_header(); ++ ksft_set_plan(1); ++ + ret = dl_iterate_phdr(ExtractStatistics, &extracted); +- if (ret != 1) { +- fprintf(stderr, "FAILED\n"); +- return 1; +- } ++ if (ret != 1) ++ ksft_exit_fail_msg("FAILED: dl_iterate_phdr\n"); + +- if (extracted.alignment == 0) { +- fprintf(stderr, "No alignment found\n"); +- return 1; +- } else if (extracted.alignment & (extracted.alignment - 1)) { +- fprintf(stderr, "Alignment is not a power of 2\n"); +- return 1; +- } ++ if (extracted.alignment == 0) ++ ksft_exit_fail_msg("FAILED: No alignment found\n"); ++ else if (extracted.alignment & (extracted.alignment - 1)) ++ ksft_exit_fail_msg("FAILED: Alignment is not a power of 2\n"); + + misalign = extracted.load_address & (extracted.alignment - 1); +- if (misalign) { +- printf("alignment = %llu, load_address = %llu\n", +- extracted.alignment, extracted.load_address); +- fprintf(stderr, "FAILED\n"); +- return 1; +- } ++ if (misalign) ++ ksft_exit_fail_msg("FAILED: alignment = %llu, load_address = %llu\n", ++ extracted.alignment, extracted.load_address); + +- fprintf(stderr, "PASS\n"); +- return 0; ++ ksft_test_result_pass("Completed\n"); ++ ksft_finished(); + } +-- +2.39.5 + diff --git a/queue-6.6/series b/queue-6.6/series new file mode 100644 index 0000000000..3354501d7b --- /dev/null +++ b/queue-6.6/series @@ -0,0 +1,60 @@ +fs-xattr.c-fix-simple_xattr_list-to-always-include-s.patch +binfmt_elf-support-segments-with-0-filesz-and-misali.patch +binfmt_elf-elf_bss-no-longer-used-by-load_elf_binary.patch +selftests-exec-load_address-conform-test-to-tap-form.patch +binfmt_elf-leave-a-gap-between-.bss-and-brk.patch +selftests-exec-build-both-static-and-non-static-load.patch +binfmt_elf-calculate-total_size-earlier.patch +binfmt_elf-honor-pt_load-alignment-for-static-pie.patch +binfmt_elf-move-brk-for-static-pie-even-if-aslr-disa.patch +platform-x86-amd-pmc-declare-quirk_spurious_8042-for.patch +platform-x86-asus-wmi-fix-wlan_ctrl_by_user-detectio.patch +cgroup-cpuset-extend-kthread_is_per_cpu-check-to-all.patch +tracing-probes-fix-a-possible-race-in-trace_probe_lo.patch +tpm-tis-double-the-timeout-b-to-4s.patch +firmware-arm_scmi-add-helper-to-trace-bad-messages.patch +firmware-arm_scmi-add-message-dump-traces-for-bad-an.patch +firmware-arm_scmi-add-support-for-debug-metrics-at-t.patch +firmware-arm_scmi-track-basic-scmi-communication-deb.patch +firmware-arm_scmi-fix-timeout-checks-on-polling-path.patch +kvm-svm-update-sev-es-shutdown-intercepts-with-more-.patch +kvm-svm-forcibly-leave-smm-mode-on-shutdown-intercep.patch +iio-adc-ad7266-fix-potential-timestamp-alignment-iss.patch +drm-amd-stop-evicting-resources-on-apus-in-suspend.patch +drm-amdgpu-fix-the-runtime-resume-failure-issue.patch +drm-amdgpu-trigger-flr_work-if-reading-pf2vf-data-fa.patch +drm-amd-add-suspend-hibernate-notification-callback-.patch +revert-drm-amd-stop-evicting-resources-on-apus-in-su.patch +iio-adc-ad7768-1-fix-insufficient-alignment-of-times.patch +iio-chemical-sps30-use-aligned_s64-for-timestamp.patch +rdma-rxe-fix-slab-use-after-free-read-in-rxe_queue_c.patch +hid-thrustmaster-fix-memory-leak-in-thrustmaster_int.patch +hid-uclogic-add-null-check-in-uclogic_input_configur.patch +nfs-handle-failure-of-nfs_get_lock_context-in-unlock.patch +spi-loopback-test-do-not-split-1024-byte-hexdumps.patch +bluetooth-mgmt-fix-mgmt_op_add_device-invalid-device.patch +net_sched-flush-gso_skb-list-too-during-change.patch +tools-ynl-ethtool.py-output-timestamping-statistics-.patch +tools-net-ynl-ethtool-fix-crash-when-hardware-clock-.patch +mctp-no-longer-rely-on-net-dev_index_head.patch +net-mctp-don-t-access-ifa_index-when-missing.patch +net-mctp-ensure-keys-maintain-only-one-ref-to-corres.patch +alsa-seq-fix-delivery-of-ump-events-to-group-ports.patch +alsa-ump-fix-a-typo-of-snd_ump_stream_msg_device_inf.patch +net-cadence-macb-fix-a-possible-deadlock-in-macb_hal.patch +net-dsa-sja1105-discard-incoming-frames-in-br_state_.patch +nvme-pci-make-nvme_pci_npages_prp-__always_inline.patch +nvme-pci-acquire-cq_poll_lock-in-nvme_poll_irqdisabl.patch +alsa-sh-snd_aica-should-depend-on-sh_dma_api.patch +net-mlx5e-disable-macsec-offload-for-uplink-represen.patch +qlcnic-fix-memory-leak-in-qlcnic_sriov_channel_cfg_c.patch +regulator-max20086-fix-invalid-memory-access.patch +octeontx2-pf-macsec-fix-incorrect-max-transmit-size-.patch +net-ethernet-mtk_eth_soc-fix-typo-for-declaration-mt.patch +octeontx2-af-fix-cgx-receive-counters.patch +wifi-mac80211-set-n_channels-after-allocating-struct.patch +mlxsw-spectrum_router-fix-use-after-free-when-deleti.patch +net-tls-fix-kernel-panic-when-alloc_page-failed.patch +tsnep-inline-small-fragments-within-tx-descriptor.patch +tsnep-fix-timestamping-with-a-stacked-dsa-driver.patch +nfsv4-pnfs-reset-the-layout-state-after-a-layoutretu.patch diff --git a/queue-6.6/spi-loopback-test-do-not-split-1024-byte-hexdumps.patch b/queue-6.6/spi-loopback-test-do-not-split-1024-byte-hexdumps.patch new file mode 100644 index 0000000000..9cd72a3855 --- /dev/null +++ b/queue-6.6/spi-loopback-test-do-not-split-1024-byte-hexdumps.patch @@ -0,0 +1,43 @@ +From 2a823c0ae6fc67de0c020bac62ea0d557f55de71 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 May 2025 13:10:35 +0200 +Subject: spi: loopback-test: Do not split 1024-byte hexdumps + +From: Geert Uytterhoeven + +[ Upstream commit a73fa3690a1f3014d6677e368dce4e70767a6ba2 ] + +spi_test_print_hex_dump() prints buffers holding less than 1024 bytes in +full. Larger buffers are truncated: only the first 512 and the last 512 +bytes are printed, separated by a truncation message. The latter is +confusing in case the buffer holds exactly 1024 bytes, as all data is +printed anyway. + +Fix this by printing buffers holding up to and including 1024 bytes in +full. + +Fixes: 84e0c4e5e2c4ef42 ("spi: add loopback test driver to allow for spi_master regression tests") +Signed-off-by: Geert Uytterhoeven +Link: https://patch.msgid.link/37ee1bc90c6554c9347040adabf04188c8f704aa.1746184171.git.geert+renesas@glider.be +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-loopback-test.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-loopback-test.c b/drivers/spi/spi-loopback-test.c +index bbf2015d8e5cc..69b6c87c5525e 100644 +--- a/drivers/spi/spi-loopback-test.c ++++ b/drivers/spi/spi-loopback-test.c +@@ -421,7 +421,7 @@ MODULE_LICENSE("GPL"); + static void spi_test_print_hex_dump(char *pre, const void *ptr, size_t len) + { + /* limit the hex_dump */ +- if (len < 1024) { ++ if (len <= 1024) { + print_hex_dump(KERN_INFO, pre, + DUMP_PREFIX_OFFSET, 16, 1, + ptr, len, 0); +-- +2.39.5 + diff --git a/queue-6.6/tools-net-ynl-ethtool-fix-crash-when-hardware-clock-.patch b/queue-6.6/tools-net-ynl-ethtool-fix-crash-when-hardware-clock-.patch new file mode 100644 index 0000000000..4429363892 --- /dev/null +++ b/queue-6.6/tools-net-ynl-ethtool-fix-crash-when-hardware-clock-.patch @@ -0,0 +1,71 @@ +From 81dd350fc73849c62bbc9acb5dc0aec303d5c411 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 May 2025 03:54:14 +0000 +Subject: tools/net/ynl: ethtool: fix crash when Hardware Clock info is missing + +From: Hangbin Liu + +[ Upstream commit 45375814eb3f4245956c0c85092a4eee4441d167 ] + +Fix a crash in the ethtool YNL implementation when Hardware Clock information +is not present in the response. This ensures graceful handling of devices or +drivers that do not provide this optional field. e.g. + + Traceback (most recent call last): + File "/net/tools/net/ynl/pyynl/./ethtool.py", line 438, in + main() + ~~~~^^ + File "/net/tools/net/ynl/pyynl/./ethtool.py", line 341, in main + print(f'PTP Hardware Clock: {tsinfo["phc-index"]}') + ~~~~~~^^^^^^^^^^^^^ + KeyError: 'phc-index' + +Fixes: f3d07b02b2b8 ("tools: ynl: ethtool testing tool") +Signed-off-by: Hangbin Liu +Acked-by: Stanislav Fomichev +Link: https://patch.msgid.link/20250508035414.82974-1-liuhangbin@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/net/ynl/ethtool.py | 22 +++++++++++++++------- + 1 file changed, 15 insertions(+), 7 deletions(-) + +diff --git a/tools/net/ynl/ethtool.py b/tools/net/ynl/ethtool.py +index 47264ae20036b..ffd8eb6d19048 100755 +--- a/tools/net/ynl/ethtool.py ++++ b/tools/net/ynl/ethtool.py +@@ -333,16 +333,24 @@ def main(): + print('Capabilities:') + [print(f'\t{v}') for v in bits_to_dict(tsinfo['timestamping'])] + +- print(f'PTP Hardware Clock: {tsinfo["phc-index"]}') ++ print(f'PTP Hardware Clock: {tsinfo.get("phc-index", "none")}') + +- print('Hardware Transmit Timestamp Modes:') +- [print(f'\t{v}') for v in bits_to_dict(tsinfo['tx-types'])] ++ if 'tx-types' in tsinfo: ++ print('Hardware Transmit Timestamp Modes:') ++ [print(f'\t{v}') for v in bits_to_dict(tsinfo['tx-types'])] ++ else: ++ print('Hardware Transmit Timestamp Modes: none') ++ ++ if 'rx-filters' in tsinfo: ++ print('Hardware Receive Filter Modes:') ++ [print(f'\t{v}') for v in bits_to_dict(tsinfo['rx-filters'])] ++ else: ++ print('Hardware Receive Filter Modes: none') + +- print('Hardware Receive Filter Modes:') +- [print(f'\t{v}') for v in bits_to_dict(tsinfo['rx-filters'])] ++ if 'stats' in tsinfo and tsinfo['stats']: ++ print('Statistics:') ++ [print(f'\t{k}: {v}') for k, v in tsinfo['stats'].items()] + +- print('Statistics:') +- [print(f'\t{k}: {v}') for k, v in tsinfo['stats'].items()] + return + + print(f'Settings for {args.device}:') +-- +2.39.5 + diff --git a/queue-6.6/tools-ynl-ethtool.py-output-timestamping-statistics-.patch b/queue-6.6/tools-ynl-ethtool.py-output-timestamping-statistics-.patch new file mode 100644 index 0000000000..0398202c8e --- /dev/null +++ b/queue-6.6/tools-ynl-ethtool.py-output-timestamping-statistics-.patch @@ -0,0 +1,73 @@ +From bce5b5d48db5b09c264a12c9aaef23363e5fe595 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Apr 2024 14:28:45 -0700 +Subject: tools: ynl: ethtool.py: Output timestamping statistics from + tsinfo-get operation + +From: Rahul Rameshbabu + +[ Upstream commit 2e0e148c727061009d3db5f436f51890bbb49a80 ] + +Print the nested stats attribute containing timestamping statistics when +the --show-time-stamping flag is used. + + [root@binary-eater-vm-01 linux-ethtool-ts]# ./tools/net/ynl/ethtool.py --show-time-stamping mlx5_1 + Time stamping parameters for mlx5_1: + Capabilities: + hardware-transmit + hardware-receive + hardware-raw-clock + PTP Hardware Clock: 0 + Hardware Transmit Timestamp Modes: + off + on + Hardware Receive Filter Modes: + none + all + Statistics: + tx-pkts: 8 + tx-lost: 0 + tx-err: 0 + +Signed-off-by: Rahul Rameshbabu +Reviewed-by: Dragos Tatulea +Link: https://lore.kernel.org/r/20240403212931.128541-8-rrameshbabu@nvidia.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 45375814eb3f ("tools/net/ynl: ethtool: fix crash when Hardware Clock info is missing") +Signed-off-by: Sasha Levin +--- + tools/net/ynl/ethtool.py | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/tools/net/ynl/ethtool.py b/tools/net/ynl/ethtool.py +index 6c9f7e31250cd..47264ae20036b 100755 +--- a/tools/net/ynl/ethtool.py ++++ b/tools/net/ynl/ethtool.py +@@ -320,7 +320,13 @@ def main(): + return + + if args.show_time_stamping: +- tsinfo = dumpit(ynl, args, 'tsinfo-get') ++ req = { ++ 'header': { ++ 'flags': 'stats', ++ }, ++ } ++ ++ tsinfo = dumpit(ynl, args, 'tsinfo-get', req) + + print(f'Time stamping parameters for {args.device}:') + +@@ -334,6 +340,9 @@ def main(): + + print('Hardware Receive Filter Modes:') + [print(f'\t{v}') for v in bits_to_dict(tsinfo['rx-filters'])] ++ ++ print('Statistics:') ++ [print(f'\t{k}: {v}') for k, v in tsinfo['stats'].items()] + return + + print(f'Settings for {args.device}:') +-- +2.39.5 + diff --git a/queue-6.6/tpm-tis-double-the-timeout-b-to-4s.patch b/queue-6.6/tpm-tis-double-the-timeout-b-to-4s.patch new file mode 100644 index 0000000000..cfb18f8929 --- /dev/null +++ b/queue-6.6/tpm-tis-double-the-timeout-b-to-4s.patch @@ -0,0 +1,76 @@ +From 0d1ab8d2662a0f1b0e047e49620ebe7b4e0916e5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Apr 2025 10:23:14 +0200 +Subject: tpm: tis: Double the timeout B to 4s + +From: Michal Suchanek + +[ Upstream commit 2f661f71fda1fc0c42b7746ca5b7da529eb6b5be ] + +With some Infineon chips the timeouts in tpm_tis_send_data (both B and +C) can reach up to about 2250 ms. + +Timeout C is retried since +commit de9e33df7762 ("tpm, tpm_tis: Workaround failed command reception on Infineon devices") + +Timeout B still needs to be extended. + +The problem is most commonly encountered with context related operation +such as load context/save context. These are issued directly by the +kernel, and there is no retry logic for them. + +When a filesystem is set up to use the TPM for unlocking the boot fails, +and restarting the userspace service is ineffective. This is likely +because ignoring a load context/save context result puts the real TPM +state and the TPM state expected by the kernel out of sync. + +Chips known to be affected: +tpm_tis IFX1522:00: 2.0 TPM (device-id 0x1D, rev-id 54) +Description: SLB9672 +Firmware Revision: 15.22 + +tpm_tis MSFT0101:00: 2.0 TPM (device-id 0x1B, rev-id 22) +Firmware Revision: 7.83 + +tpm_tis MSFT0101:00: 2.0 TPM (device-id 0x1A, rev-id 16) +Firmware Revision: 5.63 + +Link: https://lore.kernel.org/linux-integrity/Z5pI07m0Muapyu9w@kitsune.suse.cz/ +Signed-off-by: Michal Suchanek +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: Sasha Levin +--- + drivers/char/tpm/tpm_tis_core.h | 2 +- + include/linux/tpm.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h +index 369496a6aebf1..27e61ddfb6229 100644 +--- a/drivers/char/tpm/tpm_tis_core.h ++++ b/drivers/char/tpm/tpm_tis_core.h +@@ -54,7 +54,7 @@ enum tis_int_flags { + enum tis_defaults { + TIS_MEM_LEN = 0x5000, + TIS_SHORT_TIMEOUT = 750, /* ms */ +- TIS_LONG_TIMEOUT = 2000, /* 2 sec */ ++ TIS_LONG_TIMEOUT = 4000, /* 4 secs */ + TIS_TIMEOUT_MIN_ATML = 14700, /* usecs */ + TIS_TIMEOUT_MAX_ATML = 15000, /* usecs */ + }; +diff --git a/include/linux/tpm.h b/include/linux/tpm.h +index 5f4998626a988..bf8a4ec8a01c1 100644 +--- a/include/linux/tpm.h ++++ b/include/linux/tpm.h +@@ -181,7 +181,7 @@ enum tpm2_const { + + enum tpm2_timeouts { + TPM2_TIMEOUT_A = 750, +- TPM2_TIMEOUT_B = 2000, ++ TPM2_TIMEOUT_B = 4000, + TPM2_TIMEOUT_C = 200, + TPM2_TIMEOUT_D = 30, + TPM2_DURATION_SHORT = 20, +-- +2.39.5 + diff --git a/queue-6.6/tracing-probes-fix-a-possible-race-in-trace_probe_lo.patch b/queue-6.6/tracing-probes-fix-a-possible-race-in-trace_probe_lo.patch new file mode 100644 index 0000000000..ece4fb57ca --- /dev/null +++ b/queue-6.6/tracing-probes-fix-a-possible-race-in-trace_probe_lo.patch @@ -0,0 +1,153 @@ +From e5a8d085da38f5ebc5aa6ba80108cdcd5dbe4d27 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 10 May 2025 12:44:41 +0900 +Subject: tracing: probes: Fix a possible race in trace_probe_log APIs + +From: Masami Hiramatsu (Google) + +[ Upstream commit fd837de3c9cb1a162c69bc1fb1f438467fe7f2f5 ] + +Since the shared trace_probe_log variable can be accessed and +modified via probe event create operation of kprobe_events, +uprobe_events, and dynamic_events, it should be protected. +In the dynamic_events, all operations are serialized by +`dyn_event_ops_mutex`. But kprobe_events and uprobe_events +interfaces are not serialized. + +To solve this issue, introduces dyn_event_create(), which runs +create() operation under the mutex, for kprobe_events and +uprobe_events. This also uses lockdep to check the mutex is +held when using trace_probe_log* APIs. + +Link: https://lore.kernel.org/all/174684868120.551552.3068655787654268804.stgit@devnote2/ + +Reported-by: Paul Cacheux +Closes: https://lore.kernel.org/all/20250510074456.805a16872b591e2971a4d221@kernel.org/ +Fixes: ab105a4fb894 ("tracing: Use tracing error_log with probe events") +Signed-off-by: Masami Hiramatsu (Google) +Signed-off-by: Sasha Levin +--- + kernel/trace/trace_dynevent.c | 16 +++++++++++++++- + kernel/trace/trace_dynevent.h | 1 + + kernel/trace/trace_kprobe.c | 2 +- + kernel/trace/trace_probe.c | 9 +++++++++ + kernel/trace/trace_uprobe.c | 2 +- + 5 files changed, 27 insertions(+), 3 deletions(-) + +diff --git a/kernel/trace/trace_dynevent.c b/kernel/trace/trace_dynevent.c +index 4376887e0d8aa..c9b0533407ede 100644 +--- a/kernel/trace/trace_dynevent.c ++++ b/kernel/trace/trace_dynevent.c +@@ -16,7 +16,7 @@ + #include "trace_output.h" /* for trace_event_sem */ + #include "trace_dynevent.h" + +-static DEFINE_MUTEX(dyn_event_ops_mutex); ++DEFINE_MUTEX(dyn_event_ops_mutex); + static LIST_HEAD(dyn_event_ops_list); + + bool trace_event_dyn_try_get_ref(struct trace_event_call *dyn_call) +@@ -125,6 +125,20 @@ int dyn_event_release(const char *raw_command, struct dyn_event_operations *type + return ret; + } + ++/* ++ * Locked version of event creation. The event creation must be protected by ++ * dyn_event_ops_mutex because of protecting trace_probe_log. ++ */ ++int dyn_event_create(const char *raw_command, struct dyn_event_operations *type) ++{ ++ int ret; ++ ++ mutex_lock(&dyn_event_ops_mutex); ++ ret = type->create(raw_command); ++ mutex_unlock(&dyn_event_ops_mutex); ++ return ret; ++} ++ + static int create_dyn_event(const char *raw_command) + { + struct dyn_event_operations *ops; +diff --git a/kernel/trace/trace_dynevent.h b/kernel/trace/trace_dynevent.h +index 936477a111d3e..beee3f8d75444 100644 +--- a/kernel/trace/trace_dynevent.h ++++ b/kernel/trace/trace_dynevent.h +@@ -100,6 +100,7 @@ void *dyn_event_seq_next(struct seq_file *m, void *v, loff_t *pos); + void dyn_event_seq_stop(struct seq_file *m, void *v); + int dyn_events_release_all(struct dyn_event_operations *type); + int dyn_event_release(const char *raw_command, struct dyn_event_operations *type); ++int dyn_event_create(const char *raw_command, struct dyn_event_operations *type); + + /* + * for_each_dyn_event - iterate over the dyn_event list +diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c +index 508c10414a934..46491f3c1569c 100644 +--- a/kernel/trace/trace_kprobe.c ++++ b/kernel/trace/trace_kprobe.c +@@ -1004,7 +1004,7 @@ static int create_or_delete_trace_kprobe(const char *raw_command) + if (raw_command[0] == '-') + return dyn_event_release(raw_command, &trace_kprobe_ops); + +- ret = trace_kprobe_create(raw_command); ++ ret = dyn_event_create(raw_command, &trace_kprobe_ops); + return ret == -ECANCELED ? -EINVAL : ret; + } + +diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c +index 606190239c877..694f32d843d90 100644 +--- a/kernel/trace/trace_probe.c ++++ b/kernel/trace/trace_probe.c +@@ -153,9 +153,12 @@ static const struct fetch_type *find_fetch_type(const char *type, unsigned long + } + + static struct trace_probe_log trace_probe_log; ++extern struct mutex dyn_event_ops_mutex; + + void trace_probe_log_init(const char *subsystem, int argc, const char **argv) + { ++ lockdep_assert_held(&dyn_event_ops_mutex); ++ + trace_probe_log.subsystem = subsystem; + trace_probe_log.argc = argc; + trace_probe_log.argv = argv; +@@ -164,11 +167,15 @@ void trace_probe_log_init(const char *subsystem, int argc, const char **argv) + + void trace_probe_log_clear(void) + { ++ lockdep_assert_held(&dyn_event_ops_mutex); ++ + memset(&trace_probe_log, 0, sizeof(trace_probe_log)); + } + + void trace_probe_log_set_index(int index) + { ++ lockdep_assert_held(&dyn_event_ops_mutex); ++ + trace_probe_log.index = index; + } + +@@ -177,6 +184,8 @@ void __trace_probe_log_err(int offset, int err_type) + char *command, *p; + int i, len = 0, pos = 0; + ++ lockdep_assert_held(&dyn_event_ops_mutex); ++ + if (!trace_probe_log.argv) + return; + +diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c +index 79f8da7e3cd49..ecf04e81ddf70 100644 +--- a/kernel/trace/trace_uprobe.c ++++ b/kernel/trace/trace_uprobe.c +@@ -730,7 +730,7 @@ static int create_or_delete_trace_uprobe(const char *raw_command) + if (raw_command[0] == '-') + return dyn_event_release(raw_command, &trace_uprobe_ops); + +- ret = trace_uprobe_create(raw_command); ++ ret = dyn_event_create(raw_command, &trace_uprobe_ops); + return ret == -ECANCELED ? -EINVAL : ret; + } + +-- +2.39.5 + diff --git a/queue-6.6/tsnep-fix-timestamping-with-a-stacked-dsa-driver.patch b/queue-6.6/tsnep-fix-timestamping-with-a-stacked-dsa-driver.patch new file mode 100644 index 0000000000..11a7d79e45 --- /dev/null +++ b/queue-6.6/tsnep-fix-timestamping-with-a-stacked-dsa-driver.patch @@ -0,0 +1,133 @@ +From 1b162c9c797651515ca6f7e01e2f5b35288eaeed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 May 2025 21:56:57 +0200 +Subject: tsnep: fix timestamping with a stacked DSA driver + +From: Gerhard Engleder + +[ Upstream commit b3ca9eef6646576ad506a96d941d87a69f66732a ] + +This driver is susceptible to a form of the bug explained in commit +c26a2c2ddc01 ("gianfar: Fix TX timestamping with a stacked DSA driver") +and in Documentation/networking/timestamping.rst section "Other caveats +for MAC drivers", specifically it timestamps any skb which has +SKBTX_HW_TSTAMP, and does not consider if timestamping has been enabled +in adapter->hwtstamp_config.tx_type. + +Evaluate the proper TX timestamping condition only once on the TX +path (in tsnep_xmit_frame_ring()) and store the result in an additional +TX entry flag. Evaluate the new TX entry flag in the TX confirmation path +(in tsnep_tx_poll()). + +This way SKBTX_IN_PROGRESS is set by the driver as required, but never +evaluated. SKBTX_IN_PROGRESS shall not be evaluated as it can be set +by a stacked DSA driver and evaluating it would lead to unwanted +timestamps. + +Fixes: 403f69bbdbad ("tsnep: Add TSN endpoint Ethernet MAC driver") +Suggested-by: Vladimir Oltean +Signed-off-by: Gerhard Engleder +Reviewed-by: Vladimir Oltean +Link: https://patch.msgid.link/20250514195657.25874-1-gerhard@engleder-embedded.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/engleder/tsnep_main.c | 30 ++++++++++++++-------- + 1 file changed, 19 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/ethernet/engleder/tsnep_main.c b/drivers/net/ethernet/engleder/tsnep_main.c +index d8711e1511e47..215ae6745932a 100644 +--- a/drivers/net/ethernet/engleder/tsnep_main.c ++++ b/drivers/net/ethernet/engleder/tsnep_main.c +@@ -67,6 +67,8 @@ + #define TSNEP_TX_TYPE_XDP_NDO_MAP_PAGE (TSNEP_TX_TYPE_XDP_NDO | TSNEP_TX_TYPE_MAP_PAGE) + #define TSNEP_TX_TYPE_XDP (TSNEP_TX_TYPE_XDP_TX | TSNEP_TX_TYPE_XDP_NDO) + #define TSNEP_TX_TYPE_XSK BIT(12) ++#define TSNEP_TX_TYPE_TSTAMP BIT(13) ++#define TSNEP_TX_TYPE_SKB_TSTAMP (TSNEP_TX_TYPE_SKB | TSNEP_TX_TYPE_TSTAMP) + + #define TSNEP_XDP_TX BIT(0) + #define TSNEP_XDP_REDIRECT BIT(1) +@@ -385,8 +387,7 @@ static void tsnep_tx_activate(struct tsnep_tx *tx, int index, int length, + if (entry->skb) { + entry->properties = length & TSNEP_DESC_LENGTH_MASK; + entry->properties |= TSNEP_DESC_INTERRUPT_FLAG; +- if ((entry->type & TSNEP_TX_TYPE_SKB) && +- (skb_shinfo(entry->skb)->tx_flags & SKBTX_IN_PROGRESS)) ++ if ((entry->type & TSNEP_TX_TYPE_SKB_TSTAMP) == TSNEP_TX_TYPE_SKB_TSTAMP) + entry->properties |= TSNEP_DESC_EXTENDED_WRITEBACK_FLAG; + + /* toggle user flag to prevent false acknowledge +@@ -478,7 +479,8 @@ static int tsnep_tx_map_frag(skb_frag_t *frag, struct tsnep_tx_entry *entry, + return mapped; + } + +-static int tsnep_tx_map(struct sk_buff *skb, struct tsnep_tx *tx, int count) ++static int tsnep_tx_map(struct sk_buff *skb, struct tsnep_tx *tx, int count, ++ bool do_tstamp) + { + struct device *dmadev = tx->adapter->dmadev; + struct tsnep_tx_entry *entry; +@@ -504,6 +506,9 @@ static int tsnep_tx_map(struct sk_buff *skb, struct tsnep_tx *tx, int count) + entry->type = TSNEP_TX_TYPE_SKB_INLINE; + mapped = 0; + } ++ ++ if (do_tstamp) ++ entry->type |= TSNEP_TX_TYPE_TSTAMP; + } else { + skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1]; + +@@ -557,11 +562,12 @@ static int tsnep_tx_unmap(struct tsnep_tx *tx, int index, int count) + static netdev_tx_t tsnep_xmit_frame_ring(struct sk_buff *skb, + struct tsnep_tx *tx) + { +- int count = 1; + struct tsnep_tx_entry *entry; ++ bool do_tstamp = false; ++ int count = 1; + int length; +- int i; + int retval; ++ int i; + + if (skb_shinfo(skb)->nr_frags > 0) + count += skb_shinfo(skb)->nr_frags; +@@ -578,7 +584,13 @@ static netdev_tx_t tsnep_xmit_frame_ring(struct sk_buff *skb, + entry = &tx->entry[tx->write]; + entry->skb = skb; + +- retval = tsnep_tx_map(skb, tx, count); ++ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && ++ tx->adapter->hwtstamp_config.tx_type == HWTSTAMP_TX_ON) { ++ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; ++ do_tstamp = true; ++ } ++ ++ retval = tsnep_tx_map(skb, tx, count, do_tstamp); + if (retval < 0) { + tsnep_tx_unmap(tx, tx->write, count); + dev_kfree_skb_any(entry->skb); +@@ -590,9 +602,6 @@ static netdev_tx_t tsnep_xmit_frame_ring(struct sk_buff *skb, + } + length = retval; + +- if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) +- skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; +- + for (i = 0; i < count; i++) + tsnep_tx_activate(tx, (tx->write + i) & TSNEP_RING_MASK, length, + i == count - 1); +@@ -843,8 +852,7 @@ static bool tsnep_tx_poll(struct tsnep_tx *tx, int napi_budget) + + length = tsnep_tx_unmap(tx, tx->read, count); + +- if ((entry->type & TSNEP_TX_TYPE_SKB) && +- (skb_shinfo(entry->skb)->tx_flags & SKBTX_IN_PROGRESS) && ++ if (((entry->type & TSNEP_TX_TYPE_SKB_TSTAMP) == TSNEP_TX_TYPE_SKB_TSTAMP) && + (__le32_to_cpu(entry->desc_wb->properties) & + TSNEP_DESC_EXTENDED_WRITEBACK_FLAG)) { + struct skb_shared_hwtstamps hwtstamps; +-- +2.39.5 + diff --git a/queue-6.6/tsnep-inline-small-fragments-within-tx-descriptor.patch b/queue-6.6/tsnep-inline-small-fragments-within-tx-descriptor.patch new file mode 100644 index 0000000000..d9becc013e --- /dev/null +++ b/queue-6.6/tsnep-inline-small-fragments-within-tx-descriptor.patch @@ -0,0 +1,219 @@ +From c615d283a379375d867dccf477d548af9553f208 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 20:21:54 +0200 +Subject: tsnep: Inline small fragments within TX descriptor + +From: Gerhard Engleder + +[ Upstream commit dccce1d7c04051bc25d3abbe7716d0ae7af9c28a ] + +The tsnep network controller is able to extend the descriptor directly +with data to be transmitted. In this case no TX data DMA address is +necessary. Instead of the TX data DMA address the TX data buffer is +placed at the end of the descriptor. + +The descriptor is read with a 64 bytes DMA read by the tsnep network +controller. If the sum of descriptor data and TX data is less than or +equal to 64 bytes, then no additional DMA read is necessary to read the +TX data. Therefore, it makes sense to inline small fragments up to this +limit within the descriptor ring. + +Inlined fragments need to be copied to the descriptor ring. On the other +hand DMA mapping is not necessary. At most 40 bytes are copied, so +copying should be faster than DMA mapping. + +For A53 1.2 GHz copying takes <100ns and DMA mapping takes >200ns. So +inlining small fragments should result in lower CPU load. Performance +improvement is small. Thus, comparision of CPU load with and without +inlining of small fragments did not show any significant difference. +With this optimization less DMA reads will be done, which decreases the +load of the interconnect. + +Signed-off-by: Gerhard Engleder +Signed-off-by: David S. Miller +Stable-dep-of: b3ca9eef6646 ("tsnep: fix timestamping with a stacked DSA driver") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/engleder/tsnep_hw.h | 2 + + drivers/net/ethernet/engleder/tsnep_main.c | 103 +++++++++++++++------ + 2 files changed, 79 insertions(+), 26 deletions(-) + +diff --git a/drivers/net/ethernet/engleder/tsnep_hw.h b/drivers/net/ethernet/engleder/tsnep_hw.h +index 55e1caf193a69..64c97eb66f671 100644 +--- a/drivers/net/ethernet/engleder/tsnep_hw.h ++++ b/drivers/net/ethernet/engleder/tsnep_hw.h +@@ -181,6 +181,8 @@ struct tsnep_gcl_operation { + #define TSNEP_DESC_SIZE 256 + #define TSNEP_DESC_SIZE_DATA_AFTER 2048 + #define TSNEP_DESC_OFFSET 128 ++#define TSNEP_DESC_SIZE_DATA_AFTER_INLINE (64 - sizeof(struct tsnep_tx_desc) + \ ++ sizeof_field(struct tsnep_tx_desc, tx)) + #define TSNEP_DESC_OWNER_COUNTER_MASK 0xC0000000 + #define TSNEP_DESC_OWNER_COUNTER_SHIFT 30 + #define TSNEP_DESC_LENGTH_MASK 0x00003FFF +diff --git a/drivers/net/ethernet/engleder/tsnep_main.c b/drivers/net/ethernet/engleder/tsnep_main.c +index 4f36b29d66c86..d8711e1511e47 100644 +--- a/drivers/net/ethernet/engleder/tsnep_main.c ++++ b/drivers/net/ethernet/engleder/tsnep_main.c +@@ -51,12 +51,22 @@ + #define TSNEP_COALESCE_USECS_MAX ((ECM_INT_DELAY_MASK >> ECM_INT_DELAY_SHIFT) * \ + ECM_INT_DELAY_BASE_US + ECM_INT_DELAY_BASE_US - 1) + +-#define TSNEP_TX_TYPE_SKB BIT(0) +-#define TSNEP_TX_TYPE_SKB_FRAG BIT(1) +-#define TSNEP_TX_TYPE_XDP_TX BIT(2) +-#define TSNEP_TX_TYPE_XDP_NDO BIT(3) +-#define TSNEP_TX_TYPE_XDP (TSNEP_TX_TYPE_XDP_TX | TSNEP_TX_TYPE_XDP_NDO) +-#define TSNEP_TX_TYPE_XSK BIT(4) ++/* mapping type */ ++#define TSNEP_TX_TYPE_MAP BIT(0) ++#define TSNEP_TX_TYPE_MAP_PAGE BIT(1) ++#define TSNEP_TX_TYPE_INLINE BIT(2) ++/* buffer type */ ++#define TSNEP_TX_TYPE_SKB BIT(8) ++#define TSNEP_TX_TYPE_SKB_MAP (TSNEP_TX_TYPE_SKB | TSNEP_TX_TYPE_MAP) ++#define TSNEP_TX_TYPE_SKB_INLINE (TSNEP_TX_TYPE_SKB | TSNEP_TX_TYPE_INLINE) ++#define TSNEP_TX_TYPE_SKB_FRAG BIT(9) ++#define TSNEP_TX_TYPE_SKB_FRAG_MAP_PAGE (TSNEP_TX_TYPE_SKB_FRAG | TSNEP_TX_TYPE_MAP_PAGE) ++#define TSNEP_TX_TYPE_SKB_FRAG_INLINE (TSNEP_TX_TYPE_SKB_FRAG | TSNEP_TX_TYPE_INLINE) ++#define TSNEP_TX_TYPE_XDP_TX BIT(10) ++#define TSNEP_TX_TYPE_XDP_NDO BIT(11) ++#define TSNEP_TX_TYPE_XDP_NDO_MAP_PAGE (TSNEP_TX_TYPE_XDP_NDO | TSNEP_TX_TYPE_MAP_PAGE) ++#define TSNEP_TX_TYPE_XDP (TSNEP_TX_TYPE_XDP_TX | TSNEP_TX_TYPE_XDP_NDO) ++#define TSNEP_TX_TYPE_XSK BIT(12) + + #define TSNEP_XDP_TX BIT(0) + #define TSNEP_XDP_REDIRECT BIT(1) +@@ -416,6 +426,8 @@ static void tsnep_tx_activate(struct tsnep_tx *tx, int index, int length, + entry->properties |= TSNEP_TX_DESC_OWNER_USER_FLAG; + entry->desc->more_properties = + __cpu_to_le32(entry->len & TSNEP_DESC_LENGTH_MASK); ++ if (entry->type & TSNEP_TX_TYPE_INLINE) ++ entry->properties |= TSNEP_TX_DESC_DATA_AFTER_DESC_FLAG; + + /* descriptor properties shall be written last, because valid data is + * signaled there +@@ -433,39 +445,79 @@ static int tsnep_tx_desc_available(struct tsnep_tx *tx) + return tx->read - tx->write - 1; + } + ++static int tsnep_tx_map_frag(skb_frag_t *frag, struct tsnep_tx_entry *entry, ++ struct device *dmadev, dma_addr_t *dma) ++{ ++ unsigned int len; ++ int mapped; ++ ++ len = skb_frag_size(frag); ++ if (likely(len > TSNEP_DESC_SIZE_DATA_AFTER_INLINE)) { ++ *dma = skb_frag_dma_map(dmadev, frag, 0, len, DMA_TO_DEVICE); ++ if (dma_mapping_error(dmadev, *dma)) ++ return -ENOMEM; ++ entry->type = TSNEP_TX_TYPE_SKB_FRAG_MAP_PAGE; ++ mapped = 1; ++ } else { ++ void *fragdata = skb_frag_address_safe(frag); ++ ++ if (likely(fragdata)) { ++ memcpy(&entry->desc->tx, fragdata, len); ++ } else { ++ struct page *page = skb_frag_page(frag); ++ ++ fragdata = kmap_local_page(page); ++ memcpy(&entry->desc->tx, fragdata + skb_frag_off(frag), ++ len); ++ kunmap_local(fragdata); ++ } ++ entry->type = TSNEP_TX_TYPE_SKB_FRAG_INLINE; ++ mapped = 0; ++ } ++ ++ return mapped; ++} ++ + static int tsnep_tx_map(struct sk_buff *skb, struct tsnep_tx *tx, int count) + { + struct device *dmadev = tx->adapter->dmadev; + struct tsnep_tx_entry *entry; + unsigned int len; +- dma_addr_t dma; + int map_len = 0; +- int i; ++ dma_addr_t dma; ++ int i, mapped; + + for (i = 0; i < count; i++) { + entry = &tx->entry[(tx->write + i) & TSNEP_RING_MASK]; + + if (!i) { + len = skb_headlen(skb); +- dma = dma_map_single(dmadev, skb->data, len, +- DMA_TO_DEVICE); +- +- entry->type = TSNEP_TX_TYPE_SKB; ++ if (likely(len > TSNEP_DESC_SIZE_DATA_AFTER_INLINE)) { ++ dma = dma_map_single(dmadev, skb->data, len, ++ DMA_TO_DEVICE); ++ if (dma_mapping_error(dmadev, dma)) ++ return -ENOMEM; ++ entry->type = TSNEP_TX_TYPE_SKB_MAP; ++ mapped = 1; ++ } else { ++ memcpy(&entry->desc->tx, skb->data, len); ++ entry->type = TSNEP_TX_TYPE_SKB_INLINE; ++ mapped = 0; ++ } + } else { +- len = skb_frag_size(&skb_shinfo(skb)->frags[i - 1]); +- dma = skb_frag_dma_map(dmadev, +- &skb_shinfo(skb)->frags[i - 1], +- 0, len, DMA_TO_DEVICE); ++ skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1]; + +- entry->type = TSNEP_TX_TYPE_SKB_FRAG; ++ len = skb_frag_size(frag); ++ mapped = tsnep_tx_map_frag(frag, entry, dmadev, &dma); ++ if (mapped < 0) ++ return mapped; + } +- if (dma_mapping_error(dmadev, dma)) +- return -ENOMEM; + + entry->len = len; +- dma_unmap_addr_set(entry, dma, dma); +- +- entry->desc->tx = __cpu_to_le64(dma); ++ if (likely(mapped)) { ++ dma_unmap_addr_set(entry, dma, dma); ++ entry->desc->tx = __cpu_to_le64(dma); ++ } + + map_len += len; + } +@@ -484,13 +536,12 @@ static int tsnep_tx_unmap(struct tsnep_tx *tx, int index, int count) + entry = &tx->entry[(index + i) & TSNEP_RING_MASK]; + + if (entry->len) { +- if (entry->type & TSNEP_TX_TYPE_SKB) ++ if (entry->type & TSNEP_TX_TYPE_MAP) + dma_unmap_single(dmadev, + dma_unmap_addr(entry, dma), + dma_unmap_len(entry, len), + DMA_TO_DEVICE); +- else if (entry->type & +- (TSNEP_TX_TYPE_SKB_FRAG | TSNEP_TX_TYPE_XDP_NDO)) ++ else if (entry->type & TSNEP_TX_TYPE_MAP_PAGE) + dma_unmap_page(dmadev, + dma_unmap_addr(entry, dma), + dma_unmap_len(entry, len), +@@ -586,7 +637,7 @@ static int tsnep_xdp_tx_map(struct xdp_frame *xdpf, struct tsnep_tx *tx, + if (dma_mapping_error(dmadev, dma)) + return -ENOMEM; + +- entry->type = TSNEP_TX_TYPE_XDP_NDO; ++ entry->type = TSNEP_TX_TYPE_XDP_NDO_MAP_PAGE; + } else { + page = unlikely(frag) ? skb_frag_page(frag) : + virt_to_page(xdpf->data); +-- +2.39.5 + diff --git a/queue-6.6/wifi-mac80211-set-n_channels-after-allocating-struct.patch b/queue-6.6/wifi-mac80211-set-n_channels-after-allocating-struct.patch new file mode 100644 index 0000000000..8b615317cc --- /dev/null +++ b/queue-6.6/wifi-mac80211-set-n_channels-after-allocating-struct.patch @@ -0,0 +1,55 @@ +From 238405f44810779aec0aa781c524f4e321ac4eb6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 May 2025 11:46:45 -0700 +Subject: wifi: mac80211: Set n_channels after allocating struct + cfg80211_scan_request + +From: Kees Cook + +[ Upstream commit 82bbe02b2500ef0a62053fe2eb84773fe31c5a0a ] + +Make sure that n_channels is set after allocating the +struct cfg80211_registered_device::int_scan_req member. Seen with +syzkaller: + +UBSAN: array-index-out-of-bounds in net/mac80211/scan.c:1208:5 +index 0 is out of range for type 'struct ieee80211_channel *[] __counted_by(n_channels)' (aka 'struct ieee80211_channel *[]') + +This was missed in the initial conversions because I failed to locate +the allocation likely due to the "sizeof(void *)" not matching the +"channels" array type. + +Reported-by: syzbot+4bcdddd48bb6f0be0da1@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/lkml/680fd171.050a0220.2b69d1.045e.GAE@google.com/ +Fixes: e3eac9f32ec0 ("wifi: cfg80211: Annotate struct cfg80211_scan_request with __counted_by") +Signed-off-by: Kees Cook +Reviewed-by: Gustavo A. R. Silva +Link: https://patch.msgid.link/20250509184641.work.542-kees@kernel.org +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/main.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/net/mac80211/main.c b/net/mac80211/main.c +index d1046f495e63f..3a6fff98748b8 100644 +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -1186,10 +1186,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) + return -EINVAL; + } + +- local->int_scan_req = kzalloc(sizeof(*local->int_scan_req) + +- sizeof(void *) * channels, GFP_KERNEL); ++ local->int_scan_req = kzalloc(struct_size(local->int_scan_req, ++ channels, channels), ++ GFP_KERNEL); + if (!local->int_scan_req) + return -ENOMEM; ++ local->int_scan_req->n_channels = channels; + + eth_broadcast_addr(local->int_scan_req->bssid); + +-- +2.39.5 +