--- /dev/null
+From b694a4f885f301931446467ae2667560b52a0aea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 May 2025 15:45:27 +0200
+Subject: ALSA: seq: Fix delivery of UMP events to group ports
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ 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 <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 0fbf54024841ac567bf3b59bdc3fd3dff97eb710 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 May 2025 09:31:04 +0200
+Subject: ALSA: sh: SND_AICA should depend on SH_DMA_API
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ 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 <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202505131320.PzgTtl9H-lkp@intel.com/
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://patch.msgid.link/b90625f8a9078d0d304bafe862cbe3a3fab40082.1747121335.git.geert+renesas@glider.be
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 41dbe6f82d1295b5b74f7f279c71ec2c1741ac06 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <tiwai@suse.de>
+
+[ 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 <gregkh@linuxfoundation.org>
+Link: https://patch.msgid.link/20250511141147.10246-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From fd0e11608b86b5bcce2fd852c583fe7ec5d13c16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 May 2024 10:31:47 -0700
+Subject: binfmt_elf: Calculate total_size earlier
+
+From: Kees Cook <kees@kernel.org>
+
+[ 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 <kees@kernel.org>
+Stable-dep-of: 11854fe263eb ("binfmt_elf: Move brk for static PIE even if ASLR disabled")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 69e2790a063e5c79c2eb04c09124aedc50bf47b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Sep 2023 20:24:30 -0700
+Subject: binfmt_elf: elf_bss no longer used by load_elf_binary()
+
+From: Kees Cook <keescook@chromium.org>
+
+[ 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 <ebiederm@xmission.com>
+Cc: Alexander Viro <viro@zeniv.linux.org.uk>
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: linux-fsdevel@vger.kernel.org
+Cc: linux-mm@kvack.org
+Suggested-by: Eric Biederman <ebiederm@xmission.com>
+Tested-by: Pedro Falcato <pedro.falcato@gmail.com>
+Signed-off-by: Sebastian Ott <sebott@redhat.com>
+Link: https://lore.kernel.org/r/20230929032435.2391507-2-keescook@chromium.org
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Stable-dep-of: 11854fe263eb ("binfmt_elf: Move brk for static PIE even if ASLR disabled")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From c9f4f97744857a9f72b5cf847edea9db09b42a07 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 May 2024 10:31:48 -0700
+Subject: binfmt_elf: Honor PT_LOAD alignment for static PIE
+
+From: Kees Cook <kees@kernel.org>
+
+[ 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 <hjl.tools@gmail.com>
+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 <kees@kernel.org>
+Stable-dep-of: 11854fe263eb ("binfmt_elf: Move brk for static PIE even if ASLR disabled")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From f7b0d1cf496fad783b1a83eb3fcbe4ee9a72539f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Feb 2024 22:25:44 -0800
+Subject: binfmt_elf: Leave a gap between .bss and brk
+
+From: Kees Cook <keescook@chromium.org>
+
+[ 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: <y0un9n132@gmail.com>
+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 <keescook@chromium.org>
+Stable-dep-of: 11854fe263eb ("binfmt_elf: Move brk for static PIE even if ASLR disabled")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From aa4e9348c5b91079dc0b3996b99fb74cf5f95c10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 15:45:06 -0700
+Subject: binfmt_elf: Move brk for static PIE even if ASLR disabled
+
+From: Kees Cook <kees@kernel.org>
+
+[ 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 <ryan.roberts@arm.com>
+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 <ryan.roberts@arm.com>
+Tested-by: Ryan Roberts <ryan.roberts@arm.com>
+Signed-off-by: Kees Cook <kees@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 96cf0404ff3e559b5a0780a5380a25c12bace3bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <ebiederm@xmission.com>
+
+[ 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 <pavel@ucw.cz>
+> 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 <pavel@suse.cz>
+> Signed-off-by: Andrew Morton <akpm@osdl.org>
+> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
+
+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 <sebott@redhat.com>
+Reported-by: Thomas Weißschuh <linux@weissschuh.net>
+Closes: https://lkml.kernel.org/r/20230914-bss-alloc-v1-1-78de67d2c6dd@weissschuh.net
+Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
+Link: https://lore.kernel.org/r/87sf71f123.fsf@email.froward.int.ebiederm.org
+Tested-by: Pedro Falcato <pedro.falcato@gmail.com>
+Signed-off-by: Sebastian Ott <sebott@redhat.com>
+Link: https://lore.kernel.org/r/20230929032435.2391507-1-keescook@chromium.org
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Stable-dep-of: 11854fe263eb ("binfmt_elf: Move brk for static PIE even if ASLR disabled")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 46362819a8d279280dcc1d7f10032e1cc8feefcb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <luiz.von.dentz@intel.com>
+
+[ 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 <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 959c03fde5fd5af0a0bede27265ff339c55b6bac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <longman@redhat.com>
+
+[ 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 <longman@redhat.com>
+Acked-by: Frederic Weisbecker <frederic@kernel.org>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 92fa56de778377f3574c0a79b19a9ebf921edd2a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Nov 2024 21:26:56 -0600
+Subject: drm/amd: Add Suspend/Hibernate notification callback support
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ 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 <lijo.lazar@amd.com>
+Link: https://lore.kernel.org/r/20241128032656.2090059-2-superm1@kernel.org
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: d0ce1aaa8531 ("Revert "drm/amd: Stop evicting resources on APUs in suspend"")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From e1f934cc44ca71a0367445c41438486aa6910cc9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <mario.limonciello@amd.com>
+
+[ 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 <j@bitron.ch>
+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 <alexander.deucher@amd.com>
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: d0ce1aaa8531 ("Revert "drm/amd: Stop evicting resources on APUs in suspend"")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From fe4dec07dd44ef92b44b4e0374cf3fa4dd70c5d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Feb 2024 17:16:49 +0800
+Subject: drm/amdgpu: Fix the runtime resume failure issue
+
+From: Ma Jun <Jun.Ma2@amd.com>
+
+[ 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 <Jun.Ma2@amd.com>
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Stable-dep-of: d0ce1aaa8531 ("Revert "drm/amd: Stop evicting resources on APUs in suspend"")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From b13123cfa66aeb2171ca881c365def228948ed35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 16:04:35 -0500
+Subject: drm/amdgpu: trigger flr_work if reading pf2vf data failed
+
+From: Zhigang Luo <Zhigang.Luo@amd.com>
+
+[ 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 <Zhigang.Luo@amd.com>
+Acked-by: Hawking Zhang <Hawking.Zhang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: d0ce1aaa8531 ("Revert "drm/amd: Stop evicting resources on APUs in suspend"")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From d3e23f5c196ad5cae4f1b601c67caeb04caeef4b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Mar 2024 20:46:17 +0000
+Subject: firmware: arm_scmi: Add helper to trace bad messages
+
+From: Cristian Marussi <cristian.marussi@arm.com>
+
+[ 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 <cristian.marussi@arm.com>
+Link: https://lore.kernel.org/r/20240325204620.1437237-3-cristian.marussi@arm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Stable-dep-of: c23c03bf1faa ("firmware: arm_scmi: Fix timeout checks on polling path")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From c1e3b061fae9edd31e30e2422d873949dd6e0ea3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <cristian.marussi@arm.com>
+
+[ 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 <cristian.marussi@arm.com>
+Link: https://lore.kernel.org/r/20240325204620.1437237-4-cristian.marussi@arm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Stable-dep-of: c23c03bf1faa ("firmware: arm_scmi: Fix timeout checks on polling path")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From b0825bba9ef54d8984c51309590b0c7f53eb3c58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Aug 2024 14:10:09 +0100
+Subject: firmware: arm_scmi: Add support for debug metrics at the interface
+
+From: Luke Parkin <luke.parkin@arm.com>
+
+[ 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 <luke.parkin@arm.com>
+Reviewed-by: Cristian Marussi <cristian.marussi@arm.com>
+Tested-by: Cristian Marussi <cristian.marussi@arm.com>
+Message-Id: <20240805131013.587016-3-sudeep.holla@arm.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Stable-dep-of: c23c03bf1faa ("firmware: arm_scmi: Fix timeout checks on polling path")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 9e6ad9153e2538440f89e3f3de84944c0d92faed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Mar 2025 17:58:00 +0000
+Subject: firmware: arm_scmi: Fix timeout checks on polling path
+
+From: Cristian Marussi <cristian.marussi@arm.com>
+
+[ 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 <huangjie1663@phytium.com.cn>
+Closes: https://lore.kernel.org/arm-scmi/20250123083323.2363749-1-jackhuang021@gmail.com/
+Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
+Cc: stable@vger.kernel.org # 5.18.x
+Message-Id: <20250310175800.1444293-1-cristian.marussi@arm.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 208e6c8f085adde1048a50c683a263f864e5e198 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Aug 2024 14:10:10 +0100
+Subject: firmware: arm_scmi: Track basic SCMI communication debug metrics
+
+From: Luke Parkin <luke.parkin@arm.com>
+
+[ 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 <luke.parkin@arm.com>
+Reviewed-by: Cristian Marussi <cristian.marussi@arm.com>
+Tested-by: Cristian Marussi <cristian.marussi@arm.com>
+Message-Id: <20240805131013.587016-4-sudeep.holla@arm.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Stable-dep-of: c23c03bf1faa ("firmware: arm_scmi: Fix timeout checks on polling path")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From e3b976608b8afda21b403d84bfb574f58442eb78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <stephen.smalley.work@gmail.com>
+
+[ 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
+<no output>
+$ getfattr -m.* /sys/kernel/fscaps
+<no output>
+$ 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 <stephen.smalley.work@gmail.com>
+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 <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From dacec10609ca942a97038c80cb2478fb47fc0af0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Mar 2025 23:11:46 +0000
+Subject: HID: thrustmaster: fix memory leak in thrustmaster_interrupts()
+
+From: Qasim Ijaz <qasdev00@gmail.com>
+
+[ 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 <qasdev00@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 9ddd0a50199a27b83b6bbf1f462a3d29761d4e95 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 17:48:53 +0800
+Subject: HID: uclogic: Add NULL check in uclogic_input_configured()
+
+From: Henry Martin <bsdhenrymartin@gmail.com>
+
+[ 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 <bsdhenrymartin@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From d0420f0af1cd8847d837107b45cd095b45d0fdfc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <Jonathan.Cameron@huawei.com>
+
+[ 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 <dlechner@baylibre.com>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Link: https://patch.msgid.link/20250413103443.2420727-2-jic23@kernel.org
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 75184f405d18b269d148332c48b9f61391d6c81d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <Jonathan.Cameron@huawei.com>
+
+[ 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 <dlechner@baylibre.com>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Link: https://patch.msgid.link/20250413103443.2420727-3-jic23@kernel.org
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From ea221fa0a2519c302f42b10ce7858e6e9d3b4c8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <dlechner@baylibre.com>
+
+[ 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 <dlechner@baylibre.com>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://patch.msgid.link/20250417-iio-more-timestamp-alignment-v1-5-eafac1e22318@baylibre.com
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 47353fb81d51fdf16a0c593daaf88b08091b0c01 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 20:12:06 +0300
+Subject: KVM: SVM: Forcibly leave SMM mode on SHUTDOWN interception
+
+From: Mikhail Lobanov <m.lobanov@rosa.ru>
+
+[ 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:
+ <TASK>
+ 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 <seanjc@google.com>
+Signed-off-by: Mikhail Lobanov <m.lobanov@rosa.ru>
+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 <seanjc@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 1b91035caa98a725df31dea7df4bd4f70e9d42b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Sep 2023 09:24:49 -0700
+Subject: KVM: SVM: Update SEV-ES shutdown intercepts with more metadata
+
+From: Peter Gonda <pgonda@google.com>
+
+[ 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 <pgonda@google.com>
+Suggested-by: Sean Christopherson <seanjc@google.com>
+Suggested-by: Tom Lendacky <thomas.lendacky@amd.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: Sean Christopherson <seanjc@google.com>
+Cc: Tom Lendacky <thomas.lendacky@amd.com>
+Cc: Joerg Roedel <joro@8bytes.org>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: x86@kernel.org
+Cc: kvm@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
+Link: https://lore.kernel.org/r/20230907162449.1739785-1-pgonda@google.com
+[sean: tweak changelog]
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Stable-dep-of: a2620f8932fa ("KVM: SVM: Forcibly leave SMM mode on SHUTDOWN interception")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 288396659886a3099b2545d0ad0edf58ca23ac53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Dec 2024 22:38:11 +0000
+Subject: mctp: no longer rely on net->dev_index_head[]
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <edumazet@google.com>
+Cc: Matt Johnston <matt@codeconstruct.com.au>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Acked-by: Jeremy Kerr <jk@codeconstruct.com.au>
+Link: https://patch.msgid.link/20241206223811.1343076-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: f11cf946c0a9 ("net: mctp: Don't access ifa_index when missing")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 <net/sock.h>
+
+ 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
+
--- /dev/null
+From 60a1ff2ba652781b89c1616afd6aae827fed0160 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <idosch@nvidia.com>
+
+[ 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:
+ <TASK>
+ 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 <idosch@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Link: https://patch.msgid.link/c53c02c904fde32dad484657be3b1477884e9ad6.1747225701.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 2ecfa20afe7a190bca008fb3fd6b479dd70a297e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 May 2025 14:19:35 +0200
+Subject: net: cadence: macb: Fix a possible deadlock in macb_halt_tx.
+
+From: Mathieu Othacehe <othacehe@gnu.org>
+
+[ 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 <othacehe@gnu.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250509121935.16282-1-othacehe@gnu.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From a01a2eb43cd866cb51e451922e1295e6d97a3209 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 May 2025 14:38:16 +0300
+Subject: net: dsa: sja1105: discard incoming frames in BR_STATE_LISTENING
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ 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 <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250509113816.2221992-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From a62267a731b3851bf6ea7ad79d998399f96b2356 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <bc-bocun.chen@mediatek.com>
+
+[ 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 <bc-bocun.chen@mediatek.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Link: https://patch.msgid.link/b8b37f409d1280fad9c4d32521e6207f63cd3213.1747110258.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 1a7ecd95ecd05c6692c4c74ded8df8eaf1c385c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 May 2025 13:18:32 +0800
+Subject: net: mctp: Don't access ifa_index when missing
+
+From: Matt Johnston <matt@codeconstruct.com.au>
+
+[ 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 <matt@codeconstruct.com.au>
+Link: https://patch.msgid.link/20250508-mctp-addr-dump-v2-1-c8a53fd2dd66@codeconstruct.com.au
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 67ddeed0d988736688f06e512f042e4d3f5578b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 May 2025 14:16:00 +0930
+Subject: net: mctp: Ensure keys maintain only one ref to corresponding dev
+
+From: Andrew Jeffery <andrew@codeconstruct.com.au>
+
+[ 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 <jk@codeconstruct.com.au>
+Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
+Link: https://patch.msgid.link/20250508-mctp-dev-refcount-v1-1-d4f965c67bb5@codeconstruct.com.au
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From c81aff798606aee912c3ba0be3888b7abb000dbf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 May 2025 13:15:52 +0300
+Subject: net/mlx5e: Disable MACsec offload for uplink representor profile
+
+From: Carolina Jubran <cjubran@nvidia.com>
+
+[ 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:
+ <TASK>
+ ? 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
+ </TASK>
+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 <cjubran@nvidia.com>
+Reviewed-by: Shahar Shitrit <shshitrit@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/1746958552-561295-1-git-send-email-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 2e64e6db176b5ee44d1661aa61de8d0ed689fc35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 May 2025 21:20:13 +0800
+Subject: net/tls: fix kernel panic when alloc_page failed
+
+From: Pengtao He <hept.hept.hept@gmail.com>
+
+[ 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 <hept.hept.hept@gmail.com>
+Link: https://patch.msgid.link/20250514132013.17274-1-hept.hept.hept@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From a220d80a0e7fc5545098ba92c6f1c61f2ca37cd2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 May 2025 21:35:58 -0700
+Subject: net_sched: Flush gso_skb list too during ->change()
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+[ 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 <willsroot@protonmail.com>
+Reported-by: Savy <savy@syst3mfailure.io>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 109d8a12e3e4945e1a68055354d08361c6687854 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 15:25:08 +0800
+Subject: nfs: handle failure of nfs_get_lock_context in unlock path
+
+From: Li Lingfeng <lilingfeng3@huawei.com>
+
+[ 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:
+ <TASK>
+ __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
+ </TASK>
+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 <lilingfeng3@huawei.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Link: https://lore.kernel.org/r/20250417072508.3850532-1-lilingfeng3@huawei.com
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From a46d15aa4b5d34103fc1ed83d8716f8820f24518 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 May 2025 10:50:13 -0400
+Subject: NFSv4/pnfs: Reset the layout state after a layoutreturn
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ 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 <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 6ce5037f856b46b46b0f99926da355899b1e255c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 May 2025 16:57:06 +0200
+Subject: nvme-pci: acquire cq_poll_lock in nvme_poll_irqdisable
+
+From: Keith Busch <kbusch@kernel.org>
+
+[ 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 <hare@kernel.org>
+Closes: https://lore.kernel.org/all/20240902130728.1999-1-hare@kernel.org/
+Fixes: a0fa9647a54e ("NVMe: add blk polling support")
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Daniel Wagner <wagi@kernel.org>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From dc35f73905c4fb2843a9a5fe4f048d69395d5f6d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 May 2025 20:35:40 -0700
+Subject: nvme-pci: make nvme_pci_npages_prp() __always_inline
+
+From: Kees Cook <kees@kernel.org>
+
+[ 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 <lkp@intel.com>
+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 <kees@kernel.org>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From e9686738dae2227ff8a536a67983714506afc7e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 May 2025 12:45:54 +0530
+Subject: octeontx2-af: Fix CGX Receive counters
+
+From: Hariprasad Kelam <hkelam@marvell.com>
+
+[ 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 <hkelam@marvell.com>
+Link: https://patch.msgid.link/20250513071554.728922-1-hkelam@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 41343038bd113b8e8a2f5f9a573ae6b6598ecea2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 May 2025 18:12:36 +0530
+Subject: octeontx2-pf: macsec: Fix incorrect max transmit size in TX secy
+
+From: Subbaraya Sundeep <sbhatta@marvell.com>
+
+[ 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 <sbhatta@marvell.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/1747053756-4529-1-git-send-email-sbhatta@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 4f26251db999faa9ef58409f175c5a7de501830d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <hua@aosc.io>
+
+[ 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 <jeffbai@aosc.io>
+Suggested-by: Xinhui Yang <cyan@cyano.uk>
+Suggested-by: Rong Zhang <i@rong.moe>
+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 <mario.limonciello@amd.com>
+Link: https://zhuanldan.zhihu.com/p/730538041
+Tested-by: Yemu Lu <prcups@krgm.moe>
+Signed-off-by: Runhua He <hua@aosc.io>
+Link: https://lore.kernel.org/r/20250507100103.995395-1-hua@aosc.io
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From d878286aea88a6b28862299ca110a9e95e4f8903 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <hdegoede@redhat.com>
+
+[ 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 <hdegoede@redhat.com>
+Reviewed-by: Armin Wolf <W_Armin@gmx.de>
+Link: https://lore.kernel.org/r/20250501131702.103360-2-hdegoede@redhat.com
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From edc125732cb611d82b5c323016c3029642dec597 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 May 2025 10:18:27 +0530
+Subject: qlcnic: fix memory leak in qlcnic_sriov_channel_cfg_cmd()
+
+From: Abdun Nihaal <abdun.nihaal@gmail.com>
+
+[ 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 <abdun.nihaal@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250512044829.36400-1-abdun.nihaal@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 73b9aceacfe7b87350b251a446f8544a9fec50b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <yanjun.zhu@linux.dev>
+
+[ Upstream commit f81b33582f9339d2dc17c69b92040d3650bb4bae ]
+
+Call Trace:
+ <TASK>
+ __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 <liuy22@mails.tsinghua.edu.cn>
+Signed-off-by: Zhu Yanjun <yanjun.zhu@linux.dev>
+Link: https://patch.msgid.link/20250412075714.3257358-1-yanjun.zhu@linux.dev
+Reviewed-by: Daisuke Matsuda <matsuda-daisuke@fujitsu.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From f2177af9cd29098215368cb0bdf0597980a2daef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 May 2025 09:49:43 +0300
+Subject: regulator: max20086: fix invalid memory access
+
+From: Cosmin Tanislav <demonsingur@gmail.com>
+
+[ 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 <demonsingur@gmail.com>
+Link: https://patch.msgid.link/20250508064947.2567255-1-demonsingur@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 0fec52988b3b588f00cb0c3a10dbb011c313cb24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 May 2025 13:00:16 -0400
+Subject: Revert "drm/amd: Stop evicting resources on APUs in suspend"
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ 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 <mario.limonciello@amd.com>
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit ce8f7d95899c2869b47ea6ce0b3e5bf304b2fff4)
+Cc: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 0e744359a44ed60080b746120f0fa0225bd248ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 May 2024 10:31:46 -0700
+Subject: selftests/exec: Build both static and non-static load_address tests
+
+From: Kees Cook <kees@kernel.org>
+
+[ 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 <kees@kernel.org>
+Stable-dep-of: 11854fe263eb ("binfmt_elf: Move brk for static PIE even if ASLR disabled")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 <link.h>
+ #include <stdio.h>
+ #include <stdlib.h>
++#include <stdbool.h>
+ #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
+
--- /dev/null
+From 8073d1922ca6e68a6de9abfed9b19b4ed2c84451 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Mar 2024 20:59:24 +0500
+Subject: selftests/exec: load_address: conform test to TAP format output
+
+From: Muhammad Usama Anjum <usama.anjum@collabora.com>
+
+[ 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 <usama.anjum@collabora.com>
+Link: https://lore.kernel.org/r/20240304155928.1818928-2-usama.anjum@collabora.com
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Stable-dep-of: 11854fe263eb ("binfmt_elf: Move brk for static PIE even if ASLR disabled")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 <link.h>
+ #include <stdio.h>
+ #include <stdlib.h>
++#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
+
--- /dev/null
+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
--- /dev/null
+From 2a823c0ae6fc67de0c020bac62ea0d557f55de71 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 May 2025 13:10:35 +0200
+Subject: spi: loopback-test: Do not split 1024-byte hexdumps
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ 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 <geert+renesas@glider.be>
+Link: https://patch.msgid.link/37ee1bc90c6554c9347040adabf04188c8f704aa.1746184171.git.geert+renesas@glider.be
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 81dd350fc73849c62bbc9acb5dc0aec303d5c411 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <liuhangbin@gmail.com>
+
+[ 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 <module>
+ 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 <liuhangbin@gmail.com>
+Acked-by: Stanislav Fomichev <sdf@fomichev.me>
+Link: https://patch.msgid.link/20250508035414.82974-1-liuhangbin@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From bce5b5d48db5b09c264a12c9aaef23363e5fe595 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Apr 2024 14:28:45 -0700
+Subject: tools: ynl: ethtool.py: Output timestamping statistics from
+ tsinfo-get operation
+
+From: Rahul Rameshbabu <rrameshbabu@nvidia.com>
+
+[ 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 <rrameshbabu@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Link: https://lore.kernel.org/r/20240403212931.128541-8-rrameshbabu@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 45375814eb3f ("tools/net/ynl: ethtool: fix crash when Hardware Clock info is missing")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 0d1ab8d2662a0f1b0e047e49620ebe7b4e0916e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 10:23:14 +0200
+Subject: tpm: tis: Double the timeout B to 4s
+
+From: Michal Suchanek <msuchanek@suse.de>
+
+[ 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 <msuchanek@suse.de>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From e5a8d085da38f5ebc5aa6ba80108cdcd5dbe4d27 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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) <mhiramat@kernel.org>
+
+[ 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 <paulcacheux@gmail.com>
+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) <mhiramat@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 1b162c9c797651515ca6f7e01e2f5b35288eaeed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 May 2025 21:56:57 +0200
+Subject: tsnep: fix timestamping with a stacked DSA driver
+
+From: Gerhard Engleder <gerhard@engleder-embedded.com>
+
+[ 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 <vladimir.oltean@nxp.com>
+Signed-off-by: Gerhard Engleder <gerhard@engleder-embedded.com>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250514195657.25874-1-gerhard@engleder-embedded.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From c615d283a379375d867dccf477d548af9553f208 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Oct 2023 20:21:54 +0200
+Subject: tsnep: Inline small fragments within TX descriptor
+
+From: Gerhard Engleder <gerhard@engleder-embedded.com>
+
+[ 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 <gerhard@engleder-embedded.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: b3ca9eef6646 ("tsnep: fix timestamping with a stacked DSA driver")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 238405f44810779aec0aa781c524f4e321ac4eb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 May 2025 11:46:45 -0700
+Subject: wifi: mac80211: Set n_channels after allocating struct
+ cfg80211_scan_request
+
+From: Kees Cook <kees@kernel.org>
+
+[ 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 <kees@kernel.org>
+Reviewed-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Link: https://patch.msgid.link/20250509184641.work.542-kees@kernel.org
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+