]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.13
authorSasha Levin <sashal@kernel.org>
Sat, 1 Mar 2025 14:19:51 +0000 (09:19 -0500)
committerSasha Levin <sashal@kernel.org>
Sat, 1 Mar 2025 14:19:51 +0000 (09:19 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
39 files changed:
queue-6.13/afs-fix-the-server_list-to-unuse-a-displaced-server-.patch [new file with mode: 0644]
queue-6.13/afs-give-an-afs_server-object-a-ref-on-the-afs_cell-.patch [new file with mode: 0644]
queue-6.13/alsa-hda-realtek-fix-wrong-mic-setup-for-asus-vivobo.patch [new file with mode: 0644]
queue-6.13/alsa-usb-audio-avoid-dropping-midi-events-at-closing.patch [new file with mode: 0644]
queue-6.13/asoc-cs35l56-prevent-races-when-soft-resetting-using.patch [new file with mode: 0644]
queue-6.13/asoc-es8328-fix-route-from-dac-to-output.patch [new file with mode: 0644]
queue-6.13/asoc-fsl-rename-stream-name-of-sai-dai-driver.patch [new file with mode: 0644]
queue-6.13/bluetooth-l2cap-fix-l2cap_ecred_conn_rsp-response.patch [new file with mode: 0644]
queue-6.13/drm-amd-display-restore-edid-reading-from-a-given-i2.patch [new file with mode: 0644]
queue-6.13/drm-amdgpu-gfx-only-call-mes-for-enforce-isolation-i.patch [new file with mode: 0644]
queue-6.13/drm-amdgpu-mes-keep-enforce-isolation-up-to-date.patch [new file with mode: 0644]
queue-6.13/drm-xe-cancel-pending-job-timer-before-freeing-sched.patch [new file with mode: 0644]
queue-6.13/drm-xe-oa-allow-oa_exponent-value-of-0.patch [new file with mode: 0644]
queue-6.13/firmware-cs_dsp-remove-async-regmap-writes.patch [new file with mode: 0644]
queue-6.13/ice-avoid-setting-default-rx-vsi-twice-in-switchdev-.patch [new file with mode: 0644]
queue-6.13/ice-fix-deinitializing-vf-in-error-path.patch [new file with mode: 0644]
queue-6.13/idpf-fix-checksums-set-in-idpf_rx_rsc.patch [new file with mode: 0644]
queue-6.13/ipvlan-ensure-network-headers-are-in-skb-linear-part.patch [new file with mode: 0644]
queue-6.13/ipvs-always-clear-ipvs_property-flag-in-skb_scrub_pa.patch [new file with mode: 0644]
queue-6.13/net-add-net_passive_inc-and-net_passive_dec.patch [new file with mode: 0644]
queue-6.13/net-better-track-kernel-sockets-lifetime.patch [new file with mode: 0644]
queue-6.13/net-cadence-macb-synchronize-stats-calculations.patch [new file with mode: 0644]
queue-6.13/net-clear-old-fragment-checksum-value-in-napi_reuse_.patch [new file with mode: 0644]
queue-6.13/net-dsa-rtl8366rb-fix-compilation-problem.patch [new file with mode: 0644]
queue-6.13/net-ethernet-ti-am65-cpsw-select-page_pool.patch [new file with mode: 0644]
queue-6.13/net-ipv6-fix-dst-ref-loop-on-input-in-rpl-lwt.patch [new file with mode: 0644]
queue-6.13/net-ipv6-fix-dst-ref-loop-on-input-in-seg6-lwt.patch [new file with mode: 0644]
queue-6.13/net-loopback-avoid-sending-ip-packets-without-an-eth.patch [new file with mode: 0644]
queue-6.13/net-mlx5-fix-vport-qos-cleanup-on-error.patch [new file with mode: 0644]
queue-6.13/net-mlx5-irq-fix-null-string-in-debug-print.patch [new file with mode: 0644]
queue-6.13/net-mlx5-restore-missing-trace-event-when-enabling-v.patch [new file with mode: 0644]
queue-6.13/net-mvpp2-cls-fixed-non-ip-flow-with-vlan-tag-flow-d.patch [new file with mode: 0644]
queue-6.13/net-set-the-minimum-for-net_hotdata.netdev_budget_us.patch [new file with mode: 0644]
queue-6.13/net-ti-icss-iep-reject-perout-generation-request.patch [new file with mode: 0644]
queue-6.13/rxrpc-rxperf-fix-missing-decoding-of-terminal-magic-.patch [new file with mode: 0644]
queue-6.13/selftests-drv-net-check-if-combined-count-exists.patch [new file with mode: 0644]
queue-6.13/series
queue-6.13/tcp-defer-ts_recent-changes-until-req-is-owned.patch [new file with mode: 0644]
queue-6.13/tcp-devmem-don-t-write-truncated-dmabuf-cmsgs-to-use.patch [new file with mode: 0644]

diff --git a/queue-6.13/afs-fix-the-server_list-to-unuse-a-displaced-server-.patch b/queue-6.13/afs-fix-the-server_list-to-unuse-a-displaced-server-.patch
new file mode 100644 (file)
index 0000000..b03cffc
--- /dev/null
@@ -0,0 +1,59 @@
+From fd4f4de58d38e1c69fb3c80d64190e976bc2613d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Feb 2025 19:22:47 +0000
+Subject: afs: Fix the server_list to unuse a displaced server rather than
+ putting it
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit add117e48df4788a86a21bd0515833c0a6db1ad1 ]
+
+When allocating and building an afs_server_list struct object from a VLDB
+record, we look up each server address to get the server record for it -
+but a server may have more than one entry in the record and we discard the
+duplicate pointers.  Currently, however, when we discard, we only put a
+server record, not unuse it - but the lookup got as an active-user count.
+
+The active-user count on an afs_server_list object determines its lifetime
+whereas the refcount keeps the memory backing it around.  Failing to reduce
+the active-user counter prevents the record from being cleaned up and can
+lead to multiple copied being seen - and pointing to deleted afs_cell
+objects and other such things.
+
+Fix this by switching the incorrect 'put' to an 'unuse' instead.
+
+Without this, occasionally, a dead server record can be seen in
+/proc/net/afs/servers and list corruption may be observed:
+
+    list_del corruption. prev->next should be ffff888102423e40, but was 0000000000000000. (prev=ffff88810140cd38)
+
+Fixes: 977e5f8ed0ab ("afs: Split the usage count on struct afs_server")
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+Link: https://patch.msgid.link/20250218192250.296870-5-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/afs/server_list.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/afs/server_list.c b/fs/afs/server_list.c
+index 7e7e567a7f8a2..d20cd902ef949 100644
+--- a/fs/afs/server_list.c
++++ b/fs/afs/server_list.c
+@@ -97,8 +97,8 @@ struct afs_server_list *afs_alloc_server_list(struct afs_volume *volume,
+                               break;
+               if (j < slist->nr_servers) {
+                       if (slist->servers[j].server == server) {
+-                              afs_put_server(volume->cell->net, server,
+-                                             afs_server_trace_put_slist_isort);
++                              afs_unuse_server(volume->cell->net, server,
++                                               afs_server_trace_put_slist_isort);
+                               continue;
+                       }
+-- 
+2.39.5
+
diff --git a/queue-6.13/afs-give-an-afs_server-object-a-ref-on-the-afs_cell-.patch b/queue-6.13/afs-give-an-afs_server-object-a-ref-on-the-afs_cell-.patch
new file mode 100644 (file)
index 0000000..7a96b9e
--- /dev/null
@@ -0,0 +1,77 @@
+From fce175d41fab11e080b88e51ecdaf15c7d33ee2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Feb 2025 19:22:48 +0000
+Subject: afs: Give an afs_server object a ref on the afs_cell object it points
+ to
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 1f0fc3374f3345ff1d150c5c56ac5016e5d3826a ]
+
+Give an afs_server object a ref on the afs_cell object it points to so that
+the cell doesn't get deleted before the server record.
+
+Whilst this is circular (cell -> vol -> server_list -> server -> cell), the
+ref only pins the memory, not the lifetime as that's controlled by the
+activity counter.  When the volume's activity counter reaches 0, it
+detaches from the cell and discards its server list; when a cell's activity
+counter reaches 0, it discards its root volume.  At that point, the
+circularity is cut.
+
+Fixes: d2ddc776a458 ("afs: Overhaul volume and server record caching and fileserver rotation")
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+Link: https://patch.msgid.link/20250218192250.296870-6-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/afs/server.c            | 3 +++
+ include/trace/events/afs.h | 2 ++
+ 2 files changed, 5 insertions(+)
+
+diff --git a/fs/afs/server.c b/fs/afs/server.c
+index 038f9d0ae3af8..4504e16b458cc 100644
+--- a/fs/afs/server.c
++++ b/fs/afs/server.c
+@@ -163,6 +163,8 @@ static struct afs_server *afs_install_server(struct afs_cell *cell,
+       rb_insert_color(&server->uuid_rb, &net->fs_servers);
+       hlist_add_head_rcu(&server->proc_link, &net->fs_proc);
++      afs_get_cell(cell, afs_cell_trace_get_server);
++
+ added_dup:
+       write_seqlock(&net->fs_addr_lock);
+       estate = rcu_dereference_protected(server->endpoint_state,
+@@ -442,6 +444,7 @@ static void afs_server_rcu(struct rcu_head *rcu)
+                        atomic_read(&server->active), afs_server_trace_free);
+       afs_put_endpoint_state(rcu_access_pointer(server->endpoint_state),
+                              afs_estate_trace_put_server);
++      afs_put_cell(server->cell, afs_cell_trace_put_server);
+       kfree(server);
+ }
+diff --git a/include/trace/events/afs.h b/include/trace/events/afs.h
+index 9a75590227f26..3dddfc6abf0ee 100644
+--- a/include/trace/events/afs.h
++++ b/include/trace/events/afs.h
+@@ -173,6 +173,7 @@ enum yfs_cm_operation {
+       EM(afs_cell_trace_get_queue_dns,        "GET q-dns ") \
+       EM(afs_cell_trace_get_queue_manage,     "GET q-mng ") \
+       EM(afs_cell_trace_get_queue_new,        "GET q-new ") \
++      EM(afs_cell_trace_get_server,           "GET server") \
+       EM(afs_cell_trace_get_vol,              "GET vol   ") \
+       EM(afs_cell_trace_insert,               "INSERT    ") \
+       EM(afs_cell_trace_manage,               "MANAGE    ") \
+@@ -180,6 +181,7 @@ enum yfs_cm_operation {
+       EM(afs_cell_trace_put_destroy,          "PUT destry") \
+       EM(afs_cell_trace_put_queue_work,       "PUT q-work") \
+       EM(afs_cell_trace_put_queue_fail,       "PUT q-fail") \
++      EM(afs_cell_trace_put_server,           "PUT server") \
+       EM(afs_cell_trace_put_vol,              "PUT vol   ") \
+       EM(afs_cell_trace_see_source,           "SEE source") \
+       EM(afs_cell_trace_see_ws,               "SEE ws    ") \
+-- 
+2.39.5
+
diff --git a/queue-6.13/alsa-hda-realtek-fix-wrong-mic-setup-for-asus-vivobo.patch b/queue-6.13/alsa-hda-realtek-fix-wrong-mic-setup-for-asus-vivobo.patch
new file mode 100644 (file)
index 0000000..e80b04c
--- /dev/null
@@ -0,0 +1,45 @@
+From c39cd19b07012583d6fb2f5e68c52252d26b874e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 16:45:32 +0100
+Subject: ALSA: hda/realtek: Fix wrong mic setup for ASUS VivoBook 15
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 9e7c6779e3530bbdd465214afcd13f19c33e51a2 ]
+
+ASUS VivoBook 15 with SSID 1043:1460 took an incorrect quirk via the
+pin pattern matching for ASUS (ALC256_FIXUP_ASUS_MIC), resulting in
+the two built-in mic pins (0x13 and 0x1b).  This had worked without
+problems casually in the past because the right pin (0x1b) was picked
+up as the primary device.  But since we fixed the pin enumeration for
+other bugs, the bogus one (0x13) is picked up as the primary device,
+hence the bug surfaced now.
+
+For addressing the regression, this patch explicitly specifies the
+quirk entry with ALC256_FIXUP_ASUS_MIC_NO_PRESENCE, which sets up only
+the headset mic pin.
+
+Fixes: 3b4309546b48 ("ALSA: hda: Fix headset detection failure due to unstable sort")
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219807
+Link: https://patch.msgid.link/20250225154540.13543-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index ffe3de617d5dd..5441425292195 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -10595,6 +10595,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
+       SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
+       SND_PCI_QUIRK(0x1043, 0x1433, "ASUS GX650PY/PZ/PV/PU/PYV/PZV/PIV/PVV", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC),
++      SND_PCI_QUIRK(0x1043, 0x1460, "Asus VivoBook 15", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1043, 0x1463, "Asus GA402X/GA402N", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1043, 0x1473, "ASUS GU604VI/VC/VE/VG/VJ/VQ/VU/VV/VY/VZ", ALC285_FIXUP_ASUS_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1043, 0x1483, "ASUS GU603VQ/VU/VV/VJ/VI", ALC285_FIXUP_ASUS_HEADSET_MIC),
+-- 
+2.39.5
+
diff --git a/queue-6.13/alsa-usb-audio-avoid-dropping-midi-events-at-closing.patch b/queue-6.13/alsa-usb-audio-avoid-dropping-midi-events-at-closing.patch
new file mode 100644 (file)
index 0000000..1e687a4
--- /dev/null
@@ -0,0 +1,47 @@
+From e9a08b012287732775ecce6553b409c0d43e9f11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Feb 2025 12:40:24 +0100
+Subject: ALSA: usb-audio: Avoid dropping MIDI events at closing multiple ports
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit a3bdd8f5c2217e1cb35db02c2eed36ea20fb50f5 ]
+
+We fixed the UAF issue in USB MIDI code by canceling the pending work
+at closing each MIDI output device in the commit below.  However, this
+assumed that it's the only one that is tied with the endpoint, and it
+resulted in unexpected data truncations when multiple devices are
+assigned to a single endpoint and opened simultaneously.
+
+For addressing the unexpected MIDI message drops, simply replace
+cancel_work_sync() with flush_work().  The drain callback should have
+been already invoked before the close callback, hence the port->active
+flag must be already cleared.  So this just assures that the pending
+work is finished before freeing the resources.
+
+Fixes: 0125de38122f ("ALSA: usb-audio: Cancel pending work at closing a MIDI substream")
+Reported-and-tested-by: John Keeping <jkeeping@inmusicbrands.com>
+Closes: https://lore.kernel.org/20250217111647.3368132-1-jkeeping@inmusicbrands.com
+Link: https://patch.msgid.link/20250218114024.23125-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/midi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/usb/midi.c b/sound/usb/midi.c
+index 737dd00e97b14..779d97d31f170 100644
+--- a/sound/usb/midi.c
++++ b/sound/usb/midi.c
+@@ -1145,7 +1145,7 @@ static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream)
+ {
+       struct usbmidi_out_port *port = substream->runtime->private_data;
+-      cancel_work_sync(&port->ep->work);
++      flush_work(&port->ep->work);
+       return substream_open(substream, 0, 0);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.13/asoc-cs35l56-prevent-races-when-soft-resetting-using.patch b/queue-6.13/asoc-cs35l56-prevent-races-when-soft-resetting-using.patch
new file mode 100644 (file)
index 0000000..b7a9a06
--- /dev/null
@@ -0,0 +1,262 @@
+From bd61ecb35f3ede3b6b6a91f56232a6113c4fbcfd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 13:18:43 +0000
+Subject: ASoC: cs35l56: Prevent races when soft-resetting using SPI control
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit 769c1b79295c38d60fde4c0a8f5f31e01360c54f ]
+
+When SPI is used for control, the driver must hold the SPI bus lock
+while issuing the sequence of writes to perform a soft reset.
+
+>From the time the driver writes the SYSTEM_RESET command until the
+driver does a write to terminate the reset, there must not be any
+activity on the SPI bus lines. If there is any SPI activity during the
+soft-reset, another soft-reset will be triggered. The state of the SPI
+chip select is irrelevant.
+
+A repeated soft-reset does not in itself cause any problems, and it is
+not an infinite loop. The problem is a race between these resets and
+the driver polling for boot completion. There is a time window between
+soft resets where the driver could read HALO_STATE as 2 (fully booted)
+while the chip is actually soft-resetting. Although this window is
+small, it is long enough that it is possible to hit it in normal
+operation.
+
+To prevent this race and ensure the chip really is fully booted, the
+driver calls spi_bus_lock() to prevent other activity while resetting.
+It then issues the SYSTEM_RESET mailbox command. After allowing
+sufficient time for reset to take effect, the driver issues a PING
+mailbox command, which will force completion of the full soft-reset
+sequence. The SPI bus lock can then be released. The mailbox is
+checked for any boot or wakeup response from the firmware, before the
+value in HALO_STATE will be trusted.
+
+This does not affect SoundWire or I2C control.
+
+Fixes: 8a731fd37f8b ("ASoC: cs35l56: Move utility functions to shared file")
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Link: https://patch.msgid.link/20250225131843.113752-3-rf@opensource.cirrus.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/sound/cs35l56.h           | 31 ++++++++++++
+ sound/pci/hda/cs35l56_hda_spi.c   |  3 ++
+ sound/soc/codecs/cs35l56-shared.c | 80 +++++++++++++++++++++++++++++++
+ sound/soc/codecs/cs35l56-spi.c    |  3 ++
+ 4 files changed, 117 insertions(+)
+
+diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h
+index 3dc7a1551ac35..5d653a3491d07 100644
+--- a/include/sound/cs35l56.h
++++ b/include/sound/cs35l56.h
+@@ -12,6 +12,7 @@
+ #include <linux/firmware/cirrus/cs_dsp.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/regmap.h>
++#include <linux/spi/spi.h>
+ #include <sound/cs-amp-lib.h>
+ #define CS35L56_DEVID                                 0x0000000
+@@ -61,6 +62,7 @@
+ #define CS35L56_IRQ1_MASK_8                           0x000E0AC
+ #define CS35L56_IRQ1_MASK_18                          0x000E0D4
+ #define CS35L56_IRQ1_MASK_20                          0x000E0DC
++#define CS35L56_DSP_MBOX_1_RAW                                0x0011000
+ #define CS35L56_DSP_VIRTUAL1_MBOX_1                   0x0011020
+ #define CS35L56_DSP_VIRTUAL1_MBOX_2                   0x0011024
+ #define CS35L56_DSP_VIRTUAL1_MBOX_3                   0x0011028
+@@ -224,6 +226,7 @@
+ #define CS35L56_HALO_STATE_SHUTDOWN                   1
+ #define CS35L56_HALO_STATE_BOOT_DONE                  2
++#define CS35L56_MBOX_CMD_PING                         0x0A000000
+ #define CS35L56_MBOX_CMD_AUDIO_PLAY                   0x0B000001
+ #define CS35L56_MBOX_CMD_AUDIO_PAUSE                  0x0B000002
+ #define CS35L56_MBOX_CMD_AUDIO_REINIT                 0x0B000003
+@@ -254,6 +257,16 @@
+ #define CS35L56_NUM_BULK_SUPPLIES                     3
+ #define CS35L56_NUM_DSP_REGIONS                               5
++/* Additional margin for SYSTEM_RESET to control port ready on SPI */
++#define CS35L56_SPI_RESET_TO_PORT_READY_US (CS35L56_CONTROL_PORT_READY_US + 2500)
++
++struct cs35l56_spi_payload {
++      __be32  addr;
++      __be16  pad;
++      __be32  value;
++} __packed;
++static_assert(sizeof(struct cs35l56_spi_payload) == 10);
++
+ struct cs35l56_base {
+       struct device *dev;
+       struct regmap *regmap;
+@@ -269,6 +282,7 @@ struct cs35l56_base {
+       s8 cal_index;
+       struct cirrus_amp_cal_data cal_data;
+       struct gpio_desc *reset_gpio;
++      struct cs35l56_spi_payload *spi_payload_buf;
+ };
+ static inline bool cs35l56_is_otp_register(unsigned int reg)
+@@ -276,6 +290,23 @@ static inline bool cs35l56_is_otp_register(unsigned int reg)
+       return (reg >> 16) == 3;
+ }
++static inline int cs35l56_init_config_for_spi(struct cs35l56_base *cs35l56,
++                                            struct spi_device *spi)
++{
++      cs35l56->spi_payload_buf = devm_kzalloc(&spi->dev,
++                                              sizeof(*cs35l56->spi_payload_buf),
++                                              GFP_KERNEL | GFP_DMA);
++      if (!cs35l56->spi_payload_buf)
++              return -ENOMEM;
++
++      return 0;
++}
++
++static inline bool cs35l56_is_spi(struct cs35l56_base *cs35l56)
++{
++      return IS_ENABLED(CONFIG_SPI_MASTER) && !!cs35l56->spi_payload_buf;
++}
++
+ extern const struct regmap_config cs35l56_regmap_i2c;
+ extern const struct regmap_config cs35l56_regmap_spi;
+ extern const struct regmap_config cs35l56_regmap_sdw;
+diff --git a/sound/pci/hda/cs35l56_hda_spi.c b/sound/pci/hda/cs35l56_hda_spi.c
+index d4ee5bb7c4866..9035784669053 100644
+--- a/sound/pci/hda/cs35l56_hda_spi.c
++++ b/sound/pci/hda/cs35l56_hda_spi.c
+@@ -22,6 +22,9 @@ static int cs35l56_hda_spi_probe(struct spi_device *spi)
+               return -ENOMEM;
+       cs35l56->base.dev = &spi->dev;
++      ret = cs35l56_init_config_for_spi(&cs35l56->base, spi);
++      if (ret)
++              return ret;
+ #ifdef CS35L56_WAKE_HOLD_TIME_US
+       cs35l56->base.can_hibernate = true;
+diff --git a/sound/soc/codecs/cs35l56-shared.c b/sound/soc/codecs/cs35l56-shared.c
+index e0ed4fc11155a..e28bfefa72f33 100644
+--- a/sound/soc/codecs/cs35l56-shared.c
++++ b/sound/soc/codecs/cs35l56-shared.c
+@@ -10,6 +10,7 @@
+ #include <linux/gpio/consumer.h>
+ #include <linux/regmap.h>
+ #include <linux/regulator/consumer.h>
++#include <linux/spi/spi.h>
+ #include <linux/types.h>
+ #include <sound/cs-amp-lib.h>
+@@ -303,6 +304,79 @@ void cs35l56_wait_min_reset_pulse(void)
+ }
+ EXPORT_SYMBOL_NS_GPL(cs35l56_wait_min_reset_pulse, "SND_SOC_CS35L56_SHARED");
++static const struct {
++      u32 addr;
++      u32 value;
++} cs35l56_spi_system_reset_stages[] = {
++      { .addr = CS35L56_DSP_VIRTUAL1_MBOX_1, .value = CS35L56_MBOX_CMD_SYSTEM_RESET },
++      /* The next write is necessary to delimit the soft reset */
++      { .addr = CS35L56_DSP_MBOX_1_RAW, .value = CS35L56_MBOX_CMD_PING },
++};
++
++static void cs35l56_spi_issue_bus_locked_reset(struct cs35l56_base *cs35l56_base,
++                                             struct spi_device *spi)
++{
++      struct cs35l56_spi_payload *buf = cs35l56_base->spi_payload_buf;
++      struct spi_transfer t = {
++              .tx_buf         = buf,
++              .len            = sizeof(*buf),
++      };
++      struct spi_message m;
++      int i, ret;
++
++      for (i = 0; i < ARRAY_SIZE(cs35l56_spi_system_reset_stages); i++) {
++              buf->addr = cpu_to_be32(cs35l56_spi_system_reset_stages[i].addr);
++              buf->value = cpu_to_be32(cs35l56_spi_system_reset_stages[i].value);
++              spi_message_init_with_transfers(&m, &t, 1);
++              ret = spi_sync_locked(spi, &m);
++              if (ret)
++                      dev_warn(cs35l56_base->dev, "spi_sync failed: %d\n", ret);
++
++              usleep_range(CS35L56_SPI_RESET_TO_PORT_READY_US,
++                           2 * CS35L56_SPI_RESET_TO_PORT_READY_US);
++      }
++}
++
++static void cs35l56_spi_system_reset(struct cs35l56_base *cs35l56_base)
++{
++      struct spi_device *spi = to_spi_device(cs35l56_base->dev);
++      unsigned int val;
++      int read_ret, ret;
++
++      /*
++       * There must not be any other SPI bus activity while the amp is
++       * soft-resetting.
++       */
++      ret = spi_bus_lock(spi->controller);
++      if (ret) {
++              dev_warn(cs35l56_base->dev, "spi_bus_lock failed: %d\n", ret);
++              return;
++      }
++
++      cs35l56_spi_issue_bus_locked_reset(cs35l56_base, spi);
++      spi_bus_unlock(spi->controller);
++
++      /*
++       * Check firmware boot by testing for a response in MBOX_2.
++       * HALO_STATE cannot be trusted yet because the reset sequence
++       * can leave it with stale state. But MBOX is reset.
++       * The regmap must remain in cache-only until the chip has
++       * booted, so use a bypassed read.
++       */
++      ret = read_poll_timeout(regmap_read_bypassed, read_ret,
++                              (val > 0) && (val < 0xffffffff),
++                              CS35L56_HALO_STATE_POLL_US,
++                              CS35L56_HALO_STATE_TIMEOUT_US,
++                              false,
++                              cs35l56_base->regmap,
++                              CS35L56_DSP_VIRTUAL1_MBOX_2,
++                              &val);
++      if (ret) {
++              dev_err(cs35l56_base->dev, "SPI reboot timed out(%d): MBOX2=%#x\n",
++                      read_ret, val);
++      }
++}
++
+ static const struct reg_sequence cs35l56_system_reset_seq[] = {
+       REG_SEQ0(CS35L56_DSP1_HALO_STATE, 0),
+       REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_SYSTEM_RESET),
+@@ -315,6 +389,12 @@ void cs35l56_system_reset(struct cs35l56_base *cs35l56_base, bool is_soundwire)
+        * accesses other than the controlled system reset sequence below.
+        */
+       regcache_cache_only(cs35l56_base->regmap, true);
++
++      if (cs35l56_is_spi(cs35l56_base)) {
++              cs35l56_spi_system_reset(cs35l56_base);
++              return;
++      }
++
+       regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
+                                       cs35l56_system_reset_seq,
+                                       ARRAY_SIZE(cs35l56_system_reset_seq));
+diff --git a/sound/soc/codecs/cs35l56-spi.c b/sound/soc/codecs/cs35l56-spi.c
+index c101134e85328..ca6c03a8766d3 100644
+--- a/sound/soc/codecs/cs35l56-spi.c
++++ b/sound/soc/codecs/cs35l56-spi.c
+@@ -33,6 +33,9 @@ static int cs35l56_spi_probe(struct spi_device *spi)
+       cs35l56->base.dev = &spi->dev;
+       cs35l56->base.can_hibernate = true;
++      ret = cs35l56_init_config_for_spi(&cs35l56->base, spi);
++      if (ret)
++              return ret;
+       ret = cs35l56_common_probe(cs35l56);
+       if (ret != 0)
+-- 
+2.39.5
+
diff --git a/queue-6.13/asoc-es8328-fix-route-from-dac-to-output.patch b/queue-6.13/asoc-es8328-fix-route-from-dac-to-output.patch
new file mode 100644 (file)
index 0000000..dfc74ae
--- /dev/null
@@ -0,0 +1,110 @@
+From e4aaed126e112579a27687674e6fa2e556f6acc5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Feb 2025 20:39:57 +0100
+Subject: ASoC: es8328: fix route from DAC to output
+
+From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
+
+[ Upstream commit 5b0c02f9b8acf2a791e531bbc09acae2d51f4f9b ]
+
+The ES8328 codec driver, which is also used for the ES8388 chip that
+appears to have an identical register map, claims that the output can
+either take the route from DAC->Mixer->Output or through DAC->Output
+directly. To the best of what I could find, this is not true, and
+creates problems.
+
+Without DACCONTROL17 bit index 7 set for the left channel, as well as
+DACCONTROL20 bit index 7 set for the right channel, I cannot get any
+analog audio out on Left Out 2 and Right Out 2 respectively, despite the
+DAPM routes claiming that this should be possible. Furthermore, the same
+is the case for Left Out 1 and Right Out 1, showing that those two don't
+have a direct route from DAC to output bypassing the mixer either.
+
+Those control bits toggle whether the DACs are fed (stale bread?) into
+their respective mixers. If one "unmutes" the mixer controls in
+alsamixer, then sure, the audio output works, but if it doesn't work
+without the mixer being fed the DAC input then evidently it's not a
+direct output from the DAC.
+
+ES8328/ES8388 are seemingly not alone in this. ES8323, which uses a
+separate driver for what appears to be a very similar register map,
+simply flips those two bits on in its probe function, and then pretends
+there is no power management whatsoever for the individual controls.
+Fair enough.
+
+My theory as to why nobody has noticed this up to this point is that
+everyone just assumes it's their fault when they had to unmute an
+additional control in ALSA.
+
+Fix this in the es8328 driver by removing the erroneous direct route,
+then get rid of the playback switch controls and have those bits tied to
+the mixer's widget instead, which until now had no register to play
+with.
+
+Fixes: 567e4f98922c ("ASoC: add es8328 codec driver")
+Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
+Link: https://patch.msgid.link/20250222-es8328-route-bludgeoning-v1-1-99bfb7fb22d9@collabora.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/es8328.c | 15 ++++-----------
+ 1 file changed, 4 insertions(+), 11 deletions(-)
+
+diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c
+index f3c97da798dc8..76159c45e6b52 100644
+--- a/sound/soc/codecs/es8328.c
++++ b/sound/soc/codecs/es8328.c
+@@ -233,7 +233,6 @@ static const struct snd_kcontrol_new es8328_right_line_controls =
+ /* Left Mixer */
+ static const struct snd_kcontrol_new es8328_left_mixer_controls[] = {
+-      SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL17, 7, 1, 0),
+       SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL17, 6, 1, 0),
+       SOC_DAPM_SINGLE("Right Playback Switch", ES8328_DACCONTROL18, 7, 1, 0),
+       SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL18, 6, 1, 0),
+@@ -243,7 +242,6 @@ static const struct snd_kcontrol_new es8328_left_mixer_controls[] = {
+ static const struct snd_kcontrol_new es8328_right_mixer_controls[] = {
+       SOC_DAPM_SINGLE("Left Playback Switch", ES8328_DACCONTROL19, 7, 1, 0),
+       SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL19, 6, 1, 0),
+-      SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL20, 7, 1, 0),
+       SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL20, 6, 1, 0),
+ };
+@@ -336,10 +334,10 @@ static const struct snd_soc_dapm_widget es8328_dapm_widgets[] = {
+       SND_SOC_DAPM_DAC("Left DAC", "Left Playback", ES8328_DACPOWER,
+                       ES8328_DACPOWER_LDAC_OFF, 1),
+-      SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
++      SND_SOC_DAPM_MIXER("Left Mixer", ES8328_DACCONTROL17, 7, 0,
+               &es8328_left_mixer_controls[0],
+               ARRAY_SIZE(es8328_left_mixer_controls)),
+-      SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
++      SND_SOC_DAPM_MIXER("Right Mixer", ES8328_DACCONTROL20, 7, 0,
+               &es8328_right_mixer_controls[0],
+               ARRAY_SIZE(es8328_right_mixer_controls)),
+@@ -418,19 +416,14 @@ static const struct snd_soc_dapm_route es8328_dapm_routes[] = {
+       { "Right Line Mux", "PGA", "Right PGA Mux" },
+       { "Right Line Mux", "Differential", "Differential Mux" },
+-      { "Left Out 1", NULL, "Left DAC" },
+-      { "Right Out 1", NULL, "Right DAC" },
+-      { "Left Out 2", NULL, "Left DAC" },
+-      { "Right Out 2", NULL, "Right DAC" },
+-
+-      { "Left Mixer", "Playback Switch", "Left DAC" },
++      { "Left Mixer", NULL, "Left DAC" },
+       { "Left Mixer", "Left Bypass Switch", "Left Line Mux" },
+       { "Left Mixer", "Right Playback Switch", "Right DAC" },
+       { "Left Mixer", "Right Bypass Switch", "Right Line Mux" },
+       { "Right Mixer", "Left Playback Switch", "Left DAC" },
+       { "Right Mixer", "Left Bypass Switch", "Left Line Mux" },
+-      { "Right Mixer", "Playback Switch", "Right DAC" },
++      { "Right Mixer", NULL, "Right DAC" },
+       { "Right Mixer", "Right Bypass Switch", "Right Line Mux" },
+       { "DAC DIG", NULL, "DAC STM" },
+-- 
+2.39.5
+
diff --git a/queue-6.13/asoc-fsl-rename-stream-name-of-sai-dai-driver.patch b/queue-6.13/asoc-fsl-rename-stream-name-of-sai-dai-driver.patch
new file mode 100644 (file)
index 0000000..b2c4d99
--- /dev/null
@@ -0,0 +1,73 @@
+From 7eb06a2553be9496c4b604bd6a8ab0ea82dcddde Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 10:04:37 +0900
+Subject: ASoC: fsl: Rename stream name of SAI DAI driver
+
+From: Chancel Liu <chancel.liu@nxp.com>
+
+[ Upstream commit 0da83ab025bc45e9742e87c2cce19bff423377c8 ]
+
+If stream names of DAI driver are duplicated there'll be warnings when
+machine driver tries to add widgets on a route:
+
+[    8.831335] fsl-asoc-card sound-wm8960: ASoC: sink widget CPU-Playback overwritten
+[    8.839917] fsl-asoc-card sound-wm8960: ASoC: source widget CPU-Capture overwritten
+
+Use different stream names to avoid such warnings.
+DAI names in AUDMIX are also updated accordingly.
+
+Fixes: 15c958390460 ("ASoC: fsl_sai: Add separate DAI for transmitter and receiver")
+Signed-off-by: Chancel Liu <chancel.liu@nxp.com>
+Acked-by: Shengjiu Wang <shengjiu.wang@gmail.com>
+Link: https://patch.msgid.link/20250217010437.258621-1-chancel.liu@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_sai.c    | 6 +++---
+ sound/soc/fsl/imx-audmix.c | 4 ++--
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
+index 634168d2bb6e5..c5efbceb06d1f 100644
+--- a/sound/soc/fsl/fsl_sai.c
++++ b/sound/soc/fsl/fsl_sai.c
+@@ -994,10 +994,10 @@ static struct snd_soc_dai_driver fsl_sai_dai_template[] = {
+       {
+               .name = "sai-tx",
+               .playback = {
+-                      .stream_name = "CPU-Playback",
++                      .stream_name = "SAI-Playback",
+                       .channels_min = 1,
+                       .channels_max = 32,
+-                              .rate_min = 8000,
++                      .rate_min = 8000,
+                       .rate_max = 2822400,
+                       .rates = SNDRV_PCM_RATE_KNOT,
+                       .formats = FSL_SAI_FORMATS,
+@@ -1007,7 +1007,7 @@ static struct snd_soc_dai_driver fsl_sai_dai_template[] = {
+       {
+               .name = "sai-rx",
+               .capture = {
+-                      .stream_name = "CPU-Capture",
++                      .stream_name = "SAI-Capture",
+                       .channels_min = 1,
+                       .channels_max = 32,
+                       .rate_min = 8000,
+diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c
+index 50ecc5f51100e..dac5d4ddacd6e 100644
+--- a/sound/soc/fsl/imx-audmix.c
++++ b/sound/soc/fsl/imx-audmix.c
+@@ -119,8 +119,8 @@ static const struct snd_soc_ops imx_audmix_be_ops = {
+ static const char *name[][3] = {
+       {"HiFi-AUDMIX-FE-0", "HiFi-AUDMIX-FE-1", "HiFi-AUDMIX-FE-2"},
+       {"sai-tx", "sai-tx", "sai-rx"},
+-      {"AUDMIX-Playback-0", "AUDMIX-Playback-1", "CPU-Capture"},
+-      {"CPU-Playback", "CPU-Playback", "AUDMIX-Capture-0"},
++      {"AUDMIX-Playback-0", "AUDMIX-Playback-1", "SAI-Capture"},
++      {"SAI-Playback", "SAI-Playback", "AUDMIX-Capture-0"},
+ };
+ static int imx_audmix_probe(struct platform_device *pdev)
+-- 
+2.39.5
+
diff --git a/queue-6.13/bluetooth-l2cap-fix-l2cap_ecred_conn_rsp-response.patch b/queue-6.13/bluetooth-l2cap-fix-l2cap_ecred_conn_rsp-response.patch
new file mode 100644 (file)
index 0000000..7864a67
--- /dev/null
@@ -0,0 +1,99 @@
+From e60fc1ffd3e8c32ef4df122e2097c2ab408fa2f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Feb 2025 10:30:25 -0500
+Subject: Bluetooth: L2CAP: Fix L2CAP_ECRED_CONN_RSP response
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit b25120e1d5f2ebb3db00af557709041f47f7f3d0 ]
+
+L2CAP_ECRED_CONN_RSP needs to respond DCID in the same order received as
+SCID but the order is reversed due to use of list_add which actually
+prepend channels to the list so the response is reversed:
+
+> ACL Data RX: Handle 16 flags 0x02 dlen 26
+      LE L2CAP: Enhanced Credit Connection Request (0x17) ident 2 len 18
+        PSM: 39 (0x0027)
+        MTU: 256
+        MPS: 251
+        Credits: 65535
+        Source CID: 116
+        Source CID: 117
+        Source CID: 118
+        Source CID: 119
+        Source CID: 120
+< ACL Data TX: Handle 16 flags 0x00 dlen 26
+      LE L2CAP: Enhanced Credit Connection Response (0x18) ident 2 len 18
+        MTU: 517
+        MPS: 247
+        Credits: 3
+        Result: Connection successful (0x0000)
+        Destination CID: 68
+        Destination CID: 67
+        Destination CID: 66
+        Destination CID: 65
+        Destination CID: 64
+
+Also make sure the response don't include channels that are not on
+BT_CONNECT2 since the chan->ident can be set to the same value as in the
+following trace:
+
+< ACL Data TX: Handle 16 flags 0x00 dlen 12
+      LE L2CAP: LE Flow Control Credit (0x16) ident 6 len 4
+        Source CID: 64
+        Credits: 1
+...
+> ACL Data RX: Handle 16 flags 0x02 dlen 18
+      LE L2CAP: Enhanced Credit Connection Request (0x17) ident 6 len 10
+        PSM: 39 (0x0027)
+        MTU: 517
+        MPS: 251
+        Credits: 255
+        Source CID: 70
+< ACL Data TX: Handle 16 flags 0x00 dlen 20
+      LE L2CAP: Enhanced Credit Connection Response (0x18) ident 6 len 12
+        MTU: 517
+        MPS: 247
+        Credits: 3
+        Result: Connection successful (0x0000)
+        Destination CID: 64
+        Destination CID: 68
+
+Closes: https://github.com/bluez/bluez/issues/1094
+Fixes: 9aa9d9473f15 ("Bluetooth: L2CAP: Fix responding with wrong PDU type")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 27b4c4a2ba1fd..728a5ce9b5058 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -636,7 +636,8 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
+           test_bit(FLAG_HOLD_HCI_CONN, &chan->flags))
+               hci_conn_hold(conn->hcon);
+-      list_add(&chan->list, &conn->chan_l);
++      /* Append to the list since the order matters for ECRED */
++      list_add_tail(&chan->list, &conn->chan_l);
+ }
+ void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
+@@ -3776,7 +3777,11 @@ static void l2cap_ecred_rsp_defer(struct l2cap_chan *chan, void *data)
+       struct l2cap_ecred_conn_rsp *rsp_flex =
+               container_of(&rsp->pdu.rsp, struct l2cap_ecred_conn_rsp, hdr);
+-      if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags))
++      /* Check if channel for outgoing connection or if it wasn't deferred
++       * since in those cases it must be skipped.
++       */
++      if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags) ||
++          !test_and_clear_bit(FLAG_DEFER_SETUP, &chan->flags))
+               return;
+       /* Reset ident so only one response is sent */
+-- 
+2.39.5
+
diff --git a/queue-6.13/drm-amd-display-restore-edid-reading-from-a-given-i2.patch b/queue-6.13/drm-amd-display-restore-edid-reading-from-a-given-i2.patch
new file mode 100644 (file)
index 0000000..4d96831
--- /dev/null
@@ -0,0 +1,78 @@
+From bcef80708907e45c302cfc7c1890f62df0d22d77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Feb 2025 18:15:47 -0300
+Subject: drm/amd/display: restore edid reading from a given i2c adapter
+
+From: Melissa Wen <mwen@igalia.com>
+
+[ Upstream commit 12f3b92d1cfa5526715fff93a6d6fe29300d5e2a ]
+
+When switching to drm_edid, we slightly changed how to get edid by
+removing the possibility of getting them from dc_link when in aux
+transaction mode. As MST doesn't initialize the connector with
+`drm_connector_init_with_ddc()`, restore the original behavior to avoid
+functional changes.
+
+v2:
+- Fix build warning of unchecked dereference (kernel test bot)
+
+CC: Alex Hung <alex.hung@amd.com>
+CC: Mario Limonciello <mario.limonciello@amd.com>
+CC: Roman Li <Roman.Li@amd.com>
+CC: Aurabindo Pillai <Aurabindo.Pillai@amd.com>
+Fixes: 48edb2a4256e ("drm/amd/display: switch amdgpu_dm_connector to use struct drm_edid")
+Reviewed-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Melissa Wen <mwen@igalia.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 81262b1656feb3813e3d917ab78824df6831e69e)
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c   | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index f7c0d7625ff12..35b9e026fe0d5 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -7180,8 +7180,14 @@ static void amdgpu_dm_connector_funcs_force(struct drm_connector *connector)
+       struct dc_link *dc_link = aconnector->dc_link;
+       struct dc_sink *dc_em_sink = aconnector->dc_em_sink;
+       const struct drm_edid *drm_edid;
++      struct i2c_adapter *ddc;
+-      drm_edid = drm_edid_read(connector);
++      if (dc_link && dc_link->aux_mode)
++              ddc = &aconnector->dm_dp_aux.aux.ddc;
++      else
++              ddc = &aconnector->i2c->base;
++
++      drm_edid = drm_edid_read_ddc(connector, ddc);
+       drm_edid_connector_update(connector, drm_edid);
+       if (!drm_edid) {
+               DRM_ERROR("No EDID found on connector: %s.\n", connector->name);
+@@ -7226,14 +7232,21 @@ static int get_modes(struct drm_connector *connector)
+ static void create_eml_sink(struct amdgpu_dm_connector *aconnector)
+ {
+       struct drm_connector *connector = &aconnector->base;
++      struct dc_link *dc_link = aconnector->dc_link;
+       struct dc_sink_init_data init_params = {
+                       .link = aconnector->dc_link,
+                       .sink_signal = SIGNAL_TYPE_VIRTUAL
+       };
+       const struct drm_edid *drm_edid;
+       const struct edid *edid;
++      struct i2c_adapter *ddc;
++
++      if (dc_link && dc_link->aux_mode)
++              ddc = &aconnector->dm_dp_aux.aux.ddc;
++      else
++              ddc = &aconnector->i2c->base;
+-      drm_edid = drm_edid_read(connector);
++      drm_edid = drm_edid_read_ddc(connector, ddc);
+       drm_edid_connector_update(connector, drm_edid);
+       if (!drm_edid) {
+               DRM_ERROR("No EDID found on connector: %s.\n", connector->name);
+-- 
+2.39.5
+
diff --git a/queue-6.13/drm-amdgpu-gfx-only-call-mes-for-enforce-isolation-i.patch b/queue-6.13/drm-amdgpu-gfx-only-call-mes-for-enforce-isolation-i.patch
new file mode 100644 (file)
index 0000000..b333e49
--- /dev/null
@@ -0,0 +1,46 @@
+From c3b184cf4e4097a0de16a031a2fd729a25d6c34d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Feb 2025 13:37:01 -0500
+Subject: drm/amdgpu/gfx: only call mes for enforce isolation if supported
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit e7ea88207cef513514e706aacc534527ac88b9b8 ]
+
+This should not be called on chips without MES so check if
+MES is enabled and if the cleaner shader is supported.
+
+Fixes: 8521e3c5f058 ("drm/amd/amdgpu: limit single process inside MES")
+Reviewed-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: Shaoyun Liu <shaoyun.liu@amd.com>
+Cc: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+(cherry picked from commit 80513e389765c8f9543b26d8fa4bbdf0e59ff8bc)
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+index 9a4dad3e41529..11aa55bd16d28 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+@@ -1598,11 +1598,13 @@ static ssize_t amdgpu_gfx_set_enforce_isolation(struct device *dev,
+               if (adev->enforce_isolation[i] && !partition_values[i]) {
+                       /* Going from enabled to disabled */
+                       amdgpu_vmid_free_reserved(adev, AMDGPU_GFXHUB(i));
+-                      amdgpu_mes_set_enforce_isolation(adev, i, false);
++                      if (adev->enable_mes && adev->gfx.enable_cleaner_shader)
++                              amdgpu_mes_set_enforce_isolation(adev, i, false);
+               } else if (!adev->enforce_isolation[i] && partition_values[i]) {
+                       /* Going from disabled to enabled */
+                       amdgpu_vmid_alloc_reserved(adev, AMDGPU_GFXHUB(i));
+-                      amdgpu_mes_set_enforce_isolation(adev, i, true);
++                      if (adev->enable_mes && adev->gfx.enable_cleaner_shader)
++                              amdgpu_mes_set_enforce_isolation(adev, i, true);
+               }
+               adev->enforce_isolation[i] = partition_values[i];
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.13/drm-amdgpu-mes-keep-enforce-isolation-up-to-date.patch b/queue-6.13/drm-amdgpu-mes-keep-enforce-isolation-up-to-date.patch
new file mode 100644 (file)
index 0000000..adfbb90
--- /dev/null
@@ -0,0 +1,144 @@
+From 1b2b37bd3b5b1f5186314ff68706394fd254d336 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Feb 2025 12:32:30 -0500
+Subject: drm/amdgpu/mes: keep enforce isolation up to date
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 748a1f51bb74453f1fe22d3ca68a717cb31f02e5 ]
+
+Re-send the mes message on resume to make sure the
+mes state is up to date.
+
+Fixes: 8521e3c5f058 ("drm/amd/amdgpu: limit single process inside MES")
+Acked-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: Shaoyun Liu <shaoyun.liu@amd.com>
+Cc: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 27b791514789844e80da990c456c2465325e0851)
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 13 ++++---------
+ drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 20 +++++++++++++++++++-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h |  2 +-
+ drivers/gpu/drm/amd/amdgpu/mes_v11_0.c  |  4 ++++
+ drivers/gpu/drm/amd/amdgpu/mes_v12_0.c  |  4 ++++
+ 5 files changed, 32 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+index 11aa55bd16d28..7ec35e3677585 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+@@ -1593,24 +1593,19 @@ static ssize_t amdgpu_gfx_set_enforce_isolation(struct device *dev,
+       }
+       mutex_lock(&adev->enforce_isolation_mutex);
+-
+       for (i = 0; i < num_partitions; i++) {
+-              if (adev->enforce_isolation[i] && !partition_values[i]) {
++              if (adev->enforce_isolation[i] && !partition_values[i])
+                       /* Going from enabled to disabled */
+                       amdgpu_vmid_free_reserved(adev, AMDGPU_GFXHUB(i));
+-                      if (adev->enable_mes && adev->gfx.enable_cleaner_shader)
+-                              amdgpu_mes_set_enforce_isolation(adev, i, false);
+-              } else if (!adev->enforce_isolation[i] && partition_values[i]) {
++              else if (!adev->enforce_isolation[i] && partition_values[i])
+                       /* Going from disabled to enabled */
+                       amdgpu_vmid_alloc_reserved(adev, AMDGPU_GFXHUB(i));
+-                      if (adev->enable_mes && adev->gfx.enable_cleaner_shader)
+-                              amdgpu_mes_set_enforce_isolation(adev, i, true);
+-              }
+               adev->enforce_isolation[i] = partition_values[i];
+       }
+-
+       mutex_unlock(&adev->enforce_isolation_mutex);
++      amdgpu_mes_update_enforce_isolation(adev);
++
+       return count;
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+index 59ec20b07a6af..452ca07e7e7d2 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+@@ -1679,7 +1679,8 @@ bool amdgpu_mes_suspend_resume_all_supported(struct amdgpu_device *adev)
+ }
+ /* Fix me -- node_id is used to identify the correct MES instances in the future */
+-int amdgpu_mes_set_enforce_isolation(struct amdgpu_device *adev, uint32_t node_id, bool enable)
++static int amdgpu_mes_set_enforce_isolation(struct amdgpu_device *adev,
++                                          uint32_t node_id, bool enable)
+ {
+       struct mes_misc_op_input op_input = {0};
+       int r;
+@@ -1701,6 +1702,23 @@ int amdgpu_mes_set_enforce_isolation(struct amdgpu_device *adev, uint32_t node_i
+       return r;
+ }
++int amdgpu_mes_update_enforce_isolation(struct amdgpu_device *adev)
++{
++      int i, r = 0;
++
++      if (adev->enable_mes && adev->gfx.enable_cleaner_shader) {
++              mutex_lock(&adev->enforce_isolation_mutex);
++              for (i = 0; i < (adev->xcp_mgr ? adev->xcp_mgr->num_xcps : 1); i++) {
++                      if (adev->enforce_isolation[i])
++                              r |= amdgpu_mes_set_enforce_isolation(adev, i, true);
++                      else
++                              r |= amdgpu_mes_set_enforce_isolation(adev, i, false);
++              }
++              mutex_unlock(&adev->enforce_isolation_mutex);
++      }
++      return r;
++}
++
+ #if defined(CONFIG_DEBUG_FS)
+ static int amdgpu_debugfs_mes_event_log_show(struct seq_file *m, void *unused)
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
+index c6f93cbd6739f..f089c5087c63d 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
+@@ -534,6 +534,6 @@ static inline void amdgpu_mes_unlock(struct amdgpu_mes *mes)
+ bool amdgpu_mes_suspend_resume_all_supported(struct amdgpu_device *adev);
+-int amdgpu_mes_set_enforce_isolation(struct amdgpu_device *adev, uint32_t node_id, bool enable);
++int amdgpu_mes_update_enforce_isolation(struct amdgpu_device *adev);
+ #endif /* __AMDGPU_MES_H__ */
+diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+index 9c905b9e93763..40750e5478efb 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+@@ -1635,6 +1635,10 @@ static int mes_v11_0_hw_init(struct amdgpu_ip_block *ip_block)
+               goto failure;
+       }
++      r = amdgpu_mes_update_enforce_isolation(adev);
++      if (r)
++              goto failure;
++
+ out:
+       /*
+        * Disable KIQ ring usage from the driver once MES is enabled.
+diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
+index 9ecc5d61e49ba..0921fd8c050da 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
+@@ -1590,6 +1590,10 @@ static int mes_v12_0_hw_init(struct amdgpu_ip_block *ip_block)
+               goto failure;
+       }
++      r = amdgpu_mes_update_enforce_isolation(adev);
++      if (r)
++              goto failure;
++
+ out:
+       /*
+        * Disable KIQ ring usage from the driver once MES is enabled.
+-- 
+2.39.5
+
diff --git a/queue-6.13/drm-xe-cancel-pending-job-timer-before-freeing-sched.patch b/queue-6.13/drm-xe-cancel-pending-job-timer-before-freeing-sched.patch
new file mode 100644 (file)
index 0000000..ef75d67
--- /dev/null
@@ -0,0 +1,47 @@
+From 2a58a4edc3e927fd355744e285ba6cbb47f782f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 10:27:54 +0530
+Subject: drm/xe: cancel pending job timer before freeing scheduler
+
+From: Tejas Upadhyay <tejas.upadhyay@intel.com>
+
+[ Upstream commit 12c2f962fe71f390951d9242725bc7e608f55927 ]
+
+The async call to __guc_exec_queue_fini_async frees the scheduler
+while a submission may time out and restart. To prevent this race
+condition, the pending job timer should be canceled before freeing
+the scheduler.
+
+V3(MattB):
+ - Adjust position of cancel pending job
+ - Remove gitlab issue# from commit message
+V2(MattB):
+ - Cancel pending jobs before scheduler finish
+
+Fixes: a20c75dba192 ("drm/xe: Call __guc_exec_queue_fini_async direct for KERNEL exec_queues")
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250225045754.600905-1-tejas.upadhyay@intel.com
+Signed-off-by: Tejas Upadhyay <tejas.upadhyay@intel.com>
+(cherry picked from commit 18fbd567e75f9b97b699b2ab4f1fa76b7cf268f6)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_guc_submit.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c
+index 6f4a9812b4f4a..fe17e9ba86725 100644
+--- a/drivers/gpu/drm/xe/xe_guc_submit.c
++++ b/drivers/gpu/drm/xe/xe_guc_submit.c
+@@ -1238,6 +1238,8 @@ static void __guc_exec_queue_fini_async(struct work_struct *w)
+       if (xe_exec_queue_is_lr(q))
+               cancel_work_sync(&ge->lr_tdr);
++      /* Confirm no work left behind accessing device structures */
++      cancel_delayed_work_sync(&ge->sched.base.work_tdr);
+       release_guc_id(guc, q);
+       xe_sched_entity_fini(&ge->entity);
+       xe_sched_fini(&ge->sched);
+-- 
+2.39.5
+
diff --git a/queue-6.13/drm-xe-oa-allow-oa_exponent-value-of-0.patch b/queue-6.13/drm-xe-oa-allow-oa_exponent-value-of-0.patch
new file mode 100644 (file)
index 0000000..51885b5
--- /dev/null
@@ -0,0 +1,61 @@
+From 26071e9a2703203d9d6d40b3e5eb6a49c6387b56 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Feb 2025 13:33:52 -0800
+Subject: drm/xe/oa: Allow oa_exponent value of 0
+
+From: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
+
+[ Upstream commit 5bd566703e16b17d17f4fb648440d54f8967462c ]
+
+OA exponent value of 0 is a valid value for periodic reports. Allow user
+to pass 0 for the OA sampling interval since it gets converted to 2 gt
+clock ticks.
+
+v2: Update the check in xe_oa_stream_init as well (Ashutosh)
+v3: Fix mi-rpc failure by setting default exponent to -1 (CI)
+v4: Add the Fixes tag
+
+Fixes: b6fd51c62119 ("drm/xe/oa/uapi: Define and parse OA stream properties")
+Signed-off-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
+Reviewed-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250221213352.1712932-1-umesh.nerlige.ramappa@intel.com
+(cherry picked from commit 30341f0b8ea71725cc4ab2c43e3a3b749892fc92)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_oa.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c
+index 913f6ba606370..5c50ca8cd8e78 100644
+--- a/drivers/gpu/drm/xe/xe_oa.c
++++ b/drivers/gpu/drm/xe/xe_oa.c
+@@ -1766,7 +1766,7 @@ static int xe_oa_stream_init(struct xe_oa_stream *stream,
+       stream->oa_buffer.format = &stream->oa->oa_formats[param->oa_format];
+       stream->sample = param->sample;
+-      stream->periodic = param->period_exponent > 0;
++      stream->periodic = param->period_exponent >= 0;
+       stream->period_exponent = param->period_exponent;
+       stream->no_preempt = param->no_preempt;
+       stream->wait_num_reports = param->wait_num_reports;
+@@ -2058,6 +2058,7 @@ int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *f
+       }
+       param.xef = xef;
++      param.period_exponent = -1;
+       ret = xe_oa_user_extensions(oa, XE_OA_USER_EXTN_FROM_OPEN, data, 0, &param);
+       if (ret)
+               return ret;
+@@ -2112,7 +2113,7 @@ int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *f
+               goto err_exec_q;
+       }
+-      if (param.period_exponent > 0) {
++      if (param.period_exponent >= 0) {
+               u64 oa_period, oa_freq_hz;
+               /* Requesting samples from OAG buffer is a privileged operation */
+-- 
+2.39.5
+
diff --git a/queue-6.13/firmware-cs_dsp-remove-async-regmap-writes.patch b/queue-6.13/firmware-cs_dsp-remove-async-regmap-writes.patch
new file mode 100644 (file)
index 0000000..343c450
--- /dev/null
@@ -0,0 +1,115 @@
+From 347da59265413523299cd3c973c408c9cbb49da3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 13:18:42 +0000
+Subject: firmware: cs_dsp: Remove async regmap writes
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit fe08b7d5085a9774abc30c26d5aebc5b9cdd6091 ]
+
+Change calls to async regmap write functions to use the normal
+blocking writes so that the cs35l56 driver can use spi_bus_lock() to
+gain exclusive access to the SPI bus.
+
+As this is part of a fix, it makes only the minimal change to swap the
+functions to the blocking equivalents. There's no need to risk
+reworking the buffer allocation logic that is now partially redundant.
+
+The async writes are a 12-year-old workaround for inefficiency of
+synchronous writes in the SPI subsystem. The SPI subsystem has since
+been changed to avoid the overheads, so this workaround should not be
+necessary.
+
+The cs35l56 driver needs to use spi_bus_lock() prevent bus activity
+while it is soft-resetting the cs35l56. But spi_bus_lock() is
+incompatible with spi_async() calls, which will fail with -EBUSY.
+
+Fixes: 8a731fd37f8b ("ASoC: cs35l56: Move utility functions to shared file")
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Link: https://patch.msgid.link/20250225131843.113752-2-rf@opensource.cirrus.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/cirrus/cs_dsp.c | 24 ++++++------------------
+ 1 file changed, 6 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c
+index 5365e9a430007..42433c19eb308 100644
+--- a/drivers/firmware/cirrus/cs_dsp.c
++++ b/drivers/firmware/cirrus/cs_dsp.c
+@@ -1609,8 +1609,8 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware,
+                               goto out_fw;
+                       }
+-                      ret = regmap_raw_write_async(regmap, reg, buf->buf,
+-                                                   le32_to_cpu(region->len));
++                      ret = regmap_raw_write(regmap, reg, buf->buf,
++                                             le32_to_cpu(region->len));
+                       if (ret != 0) {
+                               cs_dsp_err(dsp,
+                                          "%s.%d: Failed to write %d bytes at %d in %s: %d\n",
+@@ -1625,12 +1625,6 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware,
+               regions++;
+       }
+-      ret = regmap_async_complete(regmap);
+-      if (ret != 0) {
+-              cs_dsp_err(dsp, "Failed to complete async write: %d\n", ret);
+-              goto out_fw;
+-      }
+-
+       if (pos > firmware->size)
+               cs_dsp_warn(dsp, "%s.%d: %zu bytes at end of file\n",
+                           file, regions, pos - firmware->size);
+@@ -1638,7 +1632,6 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware,
+       cs_dsp_debugfs_save_wmfwname(dsp, file);
+ out_fw:
+-      regmap_async_complete(regmap);
+       cs_dsp_buf_free(&buf_list);
+       if (ret == -EOVERFLOW)
+@@ -2326,8 +2319,8 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware
+                       cs_dsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n",
+                                  file, blocks, le32_to_cpu(blk->len),
+                                  reg);
+-                      ret = regmap_raw_write_async(regmap, reg, buf->buf,
+-                                                   le32_to_cpu(blk->len));
++                      ret = regmap_raw_write(regmap, reg, buf->buf,
++                                             le32_to_cpu(blk->len));
+                       if (ret != 0) {
+                               cs_dsp_err(dsp,
+                                          "%s.%d: Failed to write to %x in %s: %d\n",
+@@ -2339,10 +2332,6 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware
+               blocks++;
+       }
+-      ret = regmap_async_complete(regmap);
+-      if (ret != 0)
+-              cs_dsp_err(dsp, "Failed to complete async write: %d\n", ret);
+-
+       if (pos > firmware->size)
+               cs_dsp_warn(dsp, "%s.%d: %zu bytes at end of file\n",
+                           file, blocks, pos - firmware->size);
+@@ -2350,7 +2339,6 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware
+       cs_dsp_debugfs_save_binname(dsp, file);
+ out_fw:
+-      regmap_async_complete(regmap);
+       cs_dsp_buf_free(&buf_list);
+       if (ret == -EOVERFLOW)
+@@ -2561,8 +2549,8 @@ static int cs_dsp_adsp2_enable_core(struct cs_dsp *dsp)
+ {
+       int ret;
+-      ret = regmap_update_bits_async(dsp->regmap, dsp->base + ADSP2_CONTROL,
+-                                     ADSP2_SYS_ENA, ADSP2_SYS_ENA);
++      ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
++                               ADSP2_SYS_ENA, ADSP2_SYS_ENA);
+       if (ret != 0)
+               return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.13/ice-avoid-setting-default-rx-vsi-twice-in-switchdev-.patch b/queue-6.13/ice-avoid-setting-default-rx-vsi-twice-in-switchdev-.patch
new file mode 100644 (file)
index 0000000..93efb6a
--- /dev/null
@@ -0,0 +1,57 @@
+From b49c57a78debdb2016c876aa52336c495fdfa654 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 11:06:42 -0800
+Subject: ice: Avoid setting default Rx VSI twice in switchdev setup
+
+From: Marcin Szycik <marcin.szycik@linux.intel.com>
+
+[ Upstream commit 5c07be96d8b3f8447e980f29b967bf2e1d7ac732 ]
+
+As part of switchdev environment setup, uplink VSI is configured as
+default for both Tx and Rx. Default Rx VSI is also used by promiscuous
+mode. If promisc mode is enabled and an attempt to enter switchdev mode
+is made, the setup will fail because Rx VSI is already configured as
+default (rule exists).
+
+Reproducer:
+  devlink dev eswitch set $PF1_PCI mode switchdev
+  ip l s $PF1 up
+  ip l s $PF1 promisc on
+  echo 1 > /sys/class/net/$PF1/device/sriov_numvfs
+
+In switchdev setup, use ice_set_dflt_vsi() instead of plain
+ice_cfg_dflt_vsi(), which avoids repeating setting default VSI for Rx if
+it's already configured.
+
+Fixes: 50d62022f455 ("ice: default Tx rule instead of to queue")
+Reported-by: Sujai Buvaneswaran <sujai.buvaneswaran@intel.com>
+Closes: https://lore.kernel.org/intel-wired-lan/PH0PR11MB50138B635F2E5CEB7075325D961F2@PH0PR11MB5013.namprd11.prod.outlook.com
+Reviewed-by: Martyna Szapar-Mudlaw <martyna.szapar-mudlaw@linux.intel.com>
+Signed-off-by: Marcin Szycik <marcin.szycik@linux.intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Sujai Buvaneswaran <sujai.buvaneswaran@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Link: https://patch.msgid.link/20250224190647.3601930-3-anthony.l.nguyen@intel.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_eswitch.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_eswitch.c b/drivers/net/ethernet/intel/ice/ice_eswitch.c
+index fb527434b58b1..d649c197cf673 100644
+--- a/drivers/net/ethernet/intel/ice/ice_eswitch.c
++++ b/drivers/net/ethernet/intel/ice/ice_eswitch.c
+@@ -38,8 +38,7 @@ static int ice_eswitch_setup_env(struct ice_pf *pf)
+       if (ice_vsi_add_vlan_zero(uplink_vsi))
+               goto err_vlan_zero;
+-      if (ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx, true,
+-                           ICE_FLTR_RX))
++      if (ice_set_dflt_vsi(uplink_vsi))
+               goto err_def_rx;
+       if (ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx, true,
+-- 
+2.39.5
+
diff --git a/queue-6.13/ice-fix-deinitializing-vf-in-error-path.patch b/queue-6.13/ice-fix-deinitializing-vf-in-error-path.patch
new file mode 100644 (file)
index 0000000..e763bb6
--- /dev/null
@@ -0,0 +1,114 @@
+From d2945c3534674ea9a9b0d4efcab319f13e8471b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 11:06:41 -0800
+Subject: ice: Fix deinitializing VF in error path
+
+From: Marcin Szycik <marcin.szycik@linux.intel.com>
+
+[ Upstream commit 79990cf5e7aded76d0c092c9f5ed31eb1c75e02c ]
+
+If ice_ena_vfs() fails after calling ice_create_vf_entries(), it frees
+all VFs without removing them from snapshot PF-VF mailbox list, leading
+to list corruption.
+
+Reproducer:
+  devlink dev eswitch set $PF1_PCI mode switchdev
+  ip l s $PF1 up
+  ip l s $PF1 promisc on
+  sleep 1
+  echo 1 > /sys/class/net/$PF1/device/sriov_numvfs
+  sleep 1
+  echo 1 > /sys/class/net/$PF1/device/sriov_numvfs
+
+Trace (minimized):
+  list_add corruption. next->prev should be prev (ffff8882e241c6f0), but was 0000000000000000. (next=ffff888455da1330).
+  kernel BUG at lib/list_debug.c:29!
+  RIP: 0010:__list_add_valid_or_report+0xa6/0x100
+   ice_mbx_init_vf_info+0xa7/0x180 [ice]
+   ice_initialize_vf_entry+0x1fa/0x250 [ice]
+   ice_sriov_configure+0x8d7/0x1520 [ice]
+   ? __percpu_ref_switch_mode+0x1b1/0x5d0
+   ? __pfx_ice_sriov_configure+0x10/0x10 [ice]
+
+Sometimes a KASAN report can be seen instead with a similar stack trace:
+  BUG: KASAN: use-after-free in __list_add_valid_or_report+0xf1/0x100
+
+VFs are added to this list in ice_mbx_init_vf_info(), but only removed
+in ice_free_vfs(). Move the removing to ice_free_vf_entries(), which is
+also being called in other places where VFs are being removed (including
+ice_free_vfs() itself).
+
+Fixes: 8cd8a6b17d27 ("ice: move VF overflow message count into struct ice_mbx_vf_info")
+Reported-by: Sujai Buvaneswaran <sujai.buvaneswaran@intel.com>
+Closes: https://lore.kernel.org/intel-wired-lan/PH0PR11MB50138B635F2E5CEB7075325D961F2@PH0PR11MB5013.namprd11.prod.outlook.com
+Reviewed-by: Martyna Szapar-Mudlaw <martyna.szapar-mudlaw@linux.intel.com>
+Signed-off-by: Marcin Szycik <marcin.szycik@linux.intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Sujai Buvaneswaran <sujai.buvaneswaran@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Link: https://patch.msgid.link/20250224190647.3601930-2-anthony.l.nguyen@intel.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_sriov.c          | 5 +----
+ drivers/net/ethernet/intel/ice/ice_vf_lib.c         | 8 ++++++++
+ drivers/net/ethernet/intel/ice/ice_vf_lib_private.h | 1 +
+ 3 files changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c b/drivers/net/ethernet/intel/ice/ice_sriov.c
+index b83f99c01d91b..8aabf7749aa5e 100644
+--- a/drivers/net/ethernet/intel/ice/ice_sriov.c
++++ b/drivers/net/ethernet/intel/ice/ice_sriov.c
+@@ -36,6 +36,7 @@ static void ice_free_vf_entries(struct ice_pf *pf)
+       hash_for_each_safe(vfs->table, bkt, tmp, vf, entry) {
+               hash_del_rcu(&vf->entry);
++              ice_deinitialize_vf_entry(vf);
+               ice_put_vf(vf);
+       }
+ }
+@@ -193,10 +194,6 @@ void ice_free_vfs(struct ice_pf *pf)
+                       wr32(hw, GLGEN_VFLRSTAT(reg_idx), BIT(bit_idx));
+               }
+-              /* clear malicious info since the VF is getting released */
+-              if (!ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
+-                      list_del(&vf->mbx_info.list_entry);
+-
+               mutex_unlock(&vf->cfg_lock);
+       }
+diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
+index c7c0c2f50c265..815ad0bfe8326 100644
+--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
++++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
+@@ -1036,6 +1036,14 @@ void ice_initialize_vf_entry(struct ice_vf *vf)
+       mutex_init(&vf->cfg_lock);
+ }
++void ice_deinitialize_vf_entry(struct ice_vf *vf)
++{
++      struct ice_pf *pf = vf->pf;
++
++      if (!ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
++              list_del(&vf->mbx_info.list_entry);
++}
++
+ /**
+  * ice_dis_vf_qs - Disable the VF queues
+  * @vf: pointer to the VF structure
+diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib_private.h b/drivers/net/ethernet/intel/ice/ice_vf_lib_private.h
+index 0c7e77c0a09fa..5392b04049862 100644
+--- a/drivers/net/ethernet/intel/ice/ice_vf_lib_private.h
++++ b/drivers/net/ethernet/intel/ice/ice_vf_lib_private.h
+@@ -24,6 +24,7 @@
+ #endif
+ void ice_initialize_vf_entry(struct ice_vf *vf);
++void ice_deinitialize_vf_entry(struct ice_vf *vf);
+ void ice_dis_vf_qs(struct ice_vf *vf);
+ int ice_check_vf_init(struct ice_vf *vf);
+ enum virtchnl_status_code ice_err_to_virt_err(int err);
+-- 
+2.39.5
+
diff --git a/queue-6.13/idpf-fix-checksums-set-in-idpf_rx_rsc.patch b/queue-6.13/idpf-fix-checksums-set-in-idpf_rx_rsc.patch
new file mode 100644 (file)
index 0000000..cc4c7ce
--- /dev/null
@@ -0,0 +1,80 @@
+From e59d82870b3199b2b8ec9eb97437244c0ff63c32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2025 22:12:52 +0000
+Subject: idpf: fix checksums set in idpf_rx_rsc()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 674fcb4f4a7e3e277417a01788cc6daae47c3804 ]
+
+idpf_rx_rsc() uses skb_transport_offset(skb) while the transport header
+is not set yet.
+
+This triggers the following warning for CONFIG_DEBUG_NET=y builds.
+
+DEBUG_NET_WARN_ON_ONCE(!skb_transport_header_was_set(skb))
+
+[   69.261620] WARNING: CPU: 7 PID: 0 at ./include/linux/skbuff.h:3020 idpf_vport_splitq_napi_poll (include/linux/skbuff.h:3020) idpf
+[   69.261629] Modules linked in: vfat fat dummy bridge intel_uncore_frequency_tpmi intel_uncore_frequency_common intel_vsec_tpmi idpf intel_vsec cdc_ncm cdc_eem cdc_ether usbnet mii xhci_pci xhci_hcd ehci_pci ehci_hcd libeth
+[   69.261644] CPU: 7 UID: 0 PID: 0 Comm: swapper/7 Tainted: G S      W          6.14.0-smp-DEV #1697
+[   69.261648] Tainted: [S]=CPU_OUT_OF_SPEC, [W]=WARN
+[   69.261650] RIP: 0010:idpf_vport_splitq_napi_poll (include/linux/skbuff.h:3020) idpf
+[   69.261677] ? __warn (kernel/panic.c:242 kernel/panic.c:748)
+[   69.261682] ? idpf_vport_splitq_napi_poll (include/linux/skbuff.h:3020) idpf
+[   69.261687] ? report_bug (lib/bug.c:?)
+[   69.261690] ? handle_bug (arch/x86/kernel/traps.c:285)
+[   69.261694] ? exc_invalid_op (arch/x86/kernel/traps.c:309)
+[   69.261697] ? asm_exc_invalid_op (arch/x86/include/asm/idtentry.h:621)
+[   69.261700] ? __pfx_idpf_vport_splitq_napi_poll (drivers/net/ethernet/intel/idpf/idpf_txrx.c:4011) idpf
+[   69.261704] ? idpf_vport_splitq_napi_poll (include/linux/skbuff.h:3020) idpf
+[   69.261708] ? idpf_vport_splitq_napi_poll (drivers/net/ethernet/intel/idpf/idpf_txrx.c:3072) idpf
+[   69.261712] __napi_poll (net/core/dev.c:7194)
+[   69.261716] net_rx_action (net/core/dev.c:7265)
+[   69.261718] ? __qdisc_run (net/sched/sch_generic.c:293)
+[   69.261721] ? sched_clock (arch/x86/include/asm/preempt.h:84 arch/x86/kernel/tsc.c:288)
+[   69.261726] handle_softirqs (kernel/softirq.c:561)
+
+Fixes: 3a8845af66edb ("idpf: add RX splitq napi poll support")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Alan Brady <alan.brady@intel.com>
+Cc: Joshua Hay <joshua.a.hay@intel.com>
+Cc: Willem de Bruijn <willemb@google.com>
+Acked-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Link: https://patch.msgid.link/20250226221253.1927782-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/idpf/idpf_txrx.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+index 9be6a6b59c4e1..977741c414980 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+@@ -3013,7 +3013,6 @@ static int idpf_rx_rsc(struct idpf_rx_queue *rxq, struct sk_buff *skb,
+       skb_shinfo(skb)->gso_size = rsc_seg_len;
+       skb_reset_network_header(skb);
+-      len = skb->len - skb_transport_offset(skb);
+       if (ipv4) {
+               struct iphdr *ipv4h = ip_hdr(skb);
+@@ -3022,6 +3021,7 @@ static int idpf_rx_rsc(struct idpf_rx_queue *rxq, struct sk_buff *skb,
+               /* Reset and set transport header offset in skb */
+               skb_set_transport_header(skb, sizeof(struct iphdr));
++              len = skb->len - skb_transport_offset(skb);
+               /* Compute the TCP pseudo header checksum*/
+               tcp_hdr(skb)->check =
+@@ -3031,6 +3031,7 @@ static int idpf_rx_rsc(struct idpf_rx_queue *rxq, struct sk_buff *skb,
+               skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
+               skb_set_transport_header(skb, sizeof(struct ipv6hdr));
++              len = skb->len - skb_transport_offset(skb);
+               tcp_hdr(skb)->check =
+                       ~tcp_v6_check(len, &ipv6h->saddr, &ipv6h->daddr, 0);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.13/ipvlan-ensure-network-headers-are-in-skb-linear-part.patch b/queue-6.13/ipvlan-ensure-network-headers-are-in-skb-linear-part.patch
new file mode 100644 (file)
index 0000000..685e98c
--- /dev/null
@@ -0,0 +1,113 @@
+From 2d30c17242d05c5a176e1554c6e8e30c3e9927a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Feb 2025 15:53:36 +0000
+Subject: ipvlan: ensure network headers are in skb linear part
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 27843ce6ba3d3122b65066550fe33fb8839f8aef ]
+
+syzbot found that ipvlan_process_v6_outbound() was assuming
+the IPv6 network header isis present in skb->head [1]
+
+Add the needed pskb_network_may_pull() calls for both
+IPv4 and IPv6 handlers.
+
+[1]
+BUG: KMSAN: uninit-value in __ipv6_addr_type+0xa2/0x490 net/ipv6/addrconf_core.c:47
+  __ipv6_addr_type+0xa2/0x490 net/ipv6/addrconf_core.c:47
+  ipv6_addr_type include/net/ipv6.h:555 [inline]
+  ip6_route_output_flags_noref net/ipv6/route.c:2616 [inline]
+  ip6_route_output_flags+0x51/0x720 net/ipv6/route.c:2651
+  ip6_route_output include/net/ip6_route.h:93 [inline]
+  ipvlan_route_v6_outbound+0x24e/0x520 drivers/net/ipvlan/ipvlan_core.c:476
+  ipvlan_process_v6_outbound drivers/net/ipvlan/ipvlan_core.c:491 [inline]
+  ipvlan_process_outbound drivers/net/ipvlan/ipvlan_core.c:541 [inline]
+  ipvlan_xmit_mode_l3 drivers/net/ipvlan/ipvlan_core.c:605 [inline]
+  ipvlan_queue_xmit+0xd72/0x1780 drivers/net/ipvlan/ipvlan_core.c:671
+  ipvlan_start_xmit+0x5b/0x210 drivers/net/ipvlan/ipvlan_main.c:223
+  __netdev_start_xmit include/linux/netdevice.h:5150 [inline]
+  netdev_start_xmit include/linux/netdevice.h:5159 [inline]
+  xmit_one net/core/dev.c:3735 [inline]
+  dev_hard_start_xmit+0x247/0xa20 net/core/dev.c:3751
+  sch_direct_xmit+0x399/0xd40 net/sched/sch_generic.c:343
+  qdisc_restart net/sched/sch_generic.c:408 [inline]
+  __qdisc_run+0x14da/0x35d0 net/sched/sch_generic.c:416
+  qdisc_run+0x141/0x4d0 include/net/pkt_sched.h:127
+  net_tx_action+0x78b/0x940 net/core/dev.c:5484
+  handle_softirqs+0x1a0/0x7c0 kernel/softirq.c:561
+  __do_softirq+0x14/0x1a kernel/softirq.c:595
+  do_softirq+0x9a/0x100 kernel/softirq.c:462
+  __local_bh_enable_ip+0x9f/0xb0 kernel/softirq.c:389
+  local_bh_enable include/linux/bottom_half.h:33 [inline]
+  rcu_read_unlock_bh include/linux/rcupdate.h:919 [inline]
+  __dev_queue_xmit+0x2758/0x57d0 net/core/dev.c:4611
+  dev_queue_xmit include/linux/netdevice.h:3311 [inline]
+  packet_xmit+0x9c/0x6c0 net/packet/af_packet.c:276
+  packet_snd net/packet/af_packet.c:3132 [inline]
+  packet_sendmsg+0x93e0/0xa7e0 net/packet/af_packet.c:3164
+  sock_sendmsg_nosec net/socket.c:718 [inline]
+
+Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.")
+Reported-by: syzbot+93ab4a777bafb9d9f960@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/67b74f01.050a0220.14d86d.02d8.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Mahesh Bandewar <maheshb@google.com>
+Link: https://patch.msgid.link/20250220155336.61884-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ipvlan/ipvlan_core.c | 21 ++++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
+index fd591ddb3884d..ca62188a317ad 100644
+--- a/drivers/net/ipvlan/ipvlan_core.c
++++ b/drivers/net/ipvlan/ipvlan_core.c
+@@ -416,20 +416,25 @@ struct ipvl_addr *ipvlan_addr_lookup(struct ipvl_port *port, void *lyr3h,
+ static noinline_for_stack int ipvlan_process_v4_outbound(struct sk_buff *skb)
+ {
+-      const struct iphdr *ip4h = ip_hdr(skb);
+       struct net_device *dev = skb->dev;
+       struct net *net = dev_net(dev);
+-      struct rtable *rt;
+       int err, ret = NET_XMIT_DROP;
++      const struct iphdr *ip4h;
++      struct rtable *rt;
+       struct flowi4 fl4 = {
+               .flowi4_oif = dev->ifindex,
+-              .flowi4_tos = inet_dscp_to_dsfield(ip4h_dscp(ip4h)),
+               .flowi4_flags = FLOWI_FLAG_ANYSRC,
+               .flowi4_mark = skb->mark,
+-              .daddr = ip4h->daddr,
+-              .saddr = ip4h->saddr,
+       };
++      if (!pskb_network_may_pull(skb, sizeof(struct iphdr)))
++              goto err;
++
++      ip4h = ip_hdr(skb);
++      fl4.daddr = ip4h->daddr;
++      fl4.saddr = ip4h->saddr;
++      fl4.flowi4_tos = inet_dscp_to_dsfield(ip4h_dscp(ip4h));
++
+       rt = ip_route_output_flow(net, &fl4, NULL);
+       if (IS_ERR(rt))
+               goto err;
+@@ -488,6 +493,12 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
+       struct net_device *dev = skb->dev;
+       int err, ret = NET_XMIT_DROP;
++      if (!pskb_network_may_pull(skb, sizeof(struct ipv6hdr))) {
++              DEV_STATS_INC(dev, tx_errors);
++              kfree_skb(skb);
++              return ret;
++      }
++
+       err = ipvlan_route_v6_outbound(dev, skb);
+       if (unlikely(err)) {
+               DEV_STATS_INC(dev, tx_errors);
+-- 
+2.39.5
+
diff --git a/queue-6.13/ipvs-always-clear-ipvs_property-flag-in-skb_scrub_pa.patch b/queue-6.13/ipvs-always-clear-ipvs_property-flag-in-skb_scrub_pa.patch
new file mode 100644 (file)
index 0000000..48f967a
--- /dev/null
@@ -0,0 +1,51 @@
+From c0c4371ccb2db8c28dde88bcef0ab744b3f83885 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Feb 2025 11:35:18 +0800
+Subject: ipvs: Always clear ipvs_property flag in skb_scrub_packet()
+
+From: Philo Lu <lulie@linux.alibaba.com>
+
+[ Upstream commit de2c211868b9424f9aa9b3432c4430825bafb41b ]
+
+We found an issue when using bpf_redirect with ipvs NAT mode after
+commit ff70202b2d1a ("dev_forward_skb: do not scrub skb mark within
+the same name space"). Particularly, we use bpf_redirect to return
+the skb directly back to the netif it comes from, i.e., xnet is
+false in skb_scrub_packet(), and then ipvs_property is preserved
+and SNAT is skipped in the rx path.
+
+ipvs_property has been already cleared when netns is changed in
+commit 2b5ec1a5f973 ("netfilter/ipvs: clear ipvs_property flag when
+SKB net namespace changed"). This patch just clears it in spite of
+netns.
+
+Fixes: 2b5ec1a5f973 ("netfilter/ipvs: clear ipvs_property flag when SKB net namespace changed")
+Signed-off-by: Philo Lu <lulie@linux.alibaba.com>
+Acked-by: Julian Anastasov <ja@ssi.bg>
+Link: https://patch.msgid.link/20250222033518.126087-1-lulie@linux.alibaba.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skbuff.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index f251a99f8d421..bed75273f8c47 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -6127,11 +6127,11 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet)
+       skb->offload_fwd_mark = 0;
+       skb->offload_l3_fwd_mark = 0;
+ #endif
++      ipvs_reset(skb);
+       if (!xnet)
+               return;
+-      ipvs_reset(skb);
+       skb->mark = 0;
+       skb_clear_tstamp(skb);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.13/net-add-net_passive_inc-and-net_passive_dec.patch b/queue-6.13/net-add-net_passive_inc-and-net_passive_dec.patch
new file mode 100644 (file)
index 0000000..9a23045
--- /dev/null
@@ -0,0 +1,104 @@
+From 0015ab294f7fa831bcf05abf3c23f468b31f8d75 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 11:11:27 -0800
+Subject: net: Add net_passive_inc() and net_passive_dec().
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit e57a6320215c3967f51ab0edeff87db2095440e4 ]
+
+net_drop_ns() is NULL when CONFIG_NET_NS is disabled.
+
+The next patch introduces a function that increments
+and decrements net->passive.
+
+As a prep, let's rename and export net_free() to
+net_passive_dec() and add net_passive_inc().
+
+Suggested-by: Eric Dumazet <edumazet@google.com>
+Link: https://lore.kernel.org/netdev/CANn89i+oUCt2VGvrbrweniTendZFEh+nwS=uonc004-aPkWy-Q@mail.gmail.com/
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20250217191129.19967-2-kuniyu@amazon.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 5c70eb5c593d ("net: better track kernel sockets lifetime")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/net_namespace.h | 11 +++++++++++
+ net/core/net_namespace.c    |  8 ++++----
+ 2 files changed, 15 insertions(+), 4 deletions(-)
+
+diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
+index 44be742cf4d60..47181fd749b25 100644
+--- a/include/net/net_namespace.h
++++ b/include/net/net_namespace.h
+@@ -295,6 +295,7 @@ static inline int check_net(const struct net *net)
+ }
+ void net_drop_ns(void *);
++void net_passive_dec(struct net *net);
+ #else
+@@ -324,8 +325,18 @@ static inline int check_net(const struct net *net)
+ }
+ #define net_drop_ns NULL
++
++static inline void net_passive_dec(struct net *net)
++{
++      refcount_dec(&net->passive);
++}
+ #endif
++static inline void net_passive_inc(struct net *net)
++{
++      refcount_inc(&net->passive);
++}
++
+ /* Returns true if the netns initialization is completed successfully */
+ static inline bool net_initialized(const struct net *net)
+ {
+diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
+index b5cd3ae4f04cf..b71aa96eeee23 100644
+--- a/net/core/net_namespace.c
++++ b/net/core/net_namespace.c
+@@ -464,7 +464,7 @@ static void net_complete_free(void)
+ }
+-static void net_free(struct net *net)
++void net_passive_dec(struct net *net)
+ {
+       if (refcount_dec_and_test(&net->passive)) {
+               kfree(rcu_access_pointer(net->gen));
+@@ -482,7 +482,7 @@ void net_drop_ns(void *p)
+       struct net *net = (struct net *)p;
+       if (net)
+-              net_free(net);
++              net_passive_dec(net);
+ }
+ struct net *copy_net_ns(unsigned long flags,
+@@ -523,7 +523,7 @@ struct net *copy_net_ns(unsigned long flags,
+               key_remove_domain(net->key_domain);
+ #endif
+               put_user_ns(user_ns);
+-              net_free(net);
++              net_passive_dec(net);
+ dec_ucounts:
+               dec_net_namespaces(ucounts);
+               return ERR_PTR(rv);
+@@ -668,7 +668,7 @@ static void cleanup_net(struct work_struct *work)
+               key_remove_domain(net->key_domain);
+ #endif
+               put_user_ns(net->user_ns);
+-              net_free(net);
++              net_passive_dec(net);
+       }
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.13/net-better-track-kernel-sockets-lifetime.patch b/queue-6.13/net-better-track-kernel-sockets-lifetime.patch
new file mode 100644 (file)
index 0000000..79c84af
--- /dev/null
@@ -0,0 +1,257 @@
+From 76fb3658ac3a5a75d7ed592418772e1caf98f736 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Feb 2025 13:18:54 +0000
+Subject: net: better track kernel sockets lifetime
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 5c70eb5c593d64d93b178905da215a9fd288a4b5 ]
+
+While kernel sockets are dismantled during pernet_operations->exit(),
+their freeing can be delayed by any tx packets still held in qdisc
+or device queues, due to skb_set_owner_w() prior calls.
+
+This then trigger the following warning from ref_tracker_dir_exit() [1]
+
+To fix this, make sure that kernel sockets own a reference on net->passive.
+
+Add sk_net_refcnt_upgrade() helper, used whenever a kernel socket
+is converted to a refcounted one.
+
+[1]
+
+[  136.263918][   T35] ref_tracker: net notrefcnt@ffff8880638f01e0 has 1/2 users at
+[  136.263918][   T35]      sk_alloc+0x2b3/0x370
+[  136.263918][   T35]      inet6_create+0x6ce/0x10f0
+[  136.263918][   T35]      __sock_create+0x4c0/0xa30
+[  136.263918][   T35]      inet_ctl_sock_create+0xc2/0x250
+[  136.263918][   T35]      igmp6_net_init+0x39/0x390
+[  136.263918][   T35]      ops_init+0x31e/0x590
+[  136.263918][   T35]      setup_net+0x287/0x9e0
+[  136.263918][   T35]      copy_net_ns+0x33f/0x570
+[  136.263918][   T35]      create_new_namespaces+0x425/0x7b0
+[  136.263918][   T35]      unshare_nsproxy_namespaces+0x124/0x180
+[  136.263918][   T35]      ksys_unshare+0x57d/0xa70
+[  136.263918][   T35]      __x64_sys_unshare+0x38/0x40
+[  136.263918][   T35]      do_syscall_64+0xf3/0x230
+[  136.263918][   T35]      entry_SYSCALL_64_after_hwframe+0x77/0x7f
+[  136.263918][   T35]
+[  136.343488][   T35] ref_tracker: net notrefcnt@ffff8880638f01e0 has 1/2 users at
+[  136.343488][   T35]      sk_alloc+0x2b3/0x370
+[  136.343488][   T35]      inet6_create+0x6ce/0x10f0
+[  136.343488][   T35]      __sock_create+0x4c0/0xa30
+[  136.343488][   T35]      inet_ctl_sock_create+0xc2/0x250
+[  136.343488][   T35]      ndisc_net_init+0xa7/0x2b0
+[  136.343488][   T35]      ops_init+0x31e/0x590
+[  136.343488][   T35]      setup_net+0x287/0x9e0
+[  136.343488][   T35]      copy_net_ns+0x33f/0x570
+[  136.343488][   T35]      create_new_namespaces+0x425/0x7b0
+[  136.343488][   T35]      unshare_nsproxy_namespaces+0x124/0x180
+[  136.343488][   T35]      ksys_unshare+0x57d/0xa70
+[  136.343488][   T35]      __x64_sys_unshare+0x38/0x40
+[  136.343488][   T35]      do_syscall_64+0xf3/0x230
+[  136.343488][   T35]      entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fixes: 0cafd77dcd03 ("net: add a refcount tracker for kernel sockets")
+Reported-by: syzbot+30a19e01a97420719891@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/67b72aeb.050a0220.14d86d.0283.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20250220131854.4048077-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sock.h       |  1 +
+ net/core/sock.c          | 27 ++++++++++++++++++++++-----
+ net/mptcp/subflow.c      |  5 +----
+ net/netlink/af_netlink.c | 10 ----------
+ net/rds/tcp.c            |  8 ++------
+ net/smc/af_smc.c         |  5 +----
+ net/sunrpc/svcsock.c     |  5 +----
+ net/sunrpc/xprtsock.c    |  8 ++------
+ 8 files changed, 30 insertions(+), 39 deletions(-)
+
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 691ca7695d1db..d3efb581c2ff4 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1750,6 +1750,7 @@ static inline bool sock_allow_reclassification(const struct sock *csk)
+ struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
+                     struct proto *prot, int kern);
+ void sk_free(struct sock *sk);
++void sk_net_refcnt_upgrade(struct sock *sk);
+ void sk_destruct(struct sock *sk);
+ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority);
+ void sk_free_unlock_clone(struct sock *sk);
+diff --git a/net/core/sock.c b/net/core/sock.c
+index be84885f9290a..9d5dd99cc5817 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -2233,6 +2233,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
+                       get_net_track(net, &sk->ns_tracker, priority);
+                       sock_inuse_add(net, 1);
+               } else {
++                      net_passive_inc(net);
+                       __netns_tracker_alloc(net, &sk->ns_tracker,
+                                             false, priority);
+               }
+@@ -2257,6 +2258,7 @@ EXPORT_SYMBOL(sk_alloc);
+ static void __sk_destruct(struct rcu_head *head)
+ {
+       struct sock *sk = container_of(head, struct sock, sk_rcu);
++      struct net *net = sock_net(sk);
+       struct sk_filter *filter;
+       if (sk->sk_destruct)
+@@ -2288,14 +2290,28 @@ static void __sk_destruct(struct rcu_head *head)
+       put_cred(sk->sk_peer_cred);
+       put_pid(sk->sk_peer_pid);
+-      if (likely(sk->sk_net_refcnt))
+-              put_net_track(sock_net(sk), &sk->ns_tracker);
+-      else
+-              __netns_tracker_free(sock_net(sk), &sk->ns_tracker, false);
+-
++      if (likely(sk->sk_net_refcnt)) {
++              put_net_track(net, &sk->ns_tracker);
++      } else {
++              __netns_tracker_free(net, &sk->ns_tracker, false);
++              net_passive_dec(net);
++      }
+       sk_prot_free(sk->sk_prot_creator, sk);
+ }
++void sk_net_refcnt_upgrade(struct sock *sk)
++{
++      struct net *net = sock_net(sk);
++
++      WARN_ON_ONCE(sk->sk_net_refcnt);
++      __netns_tracker_free(net, &sk->ns_tracker, false);
++      net_passive_dec(net);
++      sk->sk_net_refcnt = 1;
++      get_net_track(net, &sk->ns_tracker, GFP_KERNEL);
++      sock_inuse_add(net, 1);
++}
++EXPORT_SYMBOL_GPL(sk_net_refcnt_upgrade);
++
+ void sk_destruct(struct sock *sk)
+ {
+       bool use_call_rcu = sock_flag(sk, SOCK_RCU_FREE);
+@@ -2392,6 +2408,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
+                * is not properly dismantling its kernel sockets at netns
+                * destroy time.
+                */
++              net_passive_inc(sock_net(newsk));
+               __netns_tracker_alloc(sock_net(newsk), &newsk->ns_tracker,
+                                     false, priority);
+       }
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index fd021cf8286ef..dfcbef9c46246 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -1772,10 +1772,7 @@ int mptcp_subflow_create_socket(struct sock *sk, unsigned short family,
+        * needs it.
+        * Update ns_tracker to current stack trace and refcounted tracker.
+        */
+-      __netns_tracker_free(net, &sf->sk->ns_tracker, false);
+-      sf->sk->sk_net_refcnt = 1;
+-      get_net_track(net, &sf->sk->ns_tracker, GFP_KERNEL);
+-      sock_inuse_add(net, 1);
++      sk_net_refcnt_upgrade(sf->sk);
+       err = tcp_set_ulp(sf->sk, "mptcp");
+       if (err)
+               goto err_free;
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index f4e7b5e4bb59f..e88a1ac160bc4 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -795,16 +795,6 @@ static int netlink_release(struct socket *sock)
+       sock_prot_inuse_add(sock_net(sk), &netlink_proto, -1);
+-      /* Because struct net might disappear soon, do not keep a pointer. */
+-      if (!sk->sk_net_refcnt && sock_net(sk) != &init_net) {
+-              __netns_tracker_free(sock_net(sk), &sk->ns_tracker, false);
+-              /* Because of deferred_put_nlk_sk and use of work queue,
+-               * it is possible  netns will be freed before this socket.
+-               */
+-              sock_net_set(sk, &init_net);
+-              __netns_tracker_alloc(&init_net, &sk->ns_tracker,
+-                                    false, GFP_KERNEL);
+-      }
+       call_rcu(&nlk->rcu, deferred_put_nlk_sk);
+       return 0;
+ }
+diff --git a/net/rds/tcp.c b/net/rds/tcp.c
+index 0581c53e65170..3cc2f303bf786 100644
+--- a/net/rds/tcp.c
++++ b/net/rds/tcp.c
+@@ -504,12 +504,8 @@ bool rds_tcp_tune(struct socket *sock)
+                       release_sock(sk);
+                       return false;
+               }
+-              /* Update ns_tracker to current stack trace and refcounted tracker */
+-              __netns_tracker_free(net, &sk->ns_tracker, false);
+-
+-              sk->sk_net_refcnt = 1;
+-              netns_tracker_alloc(net, &sk->ns_tracker, GFP_KERNEL);
+-              sock_inuse_add(net, 1);
++              sk_net_refcnt_upgrade(sk);
++              put_net(net);
+       }
+       rtn = net_generic(net, rds_tcp_netid);
+       if (rtn->sndbuf_size > 0) {
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
+index ebc41a7b13dbe..ba834cefb1773 100644
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -3334,10 +3334,7 @@ int smc_create_clcsk(struct net *net, struct sock *sk, int family)
+        * which need net ref.
+        */
+       sk = smc->clcsock->sk;
+-      __netns_tracker_free(net, &sk->ns_tracker, false);
+-      sk->sk_net_refcnt = 1;
+-      get_net_track(net, &sk->ns_tracker, GFP_KERNEL);
+-      sock_inuse_add(net, 1);
++      sk_net_refcnt_upgrade(sk);
+       return 0;
+ }
+diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
+index cb3bd12f5818b..72e5a01df3d35 100644
+--- a/net/sunrpc/svcsock.c
++++ b/net/sunrpc/svcsock.c
+@@ -1541,10 +1541,7 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv,
+       newlen = error;
+       if (protocol == IPPROTO_TCP) {
+-              __netns_tracker_free(net, &sock->sk->ns_tracker, false);
+-              sock->sk->sk_net_refcnt = 1;
+-              get_net_track(net, &sock->sk->ns_tracker, GFP_KERNEL);
+-              sock_inuse_add(net, 1);
++              sk_net_refcnt_upgrade(sock->sk);
+               if ((error = kernel_listen(sock, 64)) < 0)
+                       goto bummer;
+       }
+diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
+index 6b80b2aaf7639..83cc095846d35 100644
+--- a/net/sunrpc/xprtsock.c
++++ b/net/sunrpc/xprtsock.c
+@@ -1941,12 +1941,8 @@ static struct socket *xs_create_sock(struct rpc_xprt *xprt,
+               goto out;
+       }
+-      if (protocol == IPPROTO_TCP) {
+-              __netns_tracker_free(xprt->xprt_net, &sock->sk->ns_tracker, false);
+-              sock->sk->sk_net_refcnt = 1;
+-              get_net_track(xprt->xprt_net, &sock->sk->ns_tracker, GFP_KERNEL);
+-              sock_inuse_add(xprt->xprt_net, 1);
+-      }
++      if (protocol == IPPROTO_TCP)
++              sk_net_refcnt_upgrade(sock->sk);
+       filp = sock_alloc_file(sock, O_NONBLOCK, NULL);
+       if (IS_ERR(filp))
+-- 
+2.39.5
+
diff --git a/queue-6.13/net-cadence-macb-synchronize-stats-calculations.patch b/queue-6.13/net-cadence-macb-synchronize-stats-calculations.patch
new file mode 100644 (file)
index 0000000..87aecba
--- /dev/null
@@ -0,0 +1,115 @@
+From 11ad7012c85b7e870a6183cdb17b0f7d5911f5f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Feb 2025 11:29:50 -0500
+Subject: net: cadence: macb: Synchronize stats calculations
+
+From: Sean Anderson <sean.anderson@linux.dev>
+
+[ Upstream commit fa52f15c745ce55261b92873676f64f7348cfe82 ]
+
+Stats calculations involve a RMW to add the stat update to the existing
+value. This is currently not protected by any synchronization mechanism,
+so data races are possible. Add a spinlock to protect the update. The
+reader side could be protected using u64_stats, but we would still need
+a spinlock for the update side anyway. And we always do an update
+immediately before reading the stats anyway.
+
+Fixes: 89e5785fc8a6 ("[PATCH] Atmel MACB ethernet driver")
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Link: https://patch.msgid.link/20250220162950.95941-1-sean.anderson@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/cadence/macb.h      |  2 ++
+ drivers/net/ethernet/cadence/macb_main.c | 12 ++++++++++--
+ 2 files changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
+index 5740c98d8c9f0..2847278d9cd48 100644
+--- a/drivers/net/ethernet/cadence/macb.h
++++ b/drivers/net/ethernet/cadence/macb.h
+@@ -1279,6 +1279,8 @@ struct macb {
+       struct clk              *rx_clk;
+       struct clk              *tsu_clk;
+       struct net_device       *dev;
++      /* Protects hw_stats and ethtool_stats */
++      spinlock_t              stats_lock;
+       union {
+               struct macb_stats       macb;
+               struct gem_stats        gem;
+diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
+index daa416fb1724e..af2debcaf7dcc 100644
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -1987,10 +1987,12 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
+               if (status & MACB_BIT(ISR_ROVR)) {
+                       /* We missed at least one packet */
++                      spin_lock(&bp->stats_lock);
+                       if (macb_is_gem(bp))
+                               bp->hw_stats.gem.rx_overruns++;
+                       else
+                               bp->hw_stats.macb.rx_overruns++;
++                      spin_unlock(&bp->stats_lock);
+                       if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+                               queue_writel(queue, ISR, MACB_BIT(ISR_ROVR));
+@@ -3111,6 +3113,7 @@ static struct net_device_stats *gem_get_stats(struct macb *bp)
+       if (!netif_running(bp->dev))
+               return nstat;
++      spin_lock_irq(&bp->stats_lock);
+       gem_update_stats(bp);
+       nstat->rx_errors = (hwstat->rx_frame_check_sequence_errors +
+@@ -3140,6 +3143,7 @@ static struct net_device_stats *gem_get_stats(struct macb *bp)
+       nstat->tx_aborted_errors = hwstat->tx_excessive_collisions;
+       nstat->tx_carrier_errors = hwstat->tx_carrier_sense_errors;
+       nstat->tx_fifo_errors = hwstat->tx_underrun;
++      spin_unlock_irq(&bp->stats_lock);
+       return nstat;
+ }
+@@ -3147,12 +3151,13 @@ static struct net_device_stats *gem_get_stats(struct macb *bp)
+ static void gem_get_ethtool_stats(struct net_device *dev,
+                                 struct ethtool_stats *stats, u64 *data)
+ {
+-      struct macb *bp;
++      struct macb *bp = netdev_priv(dev);
+-      bp = netdev_priv(dev);
++      spin_lock_irq(&bp->stats_lock);
+       gem_update_stats(bp);
+       memcpy(data, &bp->ethtool_stats, sizeof(u64)
+                       * (GEM_STATS_LEN + QUEUE_STATS_LEN * MACB_MAX_QUEUES));
++      spin_unlock_irq(&bp->stats_lock);
+ }
+ static int gem_get_sset_count(struct net_device *dev, int sset)
+@@ -3202,6 +3207,7 @@ static struct net_device_stats *macb_get_stats(struct net_device *dev)
+               return gem_get_stats(bp);
+       /* read stats from hardware */
++      spin_lock_irq(&bp->stats_lock);
+       macb_update_stats(bp);
+       /* Convert HW stats into netdevice stats */
+@@ -3235,6 +3241,7 @@ static struct net_device_stats *macb_get_stats(struct net_device *dev)
+       nstat->tx_carrier_errors = hwstat->tx_carrier_errors;
+       nstat->tx_fifo_errors = hwstat->tx_underruns;
+       /* Don't know about heartbeat or window errors... */
++      spin_unlock_irq(&bp->stats_lock);
+       return nstat;
+ }
+@@ -5106,6 +5113,7 @@ static int macb_probe(struct platform_device *pdev)
+               }
+       }
+       spin_lock_init(&bp->lock);
++      spin_lock_init(&bp->stats_lock);
+       /* setup capabilities */
+       macb_configure_caps(bp, macb_config);
+-- 
+2.39.5
+
diff --git a/queue-6.13/net-clear-old-fragment-checksum-value-in-napi_reuse_.patch b/queue-6.13/net-clear-old-fragment-checksum-value-in-napi_reuse_.patch
new file mode 100644 (file)
index 0000000..2f34cc9
--- /dev/null
@@ -0,0 +1,77 @@
+From 9301842d370999abe766148aaa2d144b679a4dca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 13:28:52 +0200
+Subject: net: Clear old fragment checksum value in napi_reuse_skb
+
+From: Mohammad Heib <mheib@redhat.com>
+
+[ Upstream commit 49806fe6e61b045b5be8610e08b5a3083c109aa0 ]
+
+In certain cases, napi_get_frags() returns an skb that points to an old
+received fragment, This skb may have its skb->ip_summed, csum, and other
+fields set from previous fragment handling.
+
+Some network drivers set skb->ip_summed to either CHECKSUM_COMPLETE or
+CHECKSUM_UNNECESSARY when getting skb from napi_get_frags(), while
+others only set skb->ip_summed when RX checksum offload is enabled on
+the device, and do not set any value for skb->ip_summed when hardware
+checksum offload is disabled, assuming that the skb->ip_summed
+initiated to zero by napi_reuse_skb, ionic driver for example will
+ignore/unset any value for the ip_summed filed if HW checksum offload is
+disabled, and if we have a situation where the user disables the
+checksum offload during a traffic that could lead to the following
+errors shown in the kernel logs:
+<IRQ>
+dump_stack_lvl+0x34/0x48
+ __skb_gro_checksum_complete+0x7e/0x90
+tcp6_gro_receive+0xc6/0x190
+ipv6_gro_receive+0x1ec/0x430
+dev_gro_receive+0x188/0x360
+? ionic_rx_clean+0x25a/0x460 [ionic]
+napi_gro_frags+0x13c/0x300
+? __pfx_ionic_rx_service+0x10/0x10 [ionic]
+ionic_rx_service+0x67/0x80 [ionic]
+ionic_cq_service+0x58/0x90 [ionic]
+ionic_txrx_napi+0x64/0x1b0 [ionic]
+ __napi_poll+0x27/0x170
+net_rx_action+0x29c/0x370
+handle_softirqs+0xce/0x270
+__irq_exit_rcu+0xa3/0xc0
+common_interrupt+0x80/0xa0
+</IRQ>
+
+This inconsistency sometimes leads to checksum validation issues in the
+upper layers of the network stack.
+
+To resolve this, this patch clears the skb->ip_summed value for each
+reused skb in by napi_reuse_skb(), ensuring that the caller is responsible
+for setting the correct checksum status. This eliminates potential
+checksum validation issues caused by improper handling of
+skb->ip_summed.
+
+Fixes: 76620aafd66f ("gro: New frags interface to avoid copying shinfo")
+Signed-off-by: Mohammad Heib <mheib@redhat.com>
+Reviewed-by: Shannon Nelson <shannon.nelson@amd.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20250225112852.2507709-1-mheib@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/gro.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/core/gro.c b/net/core/gro.c
+index 78b320b631744..0ad549b07e039 100644
+--- a/net/core/gro.c
++++ b/net/core/gro.c
+@@ -653,6 +653,7 @@ static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb)
+       skb->pkt_type = PACKET_HOST;
+       skb->encapsulation = 0;
++      skb->ip_summed = CHECKSUM_NONE;
+       skb_shinfo(skb)->gso_type = 0;
+       skb_shinfo(skb)->gso_size = 0;
+       if (unlikely(skb->slow_gro)) {
+-- 
+2.39.5
+
diff --git a/queue-6.13/net-dsa-rtl8366rb-fix-compilation-problem.patch b/queue-6.13/net-dsa-rtl8366rb-fix-compilation-problem.patch
new file mode 100644 (file)
index 0000000..3135019
--- /dev/null
@@ -0,0 +1,684 @@
+From 15e3121b65d26934a530e85020b2851edd2fa1de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Feb 2025 19:48:15 +0100
+Subject: net: dsa: rtl8366rb: Fix compilation problem
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit f15176b8b6e72ac30e14fd273282d2b72562d26b ]
+
+When the kernel is compiled without LED framework support the
+rtl8366rb fails to build like this:
+
+rtl8366rb.o: in function `rtl8366rb_setup_led':
+rtl8366rb.c:953:(.text.unlikely.rtl8366rb_setup_led+0xe8):
+  undefined reference to `led_init_default_state_get'
+rtl8366rb.c:980:(.text.unlikely.rtl8366rb_setup_led+0x240):
+  undefined reference to `devm_led_classdev_register_ext'
+
+As this is constantly coming up in different randconfig builds,
+bite the bullet and create a separate file for the offending
+code, split out a header with all stuff needed both in the
+core driver and the leds code.
+
+Add a new bool Kconfig option for the LED compile target, such
+that it depends on LEDS_CLASS=y || LEDS_CLASS=RTL8366RB
+which make LED support always available when LEDS_CLASS is
+compiled into the kernel and enforce that if the LEDS_CLASS
+is a module, then the RTL8366RB driver needs to be a module
+as well so that modprobe can resolve the dependencies.
+
+Fixes: 32d617005475 ("net: dsa: realtek: add LED drivers for rtl8366rb")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202502070525.xMUImayb-lkp@intel.com/
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/realtek/Kconfig          |   6 +
+ drivers/net/dsa/realtek/Makefile         |   3 +
+ drivers/net/dsa/realtek/rtl8366rb-leds.c | 177 ++++++++++++++++
+ drivers/net/dsa/realtek/rtl8366rb.c      | 258 +----------------------
+ drivers/net/dsa/realtek/rtl8366rb.h      | 107 ++++++++++
+ 5 files changed, 299 insertions(+), 252 deletions(-)
+ create mode 100644 drivers/net/dsa/realtek/rtl8366rb-leds.c
+ create mode 100644 drivers/net/dsa/realtek/rtl8366rb.h
+
+diff --git a/drivers/net/dsa/realtek/Kconfig b/drivers/net/dsa/realtek/Kconfig
+index 6989972eebc30..10687722d14c0 100644
+--- a/drivers/net/dsa/realtek/Kconfig
++++ b/drivers/net/dsa/realtek/Kconfig
+@@ -43,4 +43,10 @@ config NET_DSA_REALTEK_RTL8366RB
+       help
+         Select to enable support for Realtek RTL8366RB.
++config NET_DSA_REALTEK_RTL8366RB_LEDS
++      bool "Support RTL8366RB LED control"
++      depends on (LEDS_CLASS=y || LEDS_CLASS=NET_DSA_REALTEK_RTL8366RB)
++      depends on NET_DSA_REALTEK_RTL8366RB
++      default NET_DSA_REALTEK_RTL8366RB
++
+ endif
+diff --git a/drivers/net/dsa/realtek/Makefile b/drivers/net/dsa/realtek/Makefile
+index 35491dc20d6d6..17367bcba496c 100644
+--- a/drivers/net/dsa/realtek/Makefile
++++ b/drivers/net/dsa/realtek/Makefile
+@@ -12,4 +12,7 @@ endif
+ obj-$(CONFIG_NET_DSA_REALTEK_RTL8366RB) += rtl8366.o
+ rtl8366-objs                          := rtl8366-core.o rtl8366rb.o
++ifdef CONFIG_NET_DSA_REALTEK_RTL8366RB_LEDS
++rtl8366-objs                          += rtl8366rb-leds.o
++endif
+ obj-$(CONFIG_NET_DSA_REALTEK_RTL8365MB) += rtl8365mb.o
+diff --git a/drivers/net/dsa/realtek/rtl8366rb-leds.c b/drivers/net/dsa/realtek/rtl8366rb-leds.c
+new file mode 100644
+index 0000000000000..99c890681ae60
+--- /dev/null
++++ b/drivers/net/dsa/realtek/rtl8366rb-leds.c
+@@ -0,0 +1,177 @@
++// SPDX-License-Identifier: GPL-2.0
++
++#include <linux/bitops.h>
++#include <linux/regmap.h>
++#include <net/dsa.h>
++#include "rtl83xx.h"
++#include "rtl8366rb.h"
++
++static inline u32 rtl8366rb_led_group_port_mask(u8 led_group, u8 port)
++{
++      switch (led_group) {
++      case 0:
++              return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port));
++      case 1:
++              return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port));
++      case 2:
++              return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port));
++      case 3:
++              return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port));
++      default:
++              return 0;
++      }
++}
++
++static int rb8366rb_get_port_led(struct rtl8366rb_led *led)
++{
++      struct realtek_priv *priv = led->priv;
++      u8 led_group = led->led_group;
++      u8 port_num = led->port_num;
++      int ret;
++      u32 val;
++
++      ret = regmap_read(priv->map, RTL8366RB_LED_X_X_CTRL_REG(led_group),
++                        &val);
++      if (ret) {
++              dev_err(priv->dev, "error reading LED on port %d group %d\n",
++                      led_group, port_num);
++              return ret;
++      }
++
++      return !!(val & rtl8366rb_led_group_port_mask(led_group, port_num));
++}
++
++static int rb8366rb_set_port_led(struct rtl8366rb_led *led, bool enable)
++{
++      struct realtek_priv *priv = led->priv;
++      u8 led_group = led->led_group;
++      u8 port_num = led->port_num;
++      int ret;
++
++      ret = regmap_update_bits(priv->map,
++                               RTL8366RB_LED_X_X_CTRL_REG(led_group),
++                               rtl8366rb_led_group_port_mask(led_group,
++                                                             port_num),
++                               enable ? 0xffff : 0);
++      if (ret) {
++              dev_err(priv->dev, "error updating LED on port %d group %d\n",
++                      led_group, port_num);
++              return ret;
++      }
++
++      /* Change the LED group to manual controlled LEDs if required */
++      ret = rb8366rb_set_ledgroup_mode(priv, led_group,
++                                       RTL8366RB_LEDGROUP_FORCE);
++
++      if (ret) {
++              dev_err(priv->dev, "error updating LED GROUP group %d\n",
++                      led_group);
++              return ret;
++      }
++
++      return 0;
++}
++
++static int
++rtl8366rb_cled_brightness_set_blocking(struct led_classdev *ldev,
++                                     enum led_brightness brightness)
++{
++      struct rtl8366rb_led *led = container_of(ldev, struct rtl8366rb_led,
++                                               cdev);
++
++      return rb8366rb_set_port_led(led, brightness == LED_ON);
++}
++
++static int rtl8366rb_setup_led(struct realtek_priv *priv, struct dsa_port *dp,
++                             struct fwnode_handle *led_fwnode)
++{
++      struct rtl8366rb *rb = priv->chip_data;
++      struct led_init_data init_data = { };
++      enum led_default_state state;
++      struct rtl8366rb_led *led;
++      u32 led_group;
++      int ret;
++
++      ret = fwnode_property_read_u32(led_fwnode, "reg", &led_group);
++      if (ret)
++              return ret;
++
++      if (led_group >= RTL8366RB_NUM_LEDGROUPS) {
++              dev_warn(priv->dev, "Invalid LED reg %d defined for port %d",
++                       led_group, dp->index);
++              return -EINVAL;
++      }
++
++      led = &rb->leds[dp->index][led_group];
++      led->port_num = dp->index;
++      led->led_group = led_group;
++      led->priv = priv;
++
++      state = led_init_default_state_get(led_fwnode);
++      switch (state) {
++      case LEDS_DEFSTATE_ON:
++              led->cdev.brightness = 1;
++              rb8366rb_set_port_led(led, 1);
++              break;
++      case LEDS_DEFSTATE_KEEP:
++              led->cdev.brightness =
++                      rb8366rb_get_port_led(led);
++              break;
++      case LEDS_DEFSTATE_OFF:
++      default:
++              led->cdev.brightness = 0;
++              rb8366rb_set_port_led(led, 0);
++      }
++
++      led->cdev.max_brightness = 1;
++      led->cdev.brightness_set_blocking =
++              rtl8366rb_cled_brightness_set_blocking;
++      init_data.fwnode = led_fwnode;
++      init_data.devname_mandatory = true;
++
++      init_data.devicename = kasprintf(GFP_KERNEL, "Realtek-%d:0%d:%d",
++                                       dp->ds->index, dp->index, led_group);
++      if (!init_data.devicename)
++              return -ENOMEM;
++
++      ret = devm_led_classdev_register_ext(priv->dev, &led->cdev, &init_data);
++      if (ret) {
++              dev_warn(priv->dev, "Failed to init LED %d for port %d",
++                       led_group, dp->index);
++              return ret;
++      }
++
++      return 0;
++}
++
++int rtl8366rb_setup_leds(struct realtek_priv *priv)
++{
++      struct dsa_switch *ds = &priv->ds;
++      struct device_node *leds_np;
++      struct dsa_port *dp;
++      int ret = 0;
++
++      dsa_switch_for_each_port(dp, ds) {
++              if (!dp->dn)
++                      continue;
++
++              leds_np = of_get_child_by_name(dp->dn, "leds");
++              if (!leds_np) {
++                      dev_dbg(priv->dev, "No leds defined for port %d",
++                              dp->index);
++                      continue;
++              }
++
++              for_each_child_of_node_scoped(leds_np, led_np) {
++                      ret = rtl8366rb_setup_led(priv, dp,
++                                                of_fwnode_handle(led_np));
++                      if (ret)
++                              break;
++              }
++
++              of_node_put(leds_np);
++              if (ret)
++                      return ret;
++      }
++      return 0;
++}
+diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c
+index 23374178a1760..6bf8427f14fbd 100644
+--- a/drivers/net/dsa/realtek/rtl8366rb.c
++++ b/drivers/net/dsa/realtek/rtl8366rb.c
+@@ -26,11 +26,7 @@
+ #include "realtek-smi.h"
+ #include "realtek-mdio.h"
+ #include "rtl83xx.h"
+-
+-#define RTL8366RB_PORT_NUM_CPU                5
+-#define RTL8366RB_NUM_PORTS           6
+-#define RTL8366RB_PHY_NO_MAX          4
+-#define RTL8366RB_PHY_ADDR_MAX                31
++#include "rtl8366rb.h"
+ /* Switch Global Configuration register */
+ #define RTL8366RB_SGCR                                0x0000
+@@ -175,39 +171,6 @@
+  */
+ #define RTL8366RB_VLAN_INGRESS_CTRL2_REG      0x037f
+-/* LED control registers */
+-/* The LED blink rate is global; it is used by all triggers in all groups. */
+-#define RTL8366RB_LED_BLINKRATE_REG           0x0430
+-#define RTL8366RB_LED_BLINKRATE_MASK          0x0007
+-#define RTL8366RB_LED_BLINKRATE_28MS          0x0000
+-#define RTL8366RB_LED_BLINKRATE_56MS          0x0001
+-#define RTL8366RB_LED_BLINKRATE_84MS          0x0002
+-#define RTL8366RB_LED_BLINKRATE_111MS         0x0003
+-#define RTL8366RB_LED_BLINKRATE_222MS         0x0004
+-#define RTL8366RB_LED_BLINKRATE_446MS         0x0005
+-
+-/* LED trigger event for each group */
+-#define RTL8366RB_LED_CTRL_REG                        0x0431
+-#define RTL8366RB_LED_CTRL_OFFSET(led_group)  \
+-      (4 * (led_group))
+-#define RTL8366RB_LED_CTRL_MASK(led_group)    \
+-      (0xf << RTL8366RB_LED_CTRL_OFFSET(led_group))
+-
+-/* The RTL8366RB_LED_X_X registers are used to manually set the LED state only
+- * when the corresponding LED group in RTL8366RB_LED_CTRL_REG is
+- * RTL8366RB_LEDGROUP_FORCE. Otherwise, it is ignored.
+- */
+-#define RTL8366RB_LED_0_1_CTRL_REG            0x0432
+-#define RTL8366RB_LED_2_3_CTRL_REG            0x0433
+-#define RTL8366RB_LED_X_X_CTRL_REG(led_group) \
+-      ((led_group) <= 1 ? \
+-              RTL8366RB_LED_0_1_CTRL_REG : \
+-              RTL8366RB_LED_2_3_CTRL_REG)
+-#define RTL8366RB_LED_0_X_CTRL_MASK           GENMASK(5, 0)
+-#define RTL8366RB_LED_X_1_CTRL_MASK           GENMASK(11, 6)
+-#define RTL8366RB_LED_2_X_CTRL_MASK           GENMASK(5, 0)
+-#define RTL8366RB_LED_X_3_CTRL_MASK           GENMASK(11, 6)
+-
+ #define RTL8366RB_MIB_COUNT                   33
+ #define RTL8366RB_GLOBAL_MIB_COUNT            1
+ #define RTL8366RB_MIB_COUNTER_PORT_OFFSET     0x0050
+@@ -243,7 +206,6 @@
+ #define RTL8366RB_PORT_STATUS_AN_MASK         0x0080
+ #define RTL8366RB_NUM_VLANS           16
+-#define RTL8366RB_NUM_LEDGROUPS               4
+ #define RTL8366RB_NUM_VIDS            4096
+ #define RTL8366RB_PRIORITYMAX         7
+ #define RTL8366RB_NUM_FIDS            8
+@@ -350,46 +312,6 @@
+ #define RTL8366RB_GREEN_FEATURE_TX    BIT(0)
+ #define RTL8366RB_GREEN_FEATURE_RX    BIT(2)
+-enum rtl8366_ledgroup_mode {
+-      RTL8366RB_LEDGROUP_OFF                  = 0x0,
+-      RTL8366RB_LEDGROUP_DUP_COL              = 0x1,
+-      RTL8366RB_LEDGROUP_LINK_ACT             = 0x2,
+-      RTL8366RB_LEDGROUP_SPD1000              = 0x3,
+-      RTL8366RB_LEDGROUP_SPD100               = 0x4,
+-      RTL8366RB_LEDGROUP_SPD10                = 0x5,
+-      RTL8366RB_LEDGROUP_SPD1000_ACT          = 0x6,
+-      RTL8366RB_LEDGROUP_SPD100_ACT           = 0x7,
+-      RTL8366RB_LEDGROUP_SPD10_ACT            = 0x8,
+-      RTL8366RB_LEDGROUP_SPD100_10_ACT        = 0x9,
+-      RTL8366RB_LEDGROUP_FIBER                = 0xa,
+-      RTL8366RB_LEDGROUP_AN_FAULT             = 0xb,
+-      RTL8366RB_LEDGROUP_LINK_RX              = 0xc,
+-      RTL8366RB_LEDGROUP_LINK_TX              = 0xd,
+-      RTL8366RB_LEDGROUP_MASTER               = 0xe,
+-      RTL8366RB_LEDGROUP_FORCE                = 0xf,
+-
+-      __RTL8366RB_LEDGROUP_MODE_MAX
+-};
+-
+-struct rtl8366rb_led {
+-      u8 port_num;
+-      u8 led_group;
+-      struct realtek_priv *priv;
+-      struct led_classdev cdev;
+-};
+-
+-/**
+- * struct rtl8366rb - RTL8366RB-specific data
+- * @max_mtu: per-port max MTU setting
+- * @pvid_enabled: if PVID is set for respective port
+- * @leds: per-port and per-ledgroup led info
+- */
+-struct rtl8366rb {
+-      unsigned int max_mtu[RTL8366RB_NUM_PORTS];
+-      bool pvid_enabled[RTL8366RB_NUM_PORTS];
+-      struct rtl8366rb_led leds[RTL8366RB_NUM_PORTS][RTL8366RB_NUM_LEDGROUPS];
+-};
+-
+ static struct rtl8366_mib_counter rtl8366rb_mib_counters[] = {
+       { 0,  0, 4, "IfInOctets"                                },
+       { 0,  4, 4, "EtherStatsOctets"                          },
+@@ -830,9 +752,10 @@ static int rtl8366rb_jam_table(const struct rtl8366rb_jam_tbl_entry *jam_table,
+       return 0;
+ }
+-static int rb8366rb_set_ledgroup_mode(struct realtek_priv *priv,
+-                                    u8 led_group,
+-                                    enum rtl8366_ledgroup_mode mode)
++/* This code is used also with LEDs disabled */
++int rb8366rb_set_ledgroup_mode(struct realtek_priv *priv,
++                             u8 led_group,
++                             enum rtl8366_ledgroup_mode mode)
+ {
+       int ret;
+       u32 val;
+@@ -849,144 +772,7 @@ static int rb8366rb_set_ledgroup_mode(struct realtek_priv *priv,
+       return 0;
+ }
+-static inline u32 rtl8366rb_led_group_port_mask(u8 led_group, u8 port)
+-{
+-      switch (led_group) {
+-      case 0:
+-              return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port));
+-      case 1:
+-              return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port));
+-      case 2:
+-              return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port));
+-      case 3:
+-              return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port));
+-      default:
+-              return 0;
+-      }
+-}
+-
+-static int rb8366rb_get_port_led(struct rtl8366rb_led *led)
+-{
+-      struct realtek_priv *priv = led->priv;
+-      u8 led_group = led->led_group;
+-      u8 port_num = led->port_num;
+-      int ret;
+-      u32 val;
+-
+-      ret = regmap_read(priv->map, RTL8366RB_LED_X_X_CTRL_REG(led_group),
+-                        &val);
+-      if (ret) {
+-              dev_err(priv->dev, "error reading LED on port %d group %d\n",
+-                      led_group, port_num);
+-              return ret;
+-      }
+-
+-      return !!(val & rtl8366rb_led_group_port_mask(led_group, port_num));
+-}
+-
+-static int rb8366rb_set_port_led(struct rtl8366rb_led *led, bool enable)
+-{
+-      struct realtek_priv *priv = led->priv;
+-      u8 led_group = led->led_group;
+-      u8 port_num = led->port_num;
+-      int ret;
+-
+-      ret = regmap_update_bits(priv->map,
+-                               RTL8366RB_LED_X_X_CTRL_REG(led_group),
+-                               rtl8366rb_led_group_port_mask(led_group,
+-                                                             port_num),
+-                               enable ? 0xffff : 0);
+-      if (ret) {
+-              dev_err(priv->dev, "error updating LED on port %d group %d\n",
+-                      led_group, port_num);
+-              return ret;
+-      }
+-
+-      /* Change the LED group to manual controlled LEDs if required */
+-      ret = rb8366rb_set_ledgroup_mode(priv, led_group,
+-                                       RTL8366RB_LEDGROUP_FORCE);
+-
+-      if (ret) {
+-              dev_err(priv->dev, "error updating LED GROUP group %d\n",
+-                      led_group);
+-              return ret;
+-      }
+-
+-      return 0;
+-}
+-
+-static int
+-rtl8366rb_cled_brightness_set_blocking(struct led_classdev *ldev,
+-                                     enum led_brightness brightness)
+-{
+-      struct rtl8366rb_led *led = container_of(ldev, struct rtl8366rb_led,
+-                                               cdev);
+-
+-      return rb8366rb_set_port_led(led, brightness == LED_ON);
+-}
+-
+-static int rtl8366rb_setup_led(struct realtek_priv *priv, struct dsa_port *dp,
+-                             struct fwnode_handle *led_fwnode)
+-{
+-      struct rtl8366rb *rb = priv->chip_data;
+-      struct led_init_data init_data = { };
+-      enum led_default_state state;
+-      struct rtl8366rb_led *led;
+-      u32 led_group;
+-      int ret;
+-
+-      ret = fwnode_property_read_u32(led_fwnode, "reg", &led_group);
+-      if (ret)
+-              return ret;
+-
+-      if (led_group >= RTL8366RB_NUM_LEDGROUPS) {
+-              dev_warn(priv->dev, "Invalid LED reg %d defined for port %d",
+-                       led_group, dp->index);
+-              return -EINVAL;
+-      }
+-
+-      led = &rb->leds[dp->index][led_group];
+-      led->port_num = dp->index;
+-      led->led_group = led_group;
+-      led->priv = priv;
+-
+-      state = led_init_default_state_get(led_fwnode);
+-      switch (state) {
+-      case LEDS_DEFSTATE_ON:
+-              led->cdev.brightness = 1;
+-              rb8366rb_set_port_led(led, 1);
+-              break;
+-      case LEDS_DEFSTATE_KEEP:
+-              led->cdev.brightness =
+-                      rb8366rb_get_port_led(led);
+-              break;
+-      case LEDS_DEFSTATE_OFF:
+-      default:
+-              led->cdev.brightness = 0;
+-              rb8366rb_set_port_led(led, 0);
+-      }
+-
+-      led->cdev.max_brightness = 1;
+-      led->cdev.brightness_set_blocking =
+-              rtl8366rb_cled_brightness_set_blocking;
+-      init_data.fwnode = led_fwnode;
+-      init_data.devname_mandatory = true;
+-
+-      init_data.devicename = kasprintf(GFP_KERNEL, "Realtek-%d:0%d:%d",
+-                                       dp->ds->index, dp->index, led_group);
+-      if (!init_data.devicename)
+-              return -ENOMEM;
+-
+-      ret = devm_led_classdev_register_ext(priv->dev, &led->cdev, &init_data);
+-      if (ret) {
+-              dev_warn(priv->dev, "Failed to init LED %d for port %d",
+-                       led_group, dp->index);
+-              return ret;
+-      }
+-
+-      return 0;
+-}
+-
++/* This code is used also with LEDs disabled */
+ static int rtl8366rb_setup_all_leds_off(struct realtek_priv *priv)
+ {
+       int ret = 0;
+@@ -1007,38 +793,6 @@ static int rtl8366rb_setup_all_leds_off(struct realtek_priv *priv)
+       return ret;
+ }
+-static int rtl8366rb_setup_leds(struct realtek_priv *priv)
+-{
+-      struct dsa_switch *ds = &priv->ds;
+-      struct device_node *leds_np;
+-      struct dsa_port *dp;
+-      int ret = 0;
+-
+-      dsa_switch_for_each_port(dp, ds) {
+-              if (!dp->dn)
+-                      continue;
+-
+-              leds_np = of_get_child_by_name(dp->dn, "leds");
+-              if (!leds_np) {
+-                      dev_dbg(priv->dev, "No leds defined for port %d",
+-                              dp->index);
+-                      continue;
+-              }
+-
+-              for_each_child_of_node_scoped(leds_np, led_np) {
+-                      ret = rtl8366rb_setup_led(priv, dp,
+-                                                of_fwnode_handle(led_np));
+-                      if (ret)
+-                              break;
+-              }
+-
+-              of_node_put(leds_np);
+-              if (ret)
+-                      return ret;
+-      }
+-      return 0;
+-}
+-
+ static int rtl8366rb_setup(struct dsa_switch *ds)
+ {
+       struct realtek_priv *priv = ds->priv;
+diff --git a/drivers/net/dsa/realtek/rtl8366rb.h b/drivers/net/dsa/realtek/rtl8366rb.h
+new file mode 100644
+index 0000000000000..685ff3275faa1
+--- /dev/null
++++ b/drivers/net/dsa/realtek/rtl8366rb.h
+@@ -0,0 +1,107 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
++
++#ifndef _RTL8366RB_H
++#define _RTL8366RB_H
++
++#include "realtek.h"
++
++#define RTL8366RB_PORT_NUM_CPU                5
++#define RTL8366RB_NUM_PORTS           6
++#define RTL8366RB_PHY_NO_MAX          4
++#define RTL8366RB_NUM_LEDGROUPS               4
++#define RTL8366RB_PHY_ADDR_MAX                31
++
++/* LED control registers */
++/* The LED blink rate is global; it is used by all triggers in all groups. */
++#define RTL8366RB_LED_BLINKRATE_REG           0x0430
++#define RTL8366RB_LED_BLINKRATE_MASK          0x0007
++#define RTL8366RB_LED_BLINKRATE_28MS          0x0000
++#define RTL8366RB_LED_BLINKRATE_56MS          0x0001
++#define RTL8366RB_LED_BLINKRATE_84MS          0x0002
++#define RTL8366RB_LED_BLINKRATE_111MS         0x0003
++#define RTL8366RB_LED_BLINKRATE_222MS         0x0004
++#define RTL8366RB_LED_BLINKRATE_446MS         0x0005
++
++/* LED trigger event for each group */
++#define RTL8366RB_LED_CTRL_REG                        0x0431
++#define RTL8366RB_LED_CTRL_OFFSET(led_group)  \
++      (4 * (led_group))
++#define RTL8366RB_LED_CTRL_MASK(led_group)    \
++      (0xf << RTL8366RB_LED_CTRL_OFFSET(led_group))
++
++/* The RTL8366RB_LED_X_X registers are used to manually set the LED state only
++ * when the corresponding LED group in RTL8366RB_LED_CTRL_REG is
++ * RTL8366RB_LEDGROUP_FORCE. Otherwise, it is ignored.
++ */
++#define RTL8366RB_LED_0_1_CTRL_REG            0x0432
++#define RTL8366RB_LED_2_3_CTRL_REG            0x0433
++#define RTL8366RB_LED_X_X_CTRL_REG(led_group) \
++      ((led_group) <= 1 ? \
++              RTL8366RB_LED_0_1_CTRL_REG : \
++              RTL8366RB_LED_2_3_CTRL_REG)
++#define RTL8366RB_LED_0_X_CTRL_MASK           GENMASK(5, 0)
++#define RTL8366RB_LED_X_1_CTRL_MASK           GENMASK(11, 6)
++#define RTL8366RB_LED_2_X_CTRL_MASK           GENMASK(5, 0)
++#define RTL8366RB_LED_X_3_CTRL_MASK           GENMASK(11, 6)
++
++enum rtl8366_ledgroup_mode {
++      RTL8366RB_LEDGROUP_OFF                  = 0x0,
++      RTL8366RB_LEDGROUP_DUP_COL              = 0x1,
++      RTL8366RB_LEDGROUP_LINK_ACT             = 0x2,
++      RTL8366RB_LEDGROUP_SPD1000              = 0x3,
++      RTL8366RB_LEDGROUP_SPD100               = 0x4,
++      RTL8366RB_LEDGROUP_SPD10                = 0x5,
++      RTL8366RB_LEDGROUP_SPD1000_ACT          = 0x6,
++      RTL8366RB_LEDGROUP_SPD100_ACT           = 0x7,
++      RTL8366RB_LEDGROUP_SPD10_ACT            = 0x8,
++      RTL8366RB_LEDGROUP_SPD100_10_ACT        = 0x9,
++      RTL8366RB_LEDGROUP_FIBER                = 0xa,
++      RTL8366RB_LEDGROUP_AN_FAULT             = 0xb,
++      RTL8366RB_LEDGROUP_LINK_RX              = 0xc,
++      RTL8366RB_LEDGROUP_LINK_TX              = 0xd,
++      RTL8366RB_LEDGROUP_MASTER               = 0xe,
++      RTL8366RB_LEDGROUP_FORCE                = 0xf,
++
++      __RTL8366RB_LEDGROUP_MODE_MAX
++};
++
++#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8366RB_LEDS)
++
++struct rtl8366rb_led {
++      u8 port_num;
++      u8 led_group;
++      struct realtek_priv *priv;
++      struct led_classdev cdev;
++};
++
++int rtl8366rb_setup_leds(struct realtek_priv *priv);
++
++#else
++
++static inline int rtl8366rb_setup_leds(struct realtek_priv *priv)
++{
++      return 0;
++}
++
++#endif /* IS_ENABLED(CONFIG_LEDS_CLASS) */
++
++/**
++ * struct rtl8366rb - RTL8366RB-specific data
++ * @max_mtu: per-port max MTU setting
++ * @pvid_enabled: if PVID is set for respective port
++ * @leds: per-port and per-ledgroup led info
++ */
++struct rtl8366rb {
++      unsigned int max_mtu[RTL8366RB_NUM_PORTS];
++      bool pvid_enabled[RTL8366RB_NUM_PORTS];
++#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8366RB_LEDS)
++      struct rtl8366rb_led leds[RTL8366RB_NUM_PORTS][RTL8366RB_NUM_LEDGROUPS];
++#endif
++};
++
++/* This code is used also with LEDs disabled */
++int rb8366rb_set_ledgroup_mode(struct realtek_priv *priv,
++                             u8 led_group,
++                             enum rtl8366_ledgroup_mode mode);
++
++#endif /* _RTL8366RB_H */
+-- 
+2.39.5
+
diff --git a/queue-6.13/net-ethernet-ti-am65-cpsw-select-page_pool.patch b/queue-6.13/net-ethernet-ti-am65-cpsw-select-page_pool.patch
new file mode 100644 (file)
index 0000000..738b99f
--- /dev/null
@@ -0,0 +1,39 @@
+From b3f7ba8c4e36e67e6ab27051f370aa5a0de7dad0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 06:17:16 +0100
+Subject: net: ethernet: ti: am65-cpsw: select PAGE_POOL
+
+From: Sascha Hauer <s.hauer@pengutronix.de>
+
+[ Upstream commit bab3a6e9ffd600f9db0ebaf8f45e1c6111cf314c ]
+
+am65-cpsw uses page_pool_dev_alloc_pages(), thus needs PAGE_POOL
+selected to avoid linker errors. This is missing since the driver
+started to use page_pool helpers in 8acacc40f733 ("net: ethernet:
+ti: am65-cpsw: Add minimal XDP support")
+
+Fixes: 8acacc40f733 ("net: ethernet: ti: am65-cpsw: Add minimal XDP support")
+Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Link: https://patch.msgid.link/20250224-net-am654-nuss-kconfig-v2-1-c124f4915c92@pengutronix.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
+index 0d5a862cd78a6..3a13d60a947a8 100644
+--- a/drivers/net/ethernet/ti/Kconfig
++++ b/drivers/net/ethernet/ti/Kconfig
+@@ -99,6 +99,7 @@ config TI_K3_AM65_CPSW_NUSS
+       select NET_DEVLINK
+       select TI_DAVINCI_MDIO
+       select PHYLINK
++      select PAGE_POOL
+       select TI_K3_CPPI_DESC_POOL
+       imply PHY_TI_GMII_SEL
+       depends on TI_K3_AM65_CPTS || !TI_K3_AM65_CPTS
+-- 
+2.39.5
+
diff --git a/queue-6.13/net-ipv6-fix-dst-ref-loop-on-input-in-rpl-lwt.patch b/queue-6.13/net-ipv6-fix-dst-ref-loop-on-input-in-rpl-lwt.patch
new file mode 100644 (file)
index 0000000..f99cfef
--- /dev/null
@@ -0,0 +1,60 @@
+From f6fefb4f950495236321cf8deafe6d0f7efb02e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 18:51:39 +0100
+Subject: net: ipv6: fix dst ref loop on input in rpl lwt
+
+From: Justin Iurman <justin.iurman@uliege.be>
+
+[ Upstream commit 13e55fbaec176119cff68a7e1693b251c8883c5f ]
+
+Prevent a dst ref loop on input in rpl_iptunnel.
+
+Fixes: a7a29f9c361f ("net: ipv6: add rpl sr tunnel")
+Cc: Alexander Aring <alex.aring@gmail.com>
+Cc: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Justin Iurman <justin.iurman@uliege.be>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/rpl_iptunnel.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv6/rpl_iptunnel.c b/net/ipv6/rpl_iptunnel.c
+index 0ac4283acdf20..7c05ac846646f 100644
+--- a/net/ipv6/rpl_iptunnel.c
++++ b/net/ipv6/rpl_iptunnel.c
+@@ -262,10 +262,18 @@ static int rpl_input(struct sk_buff *skb)
+ {
+       struct dst_entry *orig_dst = skb_dst(skb);
+       struct dst_entry *dst = NULL;
++      struct lwtunnel_state *lwtst;
+       struct rpl_lwt *rlwt;
+       int err;
+-      rlwt = rpl_lwt_lwtunnel(orig_dst->lwtstate);
++      /* We cannot dereference "orig_dst" once ip6_route_input() or
++       * skb_dst_drop() is called. However, in order to detect a dst loop, we
++       * need the address of its lwtstate. So, save the address of lwtstate
++       * now and use it later as a comparison.
++       */
++      lwtst = orig_dst->lwtstate;
++
++      rlwt = rpl_lwt_lwtunnel(lwtst);
+       local_bh_disable();
+       dst = dst_cache_get(&rlwt->cache);
+@@ -280,7 +288,9 @@ static int rpl_input(struct sk_buff *skb)
+       if (!dst) {
+               ip6_route_input(skb);
+               dst = skb_dst(skb);
+-              if (!dst->error) {
++
++              /* cache only if we don't create a dst reference loop */
++              if (!dst->error && lwtst != dst->lwtstate) {
+                       local_bh_disable();
+                       dst_cache_set_ip6(&rlwt->cache, dst,
+                                         &ipv6_hdr(skb)->saddr);
+-- 
+2.39.5
+
diff --git a/queue-6.13/net-ipv6-fix-dst-ref-loop-on-input-in-seg6-lwt.patch b/queue-6.13/net-ipv6-fix-dst-ref-loop-on-input-in-seg6-lwt.patch
new file mode 100644 (file)
index 0000000..0b00c79
--- /dev/null
@@ -0,0 +1,60 @@
+From 1310547e7c9552a802ff73c5a82660f4c6985fd4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 18:51:38 +0100
+Subject: net: ipv6: fix dst ref loop on input in seg6 lwt
+
+From: Justin Iurman <justin.iurman@uliege.be>
+
+[ Upstream commit c64a0727f9b1cbc63a5538c8c0014e9a175ad864 ]
+
+Prevent a dst ref loop on input in seg6_iptunnel.
+
+Fixes: af4a2209b134 ("ipv6: sr: use dst_cache in seg6_input")
+Cc: David Lebrun <dlebrun@google.com>
+Cc: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Justin Iurman <justin.iurman@uliege.be>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/seg6_iptunnel.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c
+index 33833b2064c07..51583461ae29b 100644
+--- a/net/ipv6/seg6_iptunnel.c
++++ b/net/ipv6/seg6_iptunnel.c
+@@ -472,10 +472,18 @@ static int seg6_input_core(struct net *net, struct sock *sk,
+ {
+       struct dst_entry *orig_dst = skb_dst(skb);
+       struct dst_entry *dst = NULL;
++      struct lwtunnel_state *lwtst;
+       struct seg6_lwt *slwt;
+       int err;
+-      slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate);
++      /* We cannot dereference "orig_dst" once ip6_route_input() or
++       * skb_dst_drop() is called. However, in order to detect a dst loop, we
++       * need the address of its lwtstate. So, save the address of lwtstate
++       * now and use it later as a comparison.
++       */
++      lwtst = orig_dst->lwtstate;
++
++      slwt = seg6_lwt_lwtunnel(lwtst);
+       local_bh_disable();
+       dst = dst_cache_get(&slwt->cache);
+@@ -490,7 +498,9 @@ static int seg6_input_core(struct net *net, struct sock *sk,
+       if (!dst) {
+               ip6_route_input(skb);
+               dst = skb_dst(skb);
+-              if (!dst->error) {
++
++              /* cache only if we don't create a dst reference loop */
++              if (!dst->error && lwtst != dst->lwtstate) {
+                       local_bh_disable();
+                       dst_cache_set_ip6(&slwt->cache, dst,
+                                         &ipv6_hdr(skb)->saddr);
+-- 
+2.39.5
+
diff --git a/queue-6.13/net-loopback-avoid-sending-ip-packets-without-an-eth.patch b/queue-6.13/net-loopback-avoid-sending-ip-packets-without-an-eth.patch
new file mode 100644 (file)
index 0000000..3557185
--- /dev/null
@@ -0,0 +1,94 @@
+From e2b100508a9ecdb9caa072bce47189daff3a90e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Feb 2025 09:25:59 +0200
+Subject: net: loopback: Avoid sending IP packets without an Ethernet header
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 0e4427f8f587c4b603475468bb3aee9418574893 ]
+
+After commit 22600596b675 ("ipv4: give an IPv4 dev to blackhole_netdev")
+IPv4 neighbors can be constructed on the blackhole net device, but they
+are constructed with an output function (neigh_direct_output()) that
+simply calls dev_queue_xmit(). The latter will transmit packets via
+'skb->dev' which might not be the blackhole net device if dst_dev_put()
+switched 'dst->dev' to the blackhole net device while another CPU was
+using the dst entry in ip_output(), but after it already initialized
+'skb->dev' from 'dst->dev'.
+
+Specifically, the following can happen:
+
+    CPU1                                      CPU2
+
+udp_sendmsg(sk1)                          udp_sendmsg(sk2)
+udp_send_skb()                            [...]
+ip_output()
+    skb->dev = skb_dst(skb)->dev
+                                          dst_dev_put()
+                                              dst->dev = blackhole_netdev
+ip_finish_output2()
+    resolves neigh on dst->dev
+neigh_output()
+neigh_direct_output()
+dev_queue_xmit()
+
+This will result in IPv4 packets being sent without an Ethernet header
+via a valid net device:
+
+tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
+listening on enp9s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
+22:07:02.329668 20:00:40:11:18:fb > 45:00:00:44:f4:94, ethertype Unknown
+(0x58c6), length 68:
+        0x0000:  8dda 74ca f1ae ca6c ca6c 0098 969c 0400  ..t....l.l......
+        0x0010:  0000 4730 3f18 6800 0000 0000 0000 9971  ..G0?.h........q
+        0x0020:  c4c9 9055 a157 0a70 9ead bf83 38ca ab38  ...U.W.p....8..8
+        0x0030:  8add ab96 e052                           .....R
+
+Fix by making sure that neighbors are constructed on top of the
+blackhole net device with an output function that simply consumes the
+packets, in a similar fashion to dst_discard_out() and
+blackhole_netdev_xmit().
+
+Fixes: 8d7017fd621d ("blackhole_netdev: use blackhole_netdev to invalidate dst entries")
+Fixes: 22600596b675 ("ipv4: give an IPv4 dev to blackhole_netdev")
+Reported-by: Florian Meister <fmei@sfs.com>
+Closes: https://lore.kernel.org/netdev/20250210084931.23a5c2e4@hermes.local/
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20250220072559.782296-1-idosch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/loopback.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
+index 1993b90b1a5f9..491e56b3263fd 100644
+--- a/drivers/net/loopback.c
++++ b/drivers/net/loopback.c
+@@ -244,8 +244,22 @@ static netdev_tx_t blackhole_netdev_xmit(struct sk_buff *skb,
+       return NETDEV_TX_OK;
+ }
++static int blackhole_neigh_output(struct neighbour *n, struct sk_buff *skb)
++{
++      kfree_skb(skb);
++      return 0;
++}
++
++static int blackhole_neigh_construct(struct net_device *dev,
++                                   struct neighbour *n)
++{
++      n->output = blackhole_neigh_output;
++      return 0;
++}
++
+ static const struct net_device_ops blackhole_netdev_ops = {
+       .ndo_start_xmit = blackhole_netdev_xmit,
++      .ndo_neigh_construct = blackhole_neigh_construct,
+ };
+ /* This is a dst-dummy device used specifically for invalidated
+-- 
+2.39.5
+
diff --git a/queue-6.13/net-mlx5-fix-vport-qos-cleanup-on-error.patch b/queue-6.13/net-mlx5-fix-vport-qos-cleanup-on-error.patch
new file mode 100644 (file)
index 0000000..fa81f11
--- /dev/null
@@ -0,0 +1,47 @@
+From 7d5e053b99e7e065fe4175eea175834bf9551250 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 09:26:06 +0200
+Subject: net/mlx5: Fix vport QoS cleanup on error
+
+From: Carolina Jubran <cjubran@nvidia.com>
+
+[ Upstream commit 7f3528f7d2f98b70e19a6bb7b130fc82c079ac54 ]
+
+When enabling vport QoS fails, the scheduling node was never freed,
+causing a leak.
+
+Add the missing free and reset the vport scheduling node pointer to
+NULL.
+
+Fixes: be034baba83e ("net/mlx5: Make vport QoS enablement more flexible for future extensions")
+Signed-off-by: Carolina Jubran <cjubran@nvidia.com>
+Reviewed-by: Cosmin Ratiu <cratiu@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/20250225072608.526866-2-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/esw/qos.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
+index 8b7c843446e11..07a28073a49ea 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
+@@ -591,8 +591,11 @@ static int mlx5_esw_qos_vport_enable(struct mlx5_vport *vport, enum sched_node_t
+       sched_node->vport = vport;
+       vport->qos.sched_node = sched_node;
+       err = esw_qos_vport_enable(vport, parent, extack);
+-      if (err)
++      if (err) {
++              __esw_qos_free_node(sched_node);
+               esw_qos_put(esw);
++              vport->qos.sched_node = NULL;
++      }
+       return err;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.13/net-mlx5-irq-fix-null-string-in-debug-print.patch b/queue-6.13/net-mlx5-irq-fix-null-string-in-debug-print.patch
new file mode 100644 (file)
index 0000000..59f228d
--- /dev/null
@@ -0,0 +1,42 @@
+From f9737883ee0fb9796f778c16ce42c262c3242f3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 09:26:08 +0200
+Subject: net/mlx5: IRQ, Fix null string in debug print
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit 2f5a6014eb168a97b24153adccfa663d3b282767 ]
+
+irq_pool_alloc() debug print can print a null string.
+Fix it by providing a default string to print.
+
+Fixes: 71e084e26414 ("net/mlx5: Allocating a pool of MSI-X vectors for SFs")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202501141055.SwfIphN0-lkp@intel.com/
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Link: https://patch.msgid.link/20250225072608.526866-4-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/pci_irq.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c
+index 7db9cab9bedf6..d9362eabc6a1c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c
+@@ -572,7 +572,7 @@ irq_pool_alloc(struct mlx5_core_dev *dev, int start, int size, char *name,
+       pool->min_threshold = min_threshold * MLX5_EQ_REFS_PER_IRQ;
+       pool->max_threshold = max_threshold * MLX5_EQ_REFS_PER_IRQ;
+       mlx5_core_dbg(dev, "pool->name = %s, pool->size = %d, pool->start = %d",
+-                    name, size, start);
++                    name ? name : "mlx5_pcif_pool", size, start);
+       return pool;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.13/net-mlx5-restore-missing-trace-event-when-enabling-v.patch b/queue-6.13/net-mlx5-restore-missing-trace-event-when-enabling-v.patch
new file mode 100644 (file)
index 0000000..7eac440
--- /dev/null
@@ -0,0 +1,41 @@
+From 50af5d8f11f5534ae942c4243d8c7fc0b9f59987 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 09:26:07 +0200
+Subject: net/mlx5: Restore missing trace event when enabling vport QoS
+
+From: Carolina Jubran <cjubran@nvidia.com>
+
+[ Upstream commit 47bcd9bf3d231bfd4698d7d3013597490fd5e2d6 ]
+
+Restore the `trace_mlx5_esw_vport_qos_create` event when creating
+the vport scheduling element. This trace event was lost during
+refactoring.
+
+Fixes: be034baba83e ("net/mlx5: Make vport QoS enablement more flexible for future extensions")
+Signed-off-by: Carolina Jubran <cjubran@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/20250225072608.526866-3-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/esw/qos.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
+index 07a28073a49ea..823c1ba456cd1 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
+@@ -564,6 +564,9 @@ static int esw_qos_vport_enable(struct mlx5_vport *vport, struct mlx5_esw_sched_
+               return err;
+       esw_qos_normalize_min_rate(parent->esw, parent, extack);
++      trace_mlx5_esw_vport_qos_create(vport->dev, vport,
++                                      vport->qos.sched_node->max_rate,
++                                      vport->qos.sched_node->bw_share);
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.13/net-mvpp2-cls-fixed-non-ip-flow-with-vlan-tag-flow-d.patch b/queue-6.13/net-mvpp2-cls-fixed-non-ip-flow-with-vlan-tag-flow-d.patch
new file mode 100644 (file)
index 0000000..de0b671
--- /dev/null
@@ -0,0 +1,40 @@
+From edcd284edb4d6c425ab566e01628be5c908f0a70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 20:20:58 -0800
+Subject: net: mvpp2: cls: Fixed Non IP flow, with vlan tag flow defination.
+
+From: Harshal Chaudhari <hchaudhari@marvell.com>
+
+[ Upstream commit 2d253726ff7106b39a44483b6864398bba8a2f74 ]
+
+Non IP flow, with vlan tag not working as expected while
+running below command for vlan-priority. fixed that.
+
+ethtool -N eth1 flow-type ether vlan 0x8000 vlan-mask 0x1fff action 0 loc 0
+
+Fixes: 1274daede3ef ("net: mvpp2: cls: Add steering based on vlan Id and priority.")
+Signed-off-by: Harshal Chaudhari <hchaudhari@marvell.com>
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20250225042058.2643838-1-hchaudhari@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c
+index 1641791a2d5b4..8ed83fb988624 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c
+@@ -324,7 +324,7 @@ static const struct mvpp2_cls_flow cls_flows[MVPP2_N_PRS_FLOWS] = {
+                      MVPP2_PRS_RI_VLAN_MASK),
+       /* Non IP flow, with vlan tag */
+       MVPP2_DEF_FLOW(MVPP22_FLOW_ETHERNET, MVPP2_FL_NON_IP_TAG,
+-                     MVPP22_CLS_HEK_OPT_VLAN,
++                     MVPP22_CLS_HEK_TAGGED,
+                      0, 0),
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.13/net-set-the-minimum-for-net_hotdata.netdev_budget_us.patch b/queue-6.13/net-set-the-minimum-for-net_hotdata.netdev_budget_us.patch
new file mode 100644 (file)
index 0000000..b15ca9f
--- /dev/null
@@ -0,0 +1,58 @@
+From b07c5fd4043e7bc296f34796e90b145ce8c33a20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Feb 2025 12:07:52 +0100
+Subject: net: set the minimum for net_hotdata.netdev_budget_usecs
+
+From: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+
+[ Upstream commit c180188ec02281126045414e90d08422a80f75b4 ]
+
+Commit 7acf8a1e8a28 ("Replace 2 jiffies with sysctl netdev_budget_usecs
+to enable softirq tuning") added a possibility to set
+net_hotdata.netdev_budget_usecs, but added no lower bound checking.
+
+Commit a4837980fd9f ("net: revert default NAPI poll timeout to 2 jiffies")
+made the *initial* value HZ-dependent, so the initial value is at least
+2 jiffies even for lower HZ values (2 ms for 1000 Hz, 8ms for 250 Hz, 20
+ms for 100 Hz).
+
+But a user still can set improper values by a sysctl. Set .extra1
+(the lower bound) for net_hotdata.netdev_budget_usecs to the same value
+as in the latter commit. That is to 2 jiffies.
+
+Fixes: a4837980fd9f ("net: revert default NAPI poll timeout to 2 jiffies")
+Fixes: 7acf8a1e8a28 ("Replace 2 jiffies with sysctl netdev_budget_usecs to enable softirq tuning")
+Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+Cc: Dmitry Yakunin <zeil@yandex-team.ru>
+Cc: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
+Link: https://patch.msgid.link/20250220110752.137639-1-jirislaby@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sysctl_net_core.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
+index ad2741f1346af..c7769ee0d9c55 100644
+--- a/net/core/sysctl_net_core.c
++++ b/net/core/sysctl_net_core.c
+@@ -34,6 +34,7 @@ static int min_sndbuf = SOCK_MIN_SNDBUF;
+ static int min_rcvbuf = SOCK_MIN_RCVBUF;
+ static int max_skb_frags = MAX_SKB_FRAGS;
+ static int min_mem_pcpu_rsv = SK_MEMORY_PCPU_RESERVE;
++static int netdev_budget_usecs_min = 2 * USEC_PER_SEC / HZ;
+ static int net_msg_warn;      /* Unused, but still a sysctl */
+@@ -587,7 +588,7 @@ static struct ctl_table net_core_table[] = {
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec_minmax,
+-              .extra1         = SYSCTL_ZERO,
++              .extra1         = &netdev_budget_usecs_min,
+       },
+       {
+               .procname       = "fb_tunnels_only_for_init_net",
+-- 
+2.39.5
+
diff --git a/queue-6.13/net-ti-icss-iep-reject-perout-generation-request.patch b/queue-6.13/net-ti-icss-iep-reject-perout-generation-request.patch
new file mode 100644 (file)
index 0000000..ddadc4a
--- /dev/null
@@ -0,0 +1,60 @@
+From c32e456dac8819711f66036bee8ff4505b1ff4e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 14:54:41 +0530
+Subject: net: ti: icss-iep: Reject perout generation request
+
+From: Meghana Malladi <m-malladi@ti.com>
+
+[ Upstream commit 54e1b4becf5e220be03db4e1be773c1310e8cbbd ]
+
+IEP driver supports both perout and pps signal generation
+but perout feature is faulty with half-cooked support
+due to some missing configuration. Remove perout
+support from the driver and reject perout requests with
+"not supported" error code.
+
+Fixes: c1e0230eeaab2 ("net: ti: icss-iep: Add IEP driver")
+Signed-off-by: Meghana Malladi <m-malladi@ti.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Link: https://patch.msgid.link/20250227092441.1848419-1-m-malladi@ti.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/icssg/icss_iep.c | 21 +--------------------
+ 1 file changed, 1 insertion(+), 20 deletions(-)
+
+diff --git a/drivers/net/ethernet/ti/icssg/icss_iep.c b/drivers/net/ethernet/ti/icssg/icss_iep.c
+index 768578c0d9587..d59c1744840af 100644
+--- a/drivers/net/ethernet/ti/icssg/icss_iep.c
++++ b/drivers/net/ethernet/ti/icssg/icss_iep.c
+@@ -474,26 +474,7 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep,
+ static int icss_iep_perout_enable(struct icss_iep *iep,
+                                 struct ptp_perout_request *req, int on)
+ {
+-      int ret = 0;
+-
+-      mutex_lock(&iep->ptp_clk_mutex);
+-
+-      if (iep->pps_enabled) {
+-              ret = -EBUSY;
+-              goto exit;
+-      }
+-
+-      if (iep->perout_enabled == !!on)
+-              goto exit;
+-
+-      ret = icss_iep_perout_enable_hw(iep, req, on);
+-      if (!ret)
+-              iep->perout_enabled = !!on;
+-
+-exit:
+-      mutex_unlock(&iep->ptp_clk_mutex);
+-
+-      return ret;
++      return -EOPNOTSUPP;
+ }
+ static void icss_iep_cap_cmp_work(struct work_struct *work)
+-- 
+2.39.5
+
diff --git a/queue-6.13/rxrpc-rxperf-fix-missing-decoding-of-terminal-magic-.patch b/queue-6.13/rxrpc-rxperf-fix-missing-decoding-of-terminal-magic-.patch
new file mode 100644 (file)
index 0000000..0f3f11d
--- /dev/null
@@ -0,0 +1,51 @@
+From 5b6e95f83bad38706690a944e5c53d34d65e5a69 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Feb 2025 19:22:44 +0000
+Subject: rxrpc: rxperf: Fix missing decoding of terminal magic cookie
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit c34d999ca3145d9fe858258cc3342ec493f47d2e ]
+
+The rxperf RPCs seem to have a magic cookie at the end of the request that
+was failing to be taken account of by the unmarshalling of the request.
+Fix the rxperf code to expect this.
+
+Fixes: 75bfdbf2fca3 ("rxrpc: Implement an in-kernel rxperf server for testing purposes")
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+Link: https://patch.msgid.link/20250218192250.296870-2-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rxrpc/rxperf.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/net/rxrpc/rxperf.c b/net/rxrpc/rxperf.c
+index 085e7892d3104..b1536da2246b8 100644
+--- a/net/rxrpc/rxperf.c
++++ b/net/rxrpc/rxperf.c
+@@ -478,6 +478,18 @@ static int rxperf_deliver_request(struct rxperf_call *call)
+               call->unmarshal++;
+               fallthrough;
+       case 2:
++              ret = rxperf_extract_data(call, true);
++              if (ret < 0)
++                      return ret;
++
++              /* Deal with the terminal magic cookie. */
++              call->iov_len = 4;
++              call->kvec[0].iov_len   = call->iov_len;
++              call->kvec[0].iov_base  = call->tmp;
++              iov_iter_kvec(&call->iter, READ, call->kvec, 1, call->iov_len);
++              call->unmarshal++;
++              fallthrough;
++      case 3:
+               ret = rxperf_extract_data(call, false);
+               if (ret < 0)
+                       return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.13/selftests-drv-net-check-if-combined-count-exists.patch b/queue-6.13/selftests-drv-net-check-if-combined-count-exists.patch
new file mode 100644 (file)
index 0000000..f3f03be
--- /dev/null
@@ -0,0 +1,82 @@
+From e62ed381795330e1ad29585b85ea012e8c9c5435 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2025 18:19:57 +0000
+Subject: selftests: drv-net: Check if combined-count exists
+
+From: Joe Damato <jdamato@fastly.com>
+
+[ Upstream commit 1cbddbddee68d17feb6467fc556c144777af91ef ]
+
+Some drivers, like tg3, do not set combined-count:
+
+$ ethtool -l enp4s0f1
+Channel parameters for enp4s0f1:
+Pre-set maximums:
+RX:            4
+TX:            4
+Other:         n/a
+Combined:      n/a
+Current hardware settings:
+RX:            4
+TX:            1
+Other:         n/a
+Combined:      n/a
+
+In the case where combined-count is not set, the ethtool netlink code
+in the kernel elides the value and the code in the test:
+
+  netnl.channels_get(...)
+
+With a tg3 device, the returned dictionary looks like:
+
+{'header': {'dev-index': 3, 'dev-name': 'enp4s0f1'},
+ 'rx-max': 4,
+ 'rx-count': 4,
+ 'tx-max': 4,
+ 'tx-count': 1}
+
+Note that the key 'combined-count' is missing. As a result of this
+missing key the test raises an exception:
+
+ # Exception|     if channels['combined-count'] == 0:
+ # Exception|        ~~~~~~~~^^^^^^^^^^^^^^^^^^
+ # Exception| KeyError: 'combined-count'
+
+Change the test to check if 'combined-count' is a key in the dictionary
+first and if not assume that this means the driver has separate RX and
+TX queues.
+
+With this change, the test now passes successfully on tg3 and mlx5
+(which does have a 'combined-count').
+
+Fixes: 1cf270424218 ("net: selftest: add test for netdev netlink queue-get API")
+Signed-off-by: Joe Damato <jdamato@fastly.com>
+Reviewed-by: David Wei <dw@davidwei.uk>
+Link: https://patch.msgid.link/20250226181957.212189-1-jdamato@fastly.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/drivers/net/queues.py | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/tools/testing/selftests/drivers/net/queues.py b/tools/testing/selftests/drivers/net/queues.py
+index 38303da957ee5..8a518905a9f9c 100755
+--- a/tools/testing/selftests/drivers/net/queues.py
++++ b/tools/testing/selftests/drivers/net/queues.py
+@@ -45,10 +45,9 @@ def addremove_queues(cfg, nl) -> None:
+     netnl = EthtoolFamily()
+     channels = netnl.channels_get({'header': {'dev-index': cfg.ifindex}})
+-    if channels['combined-count'] == 0:
+-        rx_type = 'rx'
+-    else:
+-        rx_type = 'combined'
++    rx_type = 'rx'
++    if channels.get('combined-count', 0) > 0:
++            rx_type = 'combined'
+     expected = curr_queues - 1
+     cmd(f"ethtool -L {cfg.dev['ifname']} {rx_type} {expected}", timeout=10)
+-- 
+2.39.5
+
index d24a1d39a9f1c429d0a7218608724047fdd37fec..a26c8277a300ce58976303afec547d51e32e307f 100644 (file)
@@ -22,3 +22,41 @@ scsi-ufs-core-set-default-runtime-system-pm-levels-b.patch
 rdma-mlx5-fix-bind-qp-error-cleanup-flow.patch
 rdma-bnxt_re-fix-the-page-details-for-the-srq-create.patch
 sunrpc-suppress-warnings-for-unused-procfs-functions.patch
+alsa-usb-audio-avoid-dropping-midi-events-at-closing.patch
+bluetooth-l2cap-fix-l2cap_ecred_conn_rsp-response.patch
+rxrpc-rxperf-fix-missing-decoding-of-terminal-magic-.patch
+afs-fix-the-server_list-to-unuse-a-displaced-server-.patch
+afs-give-an-afs_server-object-a-ref-on-the-afs_cell-.patch
+net-add-net_passive_inc-and-net_passive_dec.patch
+net-better-track-kernel-sockets-lifetime.patch
+net-loopback-avoid-sending-ip-packets-without-an-eth.patch
+net-set-the-minimum-for-net_hotdata.netdev_budget_us.patch
+ipvlan-ensure-network-headers-are-in-skb-linear-part.patch
+net-cadence-macb-synchronize-stats-calculations.patch
+net-dsa-rtl8366rb-fix-compilation-problem.patch
+asoc-es8328-fix-route-from-dac-to-output.patch
+asoc-fsl-rename-stream-name-of-sai-dai-driver.patch
+ipvs-always-clear-ipvs_property-flag-in-skb_scrub_pa.patch
+drm-xe-oa-allow-oa_exponent-value-of-0.patch
+firmware-cs_dsp-remove-async-regmap-writes.patch
+asoc-cs35l56-prevent-races-when-soft-resetting-using.patch
+alsa-hda-realtek-fix-wrong-mic-setup-for-asus-vivobo.patch
+drm-amdgpu-gfx-only-call-mes-for-enforce-isolation-i.patch
+drm-amdgpu-mes-keep-enforce-isolation-up-to-date.patch
+drm-amd-display-restore-edid-reading-from-a-given-i2.patch
+net-ethernet-ti-am65-cpsw-select-page_pool.patch
+tcp-devmem-don-t-write-truncated-dmabuf-cmsgs-to-use.patch
+ice-fix-deinitializing-vf-in-error-path.patch
+ice-avoid-setting-default-rx-vsi-twice-in-switchdev-.patch
+tcp-defer-ts_recent-changes-until-req-is-owned.patch
+drm-xe-cancel-pending-job-timer-before-freeing-sched.patch
+net-clear-old-fragment-checksum-value-in-napi_reuse_.patch
+net-mvpp2-cls-fixed-non-ip-flow-with-vlan-tag-flow-d.patch
+net-mlx5-fix-vport-qos-cleanup-on-error.patch
+net-mlx5-restore-missing-trace-event-when-enabling-v.patch
+net-mlx5-irq-fix-null-string-in-debug-print.patch
+net-ipv6-fix-dst-ref-loop-on-input-in-seg6-lwt.patch
+net-ipv6-fix-dst-ref-loop-on-input-in-rpl-lwt.patch
+selftests-drv-net-check-if-combined-count-exists.patch
+idpf-fix-checksums-set-in-idpf_rx_rsc.patch
+net-ti-icss-iep-reject-perout-generation-request.patch
diff --git a/queue-6.13/tcp-defer-ts_recent-changes-until-req-is-owned.patch b/queue-6.13/tcp-defer-ts_recent-changes-until-req-is-owned.patch
new file mode 100644 (file)
index 0000000..b0813b2
--- /dev/null
@@ -0,0 +1,92 @@
+From 155ce15f782771ac41f18ac159ad61b645b474b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 17:00:47 +0800
+Subject: tcp: Defer ts_recent changes until req is owned
+
+From: Wang Hai <wanghai38@huawei.com>
+
+[ Upstream commit 8d52da23b6c68a0f6bad83959ebb61a2cf623c4e ]
+
+Recently a bug was discovered where the server had entered TCP_ESTABLISHED
+state, but the upper layers were not notified.
+
+The same 5-tuple packet may be processed by different CPUSs, so two
+CPUs may receive different ack packets at the same time when the
+state is TCP_NEW_SYN_RECV.
+
+In that case, req->ts_recent in tcp_check_req may be changed concurrently,
+which will probably cause the newsk's ts_recent to be incorrectly large.
+So that tcp_validate_incoming will fail. At this point, newsk will not be
+able to enter the TCP_ESTABLISHED.
+
+cpu1                                    cpu2
+tcp_check_req
+                                        tcp_check_req
+ req->ts_recent = rcv_tsval = t1
+                                         req->ts_recent = rcv_tsval = t2
+
+ syn_recv_sock
+  tcp_sk(child)->rx_opt.ts_recent = req->ts_recent = t2 // t1 < t2
+tcp_child_process
+ tcp_rcv_state_process
+  tcp_validate_incoming
+   tcp_paws_check
+    if ((s32)(rx_opt->ts_recent - rx_opt->rcv_tsval) <= paws_win)
+        // t2 - t1 > paws_win, failed
+                                        tcp_v4_do_rcv
+                                         tcp_rcv_state_process
+                                         // TCP_ESTABLISHED
+
+The cpu2's skb or a newly received skb will call tcp_v4_do_rcv to get
+the newsk into the TCP_ESTABLISHED state, but at this point it is no
+longer possible to notify the upper layer application. A notification
+mechanism could be added here, but the fix is more complex, so the
+current fix is used.
+
+In tcp_check_req, req->ts_recent is used to assign a value to
+tcp_sk(child)->rx_opt.ts_recent, so removing the change in req->ts_recent
+and changing tcp_sk(child)->rx_opt.ts_recent directly after owning the
+req fixes this bug.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Wang Hai <wanghai38@huawei.com>
+Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_minisocks.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
+index 7121d8573928c..789e495d3bd6a 100644
+--- a/net/ipv4/tcp_minisocks.c
++++ b/net/ipv4/tcp_minisocks.c
+@@ -810,12 +810,6 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
+       /* In sequence, PAWS is OK. */
+-      /* TODO: We probably should defer ts_recent change once
+-       * we take ownership of @req.
+-       */
+-      if (tmp_opt.saw_tstamp && !after(TCP_SKB_CB(skb)->seq, tcp_rsk(req)->rcv_nxt))
+-              WRITE_ONCE(req->ts_recent, tmp_opt.rcv_tsval);
+-
+       if (TCP_SKB_CB(skb)->seq == tcp_rsk(req)->rcv_isn) {
+               /* Truncate SYN, it is out of window starting
+                  at tcp_rsk(req)->rcv_isn + 1. */
+@@ -864,6 +858,10 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
+       if (!child)
+               goto listen_overflow;
++      if (own_req && tmp_opt.saw_tstamp &&
++          !after(TCP_SKB_CB(skb)->seq, tcp_rsk(req)->rcv_nxt))
++              tcp_sk(child)->rx_opt.ts_recent = tmp_opt.rcv_tsval;
++
+       if (own_req && rsk_drop_req(req)) {
+               reqsk_queue_removed(&inet_csk(req->rsk_listener)->icsk_accept_queue, req);
+               inet_csk_reqsk_queue_drop_and_put(req->rsk_listener, req);
+-- 
+2.39.5
+
diff --git a/queue-6.13/tcp-devmem-don-t-write-truncated-dmabuf-cmsgs-to-use.patch b/queue-6.13/tcp-devmem-don-t-write-truncated-dmabuf-cmsgs-to-use.patch
new file mode 100644 (file)
index 0000000..d3e10b2
--- /dev/null
@@ -0,0 +1,129 @@
+From 1e3d288ec2da8a2996e10b347ada6523d0bfd4af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 09:44:01 -0800
+Subject: tcp: devmem: don't write truncated dmabuf CMSGs to userspace
+
+From: Stanislav Fomichev <sdf@fomichev.me>
+
+[ Upstream commit 18912c520674ec4d920fe3826e7e4fefeecdf5ae ]
+
+Currently, we report -ETOOSMALL (err) only on the first iteration
+(!sent). When we get put_cmsg error after a bunch of successful
+put_cmsg calls, we don't signal the error at all. This might be
+confusing on the userspace side which will see truncated CMSGs
+but no MSG_CTRUNC signal.
+
+Consider the following case:
+- sizeof(struct cmsghdr) = 16
+- sizeof(struct dmabuf_cmsg) = 24
+- total cmsg size (CMSG_LEN) = 40 (16+24)
+
+When calling recvmsg with msg_controllen=60, the userspace
+will receive two(!) dmabuf_cmsg(s), the first one will
+be a valid one and the second one will be silently truncated. There is no
+easy way to discover the truncation besides doing something like
+"cm->cmsg_len != CMSG_LEN(sizeof(dmabuf_cmsg))".
+
+Introduce new put_devmem_cmsg wrapper that reports an error instead
+of doing the truncation. Mina suggests that it's the intended way
+this API should work.
+
+Note that we might now report MSG_CTRUNC when the users (incorrectly)
+call us with msg_control == NULL.
+
+Fixes: 8f0b3cc9a4c1 ("tcp: RX path for devmem TCP")
+Reviewed-by: Mina Almasry <almasrymina@google.com>
+Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20250224174401.3582695-1-sdf@fomichev.me
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/socket.h |  2 ++
+ net/core/scm.c         | 10 ++++++++++
+ net/ipv4/tcp.c         | 26 ++++++++++----------------
+ 3 files changed, 22 insertions(+), 16 deletions(-)
+
+diff --git a/include/linux/socket.h b/include/linux/socket.h
+index d18cc47e89bd0..c3322eb3d6865 100644
+--- a/include/linux/socket.h
++++ b/include/linux/socket.h
+@@ -392,6 +392,8 @@ struct ucred {
+ extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr);
+ extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
++extern int put_cmsg_notrunc(struct msghdr *msg, int level, int type, int len,
++                          void *data);
+ struct timespec64;
+ struct __kernel_timespec;
+diff --git a/net/core/scm.c b/net/core/scm.c
+index 4f6a14babe5ae..733c0cbd393d2 100644
+--- a/net/core/scm.c
++++ b/net/core/scm.c
+@@ -282,6 +282,16 @@ int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data)
+ }
+ EXPORT_SYMBOL(put_cmsg);
++int put_cmsg_notrunc(struct msghdr *msg, int level, int type, int len,
++                   void *data)
++{
++      /* Don't produce truncated CMSGs */
++      if (!msg->msg_control || msg->msg_controllen < CMSG_LEN(len))
++              return -ETOOSMALL;
++
++      return put_cmsg(msg, level, type, len, data);
++}
++
+ void put_cmsg_scm_timestamping64(struct msghdr *msg, struct scm_timestamping_internal *tss_internal)
+ {
+       struct scm_timestamping64 tss;
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 0d704bda6c416..d74281eca14f0 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -2438,14 +2438,12 @@ static int tcp_recvmsg_dmabuf(struct sock *sk, const struct sk_buff *skb,
+                        */
+                       memset(&dmabuf_cmsg, 0, sizeof(dmabuf_cmsg));
+                       dmabuf_cmsg.frag_size = copy;
+-                      err = put_cmsg(msg, SOL_SOCKET, SO_DEVMEM_LINEAR,
+-                                     sizeof(dmabuf_cmsg), &dmabuf_cmsg);
+-                      if (err || msg->msg_flags & MSG_CTRUNC) {
+-                              msg->msg_flags &= ~MSG_CTRUNC;
+-                              if (!err)
+-                                      err = -ETOOSMALL;
++                      err = put_cmsg_notrunc(msg, SOL_SOCKET,
++                                             SO_DEVMEM_LINEAR,
++                                             sizeof(dmabuf_cmsg),
++                                             &dmabuf_cmsg);
++                      if (err)
+                               goto out;
+-                      }
+                       sent += copy;
+@@ -2499,16 +2497,12 @@ static int tcp_recvmsg_dmabuf(struct sock *sk, const struct sk_buff *skb,
+                               offset += copy;
+                               remaining_len -= copy;
+-                              err = put_cmsg(msg, SOL_SOCKET,
+-                                             SO_DEVMEM_DMABUF,
+-                                             sizeof(dmabuf_cmsg),
+-                                             &dmabuf_cmsg);
+-                              if (err || msg->msg_flags & MSG_CTRUNC) {
+-                                      msg->msg_flags &= ~MSG_CTRUNC;
+-                                      if (!err)
+-                                              err = -ETOOSMALL;
++                              err = put_cmsg_notrunc(msg, SOL_SOCKET,
++                                                     SO_DEVMEM_DMABUF,
++                                                     sizeof(dmabuf_cmsg),
++                                                     &dmabuf_cmsg);
++                              if (err)
+                                       goto out;
+-                              }
+                               atomic_long_inc(&niov->pp_ref_count);
+                               tcp_xa_pool.netmems[tcp_xa_pool.idx++] = skb_frag_netmem(frag);
+-- 
+2.39.5
+