--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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, ¶m);
+ 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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
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
--- /dev/null
+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
+
--- /dev/null
+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
+