From: Sasha Levin Date: Sat, 1 Mar 2025 14:19:51 +0000 (-0500) Subject: Fixes for 6.13 X-Git-Tag: v6.6.81~47 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d736b90188418611dcac134fe79e10108782e761;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.13 Signed-off-by: Sasha Levin --- diff --git a/queue-6.13/afs-fix-the-server_list-to-unuse-a-displaced-server-.patch b/queue-6.13/afs-fix-the-server_list-to-unuse-a-displaced-server-.patch new file mode 100644 index 0000000000..b03cffc1d0 --- /dev/null +++ b/queue-6.13/afs-fix-the-server_list-to-unuse-a-displaced-server-.patch @@ -0,0 +1,59 @@ +From fd4f4de58d38e1c69fb3c80d64190e976bc2613d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +cc: Marc Dionne +cc: Simon Horman +cc: linux-afs@lists.infradead.org +Link: https://patch.msgid.link/20250218192250.296870-5-dhowells@redhat.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + fs/afs/server_list.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/afs/server_list.c b/fs/afs/server_list.c +index 7e7e567a7f8a2..d20cd902ef949 100644 +--- a/fs/afs/server_list.c ++++ b/fs/afs/server_list.c +@@ -97,8 +97,8 @@ struct afs_server_list *afs_alloc_server_list(struct afs_volume *volume, + break; + if (j < slist->nr_servers) { + if (slist->servers[j].server == server) { +- afs_put_server(volume->cell->net, server, +- afs_server_trace_put_slist_isort); ++ afs_unuse_server(volume->cell->net, server, ++ afs_server_trace_put_slist_isort); + continue; + } + +-- +2.39.5 + diff --git a/queue-6.13/afs-give-an-afs_server-object-a-ref-on-the-afs_cell-.patch b/queue-6.13/afs-give-an-afs_server-object-a-ref-on-the-afs_cell-.patch new file mode 100644 index 0000000000..7a96b9e894 --- /dev/null +++ b/queue-6.13/afs-give-an-afs_server-object-a-ref-on-the-afs_cell-.patch @@ -0,0 +1,77 @@ +From fce175d41fab11e080b88e51ecdaf15c7d33ee2e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +cc: Marc Dionne +cc: Simon Horman +cc: linux-afs@lists.infradead.org +Link: https://patch.msgid.link/20250218192250.296870-6-dhowells@redhat.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + fs/afs/server.c | 3 +++ + include/trace/events/afs.h | 2 ++ + 2 files changed, 5 insertions(+) + +diff --git a/fs/afs/server.c b/fs/afs/server.c +index 038f9d0ae3af8..4504e16b458cc 100644 +--- a/fs/afs/server.c ++++ b/fs/afs/server.c +@@ -163,6 +163,8 @@ static struct afs_server *afs_install_server(struct afs_cell *cell, + rb_insert_color(&server->uuid_rb, &net->fs_servers); + hlist_add_head_rcu(&server->proc_link, &net->fs_proc); + ++ afs_get_cell(cell, afs_cell_trace_get_server); ++ + added_dup: + write_seqlock(&net->fs_addr_lock); + estate = rcu_dereference_protected(server->endpoint_state, +@@ -442,6 +444,7 @@ static void afs_server_rcu(struct rcu_head *rcu) + atomic_read(&server->active), afs_server_trace_free); + afs_put_endpoint_state(rcu_access_pointer(server->endpoint_state), + afs_estate_trace_put_server); ++ afs_put_cell(server->cell, afs_cell_trace_put_server); + kfree(server); + } + +diff --git a/include/trace/events/afs.h b/include/trace/events/afs.h +index 9a75590227f26..3dddfc6abf0ee 100644 +--- a/include/trace/events/afs.h ++++ b/include/trace/events/afs.h +@@ -173,6 +173,7 @@ enum yfs_cm_operation { + EM(afs_cell_trace_get_queue_dns, "GET q-dns ") \ + EM(afs_cell_trace_get_queue_manage, "GET q-mng ") \ + EM(afs_cell_trace_get_queue_new, "GET q-new ") \ ++ EM(afs_cell_trace_get_server, "GET server") \ + EM(afs_cell_trace_get_vol, "GET vol ") \ + EM(afs_cell_trace_insert, "INSERT ") \ + EM(afs_cell_trace_manage, "MANAGE ") \ +@@ -180,6 +181,7 @@ enum yfs_cm_operation { + EM(afs_cell_trace_put_destroy, "PUT destry") \ + EM(afs_cell_trace_put_queue_work, "PUT q-work") \ + EM(afs_cell_trace_put_queue_fail, "PUT q-fail") \ ++ EM(afs_cell_trace_put_server, "PUT server") \ + EM(afs_cell_trace_put_vol, "PUT vol ") \ + EM(afs_cell_trace_see_source, "SEE source") \ + EM(afs_cell_trace_see_ws, "SEE ws ") \ +-- +2.39.5 + diff --git a/queue-6.13/alsa-hda-realtek-fix-wrong-mic-setup-for-asus-vivobo.patch b/queue-6.13/alsa-hda-realtek-fix-wrong-mic-setup-for-asus-vivobo.patch new file mode 100644 index 0000000000..e80b04ca4d --- /dev/null +++ b/queue-6.13/alsa-hda-realtek-fix-wrong-mic-setup-for-asus-vivobo.patch @@ -0,0 +1,45 @@ +From c39cd19b07012583d6fb2f5e68c52252d26b874e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Feb 2025 16:45:32 +0100 +Subject: ALSA: hda/realtek: Fix wrong mic setup for ASUS VivoBook 15 + +From: Takashi Iwai + +[ 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 +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index ffe3de617d5dd..5441425292195 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -10595,6 +10595,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC), + SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), + SND_PCI_QUIRK(0x1043, 0x1433, "ASUS GX650PY/PZ/PV/PU/PYV/PZV/PIV/PVV", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1043, 0x1460, "Asus VivoBook 15", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x1463, "Asus GA402X/GA402N", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC), + SND_PCI_QUIRK(0x1043, 0x1473, "ASUS GU604VI/VC/VE/VG/VJ/VQ/VU/VV/VY/VZ", ALC285_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1043, 0x1483, "ASUS GU603VQ/VU/VV/VJ/VI", ALC285_FIXUP_ASUS_HEADSET_MIC), +-- +2.39.5 + diff --git a/queue-6.13/alsa-usb-audio-avoid-dropping-midi-events-at-closing.patch b/queue-6.13/alsa-usb-audio-avoid-dropping-midi-events-at-closing.patch new file mode 100644 index 0000000000..1e687a4770 --- /dev/null +++ b/queue-6.13/alsa-usb-audio-avoid-dropping-midi-events-at-closing.patch @@ -0,0 +1,47 @@ +From e9a08b012287732775ecce6553b409c0d43e9f11 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Feb 2025 12:40:24 +0100 +Subject: ALSA: usb-audio: Avoid dropping MIDI events at closing multiple ports + +From: Takashi Iwai + +[ 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 +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 +Signed-off-by: Sasha Levin +--- + sound/usb/midi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/usb/midi.c b/sound/usb/midi.c +index 737dd00e97b14..779d97d31f170 100644 +--- a/sound/usb/midi.c ++++ b/sound/usb/midi.c +@@ -1145,7 +1145,7 @@ static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) + { + struct usbmidi_out_port *port = substream->runtime->private_data; + +- cancel_work_sync(&port->ep->work); ++ flush_work(&port->ep->work); + return substream_open(substream, 0, 0); + } + +-- +2.39.5 + diff --git a/queue-6.13/asoc-cs35l56-prevent-races-when-soft-resetting-using.patch b/queue-6.13/asoc-cs35l56-prevent-races-when-soft-resetting-using.patch new file mode 100644 index 0000000000..b7a9a0675f --- /dev/null +++ b/queue-6.13/asoc-cs35l56-prevent-races-when-soft-resetting-using.patch @@ -0,0 +1,262 @@ +From bd61ecb35f3ede3b6b6a91f56232a6113c4fbcfd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Feb 2025 13:18:43 +0000 +Subject: ASoC: cs35l56: Prevent races when soft-resetting using SPI control + +From: Richard Fitzgerald + +[ 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 +Link: https://patch.msgid.link/20250225131843.113752-3-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 + #include + #include ++#include + #include + + #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 + #include + #include ++#include + #include + #include + +@@ -303,6 +304,79 @@ void cs35l56_wait_min_reset_pulse(void) + } + EXPORT_SYMBOL_NS_GPL(cs35l56_wait_min_reset_pulse, "SND_SOC_CS35L56_SHARED"); + ++static const struct { ++ u32 addr; ++ u32 value; ++} cs35l56_spi_system_reset_stages[] = { ++ { .addr = CS35L56_DSP_VIRTUAL1_MBOX_1, .value = CS35L56_MBOX_CMD_SYSTEM_RESET }, ++ /* The next write is necessary to delimit the soft reset */ ++ { .addr = CS35L56_DSP_MBOX_1_RAW, .value = CS35L56_MBOX_CMD_PING }, ++}; ++ ++static void cs35l56_spi_issue_bus_locked_reset(struct cs35l56_base *cs35l56_base, ++ struct spi_device *spi) ++{ ++ struct cs35l56_spi_payload *buf = cs35l56_base->spi_payload_buf; ++ struct spi_transfer t = { ++ .tx_buf = buf, ++ .len = sizeof(*buf), ++ }; ++ struct spi_message m; ++ int i, ret; ++ ++ for (i = 0; i < ARRAY_SIZE(cs35l56_spi_system_reset_stages); i++) { ++ buf->addr = cpu_to_be32(cs35l56_spi_system_reset_stages[i].addr); ++ buf->value = cpu_to_be32(cs35l56_spi_system_reset_stages[i].value); ++ spi_message_init_with_transfers(&m, &t, 1); ++ ret = spi_sync_locked(spi, &m); ++ if (ret) ++ dev_warn(cs35l56_base->dev, "spi_sync failed: %d\n", ret); ++ ++ usleep_range(CS35L56_SPI_RESET_TO_PORT_READY_US, ++ 2 * CS35L56_SPI_RESET_TO_PORT_READY_US); ++ } ++} ++ ++static void cs35l56_spi_system_reset(struct cs35l56_base *cs35l56_base) ++{ ++ struct spi_device *spi = to_spi_device(cs35l56_base->dev); ++ unsigned int val; ++ int read_ret, ret; ++ ++ /* ++ * There must not be any other SPI bus activity while the amp is ++ * soft-resetting. ++ */ ++ ret = spi_bus_lock(spi->controller); ++ if (ret) { ++ dev_warn(cs35l56_base->dev, "spi_bus_lock failed: %d\n", ret); ++ return; ++ } ++ ++ cs35l56_spi_issue_bus_locked_reset(cs35l56_base, spi); ++ spi_bus_unlock(spi->controller); ++ ++ /* ++ * Check firmware boot by testing for a response in MBOX_2. ++ * HALO_STATE cannot be trusted yet because the reset sequence ++ * can leave it with stale state. But MBOX is reset. ++ * The regmap must remain in cache-only until the chip has ++ * booted, so use a bypassed read. ++ */ ++ ret = read_poll_timeout(regmap_read_bypassed, read_ret, ++ (val > 0) && (val < 0xffffffff), ++ CS35L56_HALO_STATE_POLL_US, ++ CS35L56_HALO_STATE_TIMEOUT_US, ++ false, ++ cs35l56_base->regmap, ++ CS35L56_DSP_VIRTUAL1_MBOX_2, ++ &val); ++ if (ret) { ++ dev_err(cs35l56_base->dev, "SPI reboot timed out(%d): MBOX2=%#x\n", ++ read_ret, val); ++ } ++} ++ + static const struct reg_sequence cs35l56_system_reset_seq[] = { + REG_SEQ0(CS35L56_DSP1_HALO_STATE, 0), + REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_SYSTEM_RESET), +@@ -315,6 +389,12 @@ void cs35l56_system_reset(struct cs35l56_base *cs35l56_base, bool is_soundwire) + * accesses other than the controlled system reset sequence below. + */ + regcache_cache_only(cs35l56_base->regmap, true); ++ ++ if (cs35l56_is_spi(cs35l56_base)) { ++ cs35l56_spi_system_reset(cs35l56_base); ++ return; ++ } ++ + regmap_multi_reg_write_bypassed(cs35l56_base->regmap, + cs35l56_system_reset_seq, + ARRAY_SIZE(cs35l56_system_reset_seq)); +diff --git a/sound/soc/codecs/cs35l56-spi.c b/sound/soc/codecs/cs35l56-spi.c +index c101134e85328..ca6c03a8766d3 100644 +--- a/sound/soc/codecs/cs35l56-spi.c ++++ b/sound/soc/codecs/cs35l56-spi.c +@@ -33,6 +33,9 @@ static int cs35l56_spi_probe(struct spi_device *spi) + + cs35l56->base.dev = &spi->dev; + cs35l56->base.can_hibernate = true; ++ ret = cs35l56_init_config_for_spi(&cs35l56->base, spi); ++ if (ret) ++ return ret; + + ret = cs35l56_common_probe(cs35l56); + if (ret != 0) +-- +2.39.5 + diff --git a/queue-6.13/asoc-es8328-fix-route-from-dac-to-output.patch b/queue-6.13/asoc-es8328-fix-route-from-dac-to-output.patch new file mode 100644 index 0000000000..dfc74aed23 --- /dev/null +++ b/queue-6.13/asoc-es8328-fix-route-from-dac-to-output.patch @@ -0,0 +1,110 @@ +From e4aaed126e112579a27687674e6fa2e556f6acc5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Feb 2025 20:39:57 +0100 +Subject: ASoC: es8328: fix route from DAC to output + +From: Nicolas Frattaroli + +[ 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 +Link: https://patch.msgid.link/20250222-es8328-route-bludgeoning-v1-1-99bfb7fb22d9@collabora.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/es8328.c | 15 ++++----------- + 1 file changed, 4 insertions(+), 11 deletions(-) + +diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c +index f3c97da798dc8..76159c45e6b52 100644 +--- a/sound/soc/codecs/es8328.c ++++ b/sound/soc/codecs/es8328.c +@@ -233,7 +233,6 @@ static const struct snd_kcontrol_new es8328_right_line_controls = + + /* Left Mixer */ + static const struct snd_kcontrol_new es8328_left_mixer_controls[] = { +- SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL17, 7, 1, 0), + SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL17, 6, 1, 0), + SOC_DAPM_SINGLE("Right Playback Switch", ES8328_DACCONTROL18, 7, 1, 0), + SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL18, 6, 1, 0), +@@ -243,7 +242,6 @@ static const struct snd_kcontrol_new es8328_left_mixer_controls[] = { + static const struct snd_kcontrol_new es8328_right_mixer_controls[] = { + SOC_DAPM_SINGLE("Left Playback Switch", ES8328_DACCONTROL19, 7, 1, 0), + SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL19, 6, 1, 0), +- SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL20, 7, 1, 0), + SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL20, 6, 1, 0), + }; + +@@ -336,10 +334,10 @@ static const struct snd_soc_dapm_widget es8328_dapm_widgets[] = { + SND_SOC_DAPM_DAC("Left DAC", "Left Playback", ES8328_DACPOWER, + ES8328_DACPOWER_LDAC_OFF, 1), + +- SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0, ++ SND_SOC_DAPM_MIXER("Left Mixer", ES8328_DACCONTROL17, 7, 0, + &es8328_left_mixer_controls[0], + ARRAY_SIZE(es8328_left_mixer_controls)), +- SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0, ++ SND_SOC_DAPM_MIXER("Right Mixer", ES8328_DACCONTROL20, 7, 0, + &es8328_right_mixer_controls[0], + ARRAY_SIZE(es8328_right_mixer_controls)), + +@@ -418,19 +416,14 @@ static const struct snd_soc_dapm_route es8328_dapm_routes[] = { + { "Right Line Mux", "PGA", "Right PGA Mux" }, + { "Right Line Mux", "Differential", "Differential Mux" }, + +- { "Left Out 1", NULL, "Left DAC" }, +- { "Right Out 1", NULL, "Right DAC" }, +- { "Left Out 2", NULL, "Left DAC" }, +- { "Right Out 2", NULL, "Right DAC" }, +- +- { "Left Mixer", "Playback Switch", "Left DAC" }, ++ { "Left Mixer", NULL, "Left DAC" }, + { "Left Mixer", "Left Bypass Switch", "Left Line Mux" }, + { "Left Mixer", "Right Playback Switch", "Right DAC" }, + { "Left Mixer", "Right Bypass Switch", "Right Line Mux" }, + + { "Right Mixer", "Left Playback Switch", "Left DAC" }, + { "Right Mixer", "Left Bypass Switch", "Left Line Mux" }, +- { "Right Mixer", "Playback Switch", "Right DAC" }, ++ { "Right Mixer", NULL, "Right DAC" }, + { "Right Mixer", "Right Bypass Switch", "Right Line Mux" }, + + { "DAC DIG", NULL, "DAC STM" }, +-- +2.39.5 + diff --git a/queue-6.13/asoc-fsl-rename-stream-name-of-sai-dai-driver.patch b/queue-6.13/asoc-fsl-rename-stream-name-of-sai-dai-driver.patch new file mode 100644 index 0000000000..b2c4d99c3d --- /dev/null +++ b/queue-6.13/asoc-fsl-rename-stream-name-of-sai-dai-driver.patch @@ -0,0 +1,73 @@ +From 7eb06a2553be9496c4b604bd6a8ab0ea82dcddde Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Feb 2025 10:04:37 +0900 +Subject: ASoC: fsl: Rename stream name of SAI DAI driver + +From: Chancel Liu + +[ 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 +Acked-by: Shengjiu Wang +Link: https://patch.msgid.link/20250217010437.258621-1-chancel.liu@nxp.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_sai.c | 6 +++--- + sound/soc/fsl/imx-audmix.c | 4 ++-- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c +index 634168d2bb6e5..c5efbceb06d1f 100644 +--- a/sound/soc/fsl/fsl_sai.c ++++ b/sound/soc/fsl/fsl_sai.c +@@ -994,10 +994,10 @@ static struct snd_soc_dai_driver fsl_sai_dai_template[] = { + { + .name = "sai-tx", + .playback = { +- .stream_name = "CPU-Playback", ++ .stream_name = "SAI-Playback", + .channels_min = 1, + .channels_max = 32, +- .rate_min = 8000, ++ .rate_min = 8000, + .rate_max = 2822400, + .rates = SNDRV_PCM_RATE_KNOT, + .formats = FSL_SAI_FORMATS, +@@ -1007,7 +1007,7 @@ static struct snd_soc_dai_driver fsl_sai_dai_template[] = { + { + .name = "sai-rx", + .capture = { +- .stream_name = "CPU-Capture", ++ .stream_name = "SAI-Capture", + .channels_min = 1, + .channels_max = 32, + .rate_min = 8000, +diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c +index 50ecc5f51100e..dac5d4ddacd6e 100644 +--- a/sound/soc/fsl/imx-audmix.c ++++ b/sound/soc/fsl/imx-audmix.c +@@ -119,8 +119,8 @@ static const struct snd_soc_ops imx_audmix_be_ops = { + static const char *name[][3] = { + {"HiFi-AUDMIX-FE-0", "HiFi-AUDMIX-FE-1", "HiFi-AUDMIX-FE-2"}, + {"sai-tx", "sai-tx", "sai-rx"}, +- {"AUDMIX-Playback-0", "AUDMIX-Playback-1", "CPU-Capture"}, +- {"CPU-Playback", "CPU-Playback", "AUDMIX-Capture-0"}, ++ {"AUDMIX-Playback-0", "AUDMIX-Playback-1", "SAI-Capture"}, ++ {"SAI-Playback", "SAI-Playback", "AUDMIX-Capture-0"}, + }; + + static int imx_audmix_probe(struct platform_device *pdev) +-- +2.39.5 + diff --git a/queue-6.13/bluetooth-l2cap-fix-l2cap_ecred_conn_rsp-response.patch b/queue-6.13/bluetooth-l2cap-fix-l2cap_ecred_conn_rsp-response.patch new file mode 100644 index 0000000000..7864a67bd2 --- /dev/null +++ b/queue-6.13/bluetooth-l2cap-fix-l2cap_ecred_conn_rsp-response.patch @@ -0,0 +1,99 @@ +From e60fc1ffd3e8c32ef4df122e2097c2ab408fa2f7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Feb 2025 10:30:25 -0500 +Subject: Bluetooth: L2CAP: Fix L2CAP_ECRED_CONN_RSP response + +From: Luiz Augusto von Dentz + +[ 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 +Signed-off-by: Sasha Levin +--- + net/bluetooth/l2cap_core.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index 27b4c4a2ba1fd..728a5ce9b5058 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -636,7 +636,8 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) + test_bit(FLAG_HOLD_HCI_CONN, &chan->flags)) + hci_conn_hold(conn->hcon); + +- list_add(&chan->list, &conn->chan_l); ++ /* Append to the list since the order matters for ECRED */ ++ list_add_tail(&chan->list, &conn->chan_l); + } + + void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) +@@ -3776,7 +3777,11 @@ static void l2cap_ecred_rsp_defer(struct l2cap_chan *chan, void *data) + struct l2cap_ecred_conn_rsp *rsp_flex = + container_of(&rsp->pdu.rsp, struct l2cap_ecred_conn_rsp, hdr); + +- if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags)) ++ /* Check if channel for outgoing connection or if it wasn't deferred ++ * since in those cases it must be skipped. ++ */ ++ if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags) || ++ !test_and_clear_bit(FLAG_DEFER_SETUP, &chan->flags)) + return; + + /* Reset ident so only one response is sent */ +-- +2.39.5 + diff --git a/queue-6.13/drm-amd-display-restore-edid-reading-from-a-given-i2.patch b/queue-6.13/drm-amd-display-restore-edid-reading-from-a-given-i2.patch new file mode 100644 index 0000000000..4d9683165c --- /dev/null +++ b/queue-6.13/drm-amd-display-restore-edid-reading-from-a-given-i2.patch @@ -0,0 +1,78 @@ +From bcef80708907e45c302cfc7c1890f62df0d22d77 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Feb 2025 18:15:47 -0300 +Subject: drm/amd/display: restore edid reading from a given i2c adapter + +From: Melissa Wen + +[ 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 +CC: Mario Limonciello +CC: Roman Li +CC: Aurabindo Pillai +Fixes: 48edb2a4256e ("drm/amd/display: switch amdgpu_dm_connector to use struct drm_edid") +Reviewed-by: Alex Hung +Signed-off-by: Melissa Wen +Signed-off-by: Alex Deucher +(cherry picked from commit 81262b1656feb3813e3d917ab78824df6831e69e) +Signed-off-by: Sasha Levin +--- + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index f7c0d7625ff12..35b9e026fe0d5 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -7180,8 +7180,14 @@ static void amdgpu_dm_connector_funcs_force(struct drm_connector *connector) + struct dc_link *dc_link = aconnector->dc_link; + struct dc_sink *dc_em_sink = aconnector->dc_em_sink; + const struct drm_edid *drm_edid; ++ struct i2c_adapter *ddc; + +- drm_edid = drm_edid_read(connector); ++ if (dc_link && dc_link->aux_mode) ++ ddc = &aconnector->dm_dp_aux.aux.ddc; ++ else ++ ddc = &aconnector->i2c->base; ++ ++ drm_edid = drm_edid_read_ddc(connector, ddc); + drm_edid_connector_update(connector, drm_edid); + if (!drm_edid) { + DRM_ERROR("No EDID found on connector: %s.\n", connector->name); +@@ -7226,14 +7232,21 @@ static int get_modes(struct drm_connector *connector) + static void create_eml_sink(struct amdgpu_dm_connector *aconnector) + { + struct drm_connector *connector = &aconnector->base; ++ struct dc_link *dc_link = aconnector->dc_link; + struct dc_sink_init_data init_params = { + .link = aconnector->dc_link, + .sink_signal = SIGNAL_TYPE_VIRTUAL + }; + const struct drm_edid *drm_edid; + const struct edid *edid; ++ struct i2c_adapter *ddc; ++ ++ if (dc_link && dc_link->aux_mode) ++ ddc = &aconnector->dm_dp_aux.aux.ddc; ++ else ++ ddc = &aconnector->i2c->base; + +- drm_edid = drm_edid_read(connector); ++ drm_edid = drm_edid_read_ddc(connector, ddc); + drm_edid_connector_update(connector, drm_edid); + if (!drm_edid) { + DRM_ERROR("No EDID found on connector: %s.\n", connector->name); +-- +2.39.5 + diff --git a/queue-6.13/drm-amdgpu-gfx-only-call-mes-for-enforce-isolation-i.patch b/queue-6.13/drm-amdgpu-gfx-only-call-mes-for-enforce-isolation-i.patch new file mode 100644 index 0000000000..b333e495c5 --- /dev/null +++ b/queue-6.13/drm-amdgpu-gfx-only-call-mes-for-enforce-isolation-i.patch @@ -0,0 +1,46 @@ +From c3b184cf4e4097a0de16a031a2fd729a25d6c34d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Feb 2025 13:37:01 -0500 +Subject: drm/amdgpu/gfx: only call mes for enforce isolation if supported + +From: Alex Deucher + +[ 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 +Signed-off-by: Alex Deucher +Cc: Shaoyun Liu +Cc: Srinivasan Shanmugam +(cherry picked from commit 80513e389765c8f9543b26d8fa4bbdf0e59ff8bc) +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +index 9a4dad3e41529..11aa55bd16d28 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +@@ -1598,11 +1598,13 @@ static ssize_t amdgpu_gfx_set_enforce_isolation(struct device *dev, + if (adev->enforce_isolation[i] && !partition_values[i]) { + /* Going from enabled to disabled */ + amdgpu_vmid_free_reserved(adev, AMDGPU_GFXHUB(i)); +- amdgpu_mes_set_enforce_isolation(adev, i, false); ++ if (adev->enable_mes && adev->gfx.enable_cleaner_shader) ++ amdgpu_mes_set_enforce_isolation(adev, i, false); + } else if (!adev->enforce_isolation[i] && partition_values[i]) { + /* Going from disabled to enabled */ + amdgpu_vmid_alloc_reserved(adev, AMDGPU_GFXHUB(i)); +- amdgpu_mes_set_enforce_isolation(adev, i, true); ++ if (adev->enable_mes && adev->gfx.enable_cleaner_shader) ++ amdgpu_mes_set_enforce_isolation(adev, i, true); + } + adev->enforce_isolation[i] = partition_values[i]; + } +-- +2.39.5 + diff --git a/queue-6.13/drm-amdgpu-mes-keep-enforce-isolation-up-to-date.patch b/queue-6.13/drm-amdgpu-mes-keep-enforce-isolation-up-to-date.patch new file mode 100644 index 0000000000..adfbb90a3d --- /dev/null +++ b/queue-6.13/drm-amdgpu-mes-keep-enforce-isolation-up-to-date.patch @@ -0,0 +1,144 @@ +From 1b2b37bd3b5b1f5186314ff68706394fd254d336 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Feb 2025 12:32:30 -0500 +Subject: drm/amdgpu/mes: keep enforce isolation up to date + +From: Alex Deucher + +[ 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 +Signed-off-by: Alex Deucher +Cc: Shaoyun Liu +Cc: Srinivasan Shanmugam +Signed-off-by: Alex Deucher +(cherry picked from commit 27b791514789844e80da990c456c2465325e0851) +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 13 ++++--------- + drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 20 +++++++++++++++++++- + drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h | 2 +- + drivers/gpu/drm/amd/amdgpu/mes_v11_0.c | 4 ++++ + drivers/gpu/drm/amd/amdgpu/mes_v12_0.c | 4 ++++ + 5 files changed, 32 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +index 11aa55bd16d28..7ec35e3677585 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +@@ -1593,24 +1593,19 @@ static ssize_t amdgpu_gfx_set_enforce_isolation(struct device *dev, + } + + mutex_lock(&adev->enforce_isolation_mutex); +- + for (i = 0; i < num_partitions; i++) { +- if (adev->enforce_isolation[i] && !partition_values[i]) { ++ if (adev->enforce_isolation[i] && !partition_values[i]) + /* Going from enabled to disabled */ + amdgpu_vmid_free_reserved(adev, AMDGPU_GFXHUB(i)); +- if (adev->enable_mes && adev->gfx.enable_cleaner_shader) +- amdgpu_mes_set_enforce_isolation(adev, i, false); +- } else if (!adev->enforce_isolation[i] && partition_values[i]) { ++ else if (!adev->enforce_isolation[i] && partition_values[i]) + /* Going from disabled to enabled */ + amdgpu_vmid_alloc_reserved(adev, AMDGPU_GFXHUB(i)); +- if (adev->enable_mes && adev->gfx.enable_cleaner_shader) +- amdgpu_mes_set_enforce_isolation(adev, i, true); +- } + adev->enforce_isolation[i] = partition_values[i]; + } +- + mutex_unlock(&adev->enforce_isolation_mutex); + ++ amdgpu_mes_update_enforce_isolation(adev); ++ + return count; + } + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +index 59ec20b07a6af..452ca07e7e7d2 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +@@ -1679,7 +1679,8 @@ bool amdgpu_mes_suspend_resume_all_supported(struct amdgpu_device *adev) + } + + /* Fix me -- node_id is used to identify the correct MES instances in the future */ +-int amdgpu_mes_set_enforce_isolation(struct amdgpu_device *adev, uint32_t node_id, bool enable) ++static int amdgpu_mes_set_enforce_isolation(struct amdgpu_device *adev, ++ uint32_t node_id, bool enable) + { + struct mes_misc_op_input op_input = {0}; + int r; +@@ -1701,6 +1702,23 @@ int amdgpu_mes_set_enforce_isolation(struct amdgpu_device *adev, uint32_t node_i + return r; + } + ++int amdgpu_mes_update_enforce_isolation(struct amdgpu_device *adev) ++{ ++ int i, r = 0; ++ ++ if (adev->enable_mes && adev->gfx.enable_cleaner_shader) { ++ mutex_lock(&adev->enforce_isolation_mutex); ++ for (i = 0; i < (adev->xcp_mgr ? adev->xcp_mgr->num_xcps : 1); i++) { ++ if (adev->enforce_isolation[i]) ++ r |= amdgpu_mes_set_enforce_isolation(adev, i, true); ++ else ++ r |= amdgpu_mes_set_enforce_isolation(adev, i, false); ++ } ++ mutex_unlock(&adev->enforce_isolation_mutex); ++ } ++ return r; ++} ++ + #if defined(CONFIG_DEBUG_FS) + + static int amdgpu_debugfs_mes_event_log_show(struct seq_file *m, void *unused) +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h +index c6f93cbd6739f..f089c5087c63d 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h +@@ -534,6 +534,6 @@ static inline void amdgpu_mes_unlock(struct amdgpu_mes *mes) + + bool amdgpu_mes_suspend_resume_all_supported(struct amdgpu_device *adev); + +-int amdgpu_mes_set_enforce_isolation(struct amdgpu_device *adev, uint32_t node_id, bool enable); ++int amdgpu_mes_update_enforce_isolation(struct amdgpu_device *adev); + + #endif /* __AMDGPU_MES_H__ */ +diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c +index 9c905b9e93763..40750e5478efb 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c +@@ -1635,6 +1635,10 @@ static int mes_v11_0_hw_init(struct amdgpu_ip_block *ip_block) + goto failure; + } + ++ r = amdgpu_mes_update_enforce_isolation(adev); ++ if (r) ++ goto failure; ++ + out: + /* + * Disable KIQ ring usage from the driver once MES is enabled. +diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c +index 9ecc5d61e49ba..0921fd8c050da 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c +@@ -1590,6 +1590,10 @@ static int mes_v12_0_hw_init(struct amdgpu_ip_block *ip_block) + goto failure; + } + ++ r = amdgpu_mes_update_enforce_isolation(adev); ++ if (r) ++ goto failure; ++ + out: + /* + * Disable KIQ ring usage from the driver once MES is enabled. +-- +2.39.5 + diff --git a/queue-6.13/drm-xe-cancel-pending-job-timer-before-freeing-sched.patch b/queue-6.13/drm-xe-cancel-pending-job-timer-before-freeing-sched.patch new file mode 100644 index 0000000000..ef75d67ee7 --- /dev/null +++ b/queue-6.13/drm-xe-cancel-pending-job-timer-before-freeing-sched.patch @@ -0,0 +1,47 @@ +From 2a58a4edc3e927fd355744e285ba6cbb47f782f2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Feb 2025 10:27:54 +0530 +Subject: drm/xe: cancel pending job timer before freeing scheduler + +From: Tejas Upadhyay + +[ 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 +Link: https://patchwork.freedesktop.org/patch/msgid/20250225045754.600905-1-tejas.upadhyay@intel.com +Signed-off-by: Tejas Upadhyay +(cherry picked from commit 18fbd567e75f9b97b699b2ab4f1fa76b7cf268f6) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_guc_submit.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c +index 6f4a9812b4f4a..fe17e9ba86725 100644 +--- a/drivers/gpu/drm/xe/xe_guc_submit.c ++++ b/drivers/gpu/drm/xe/xe_guc_submit.c +@@ -1238,6 +1238,8 @@ static void __guc_exec_queue_fini_async(struct work_struct *w) + + if (xe_exec_queue_is_lr(q)) + cancel_work_sync(&ge->lr_tdr); ++ /* Confirm no work left behind accessing device structures */ ++ cancel_delayed_work_sync(&ge->sched.base.work_tdr); + release_guc_id(guc, q); + xe_sched_entity_fini(&ge->entity); + xe_sched_fini(&ge->sched); +-- +2.39.5 + diff --git a/queue-6.13/drm-xe-oa-allow-oa_exponent-value-of-0.patch b/queue-6.13/drm-xe-oa-allow-oa_exponent-value-of-0.patch new file mode 100644 index 0000000000..51885b5904 --- /dev/null +++ b/queue-6.13/drm-xe-oa-allow-oa_exponent-value-of-0.patch @@ -0,0 +1,61 @@ +From 26071e9a2703203d9d6d40b3e5eb6a49c6387b56 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Feb 2025 13:33:52 -0800 +Subject: drm/xe/oa: Allow oa_exponent value of 0 + +From: Umesh Nerlige Ramappa + +[ 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 +Reviewed-by: Ashutosh Dixit +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 +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.13/firmware-cs_dsp-remove-async-regmap-writes.patch b/queue-6.13/firmware-cs_dsp-remove-async-regmap-writes.patch new file mode 100644 index 0000000000..343c450ac6 --- /dev/null +++ b/queue-6.13/firmware-cs_dsp-remove-async-regmap-writes.patch @@ -0,0 +1,115 @@ +From 347da59265413523299cd3c973c408c9cbb49da3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Feb 2025 13:18:42 +0000 +Subject: firmware: cs_dsp: Remove async regmap writes + +From: Richard Fitzgerald + +[ 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 +Link: https://patch.msgid.link/20250225131843.113752-2-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/firmware/cirrus/cs_dsp.c | 24 ++++++------------------ + 1 file changed, 6 insertions(+), 18 deletions(-) + +diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c +index 5365e9a430007..42433c19eb308 100644 +--- a/drivers/firmware/cirrus/cs_dsp.c ++++ b/drivers/firmware/cirrus/cs_dsp.c +@@ -1609,8 +1609,8 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, + goto out_fw; + } + +- ret = regmap_raw_write_async(regmap, reg, buf->buf, +- le32_to_cpu(region->len)); ++ ret = regmap_raw_write(regmap, reg, buf->buf, ++ le32_to_cpu(region->len)); + if (ret != 0) { + cs_dsp_err(dsp, + "%s.%d: Failed to write %d bytes at %d in %s: %d\n", +@@ -1625,12 +1625,6 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, + regions++; + } + +- ret = regmap_async_complete(regmap); +- if (ret != 0) { +- cs_dsp_err(dsp, "Failed to complete async write: %d\n", ret); +- goto out_fw; +- } +- + if (pos > firmware->size) + cs_dsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", + file, regions, pos - firmware->size); +@@ -1638,7 +1632,6 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, + cs_dsp_debugfs_save_wmfwname(dsp, file); + + out_fw: +- regmap_async_complete(regmap); + cs_dsp_buf_free(&buf_list); + + if (ret == -EOVERFLOW) +@@ -2326,8 +2319,8 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware + cs_dsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", + file, blocks, le32_to_cpu(blk->len), + reg); +- ret = regmap_raw_write_async(regmap, reg, buf->buf, +- le32_to_cpu(blk->len)); ++ ret = regmap_raw_write(regmap, reg, buf->buf, ++ le32_to_cpu(blk->len)); + if (ret != 0) { + cs_dsp_err(dsp, + "%s.%d: Failed to write to %x in %s: %d\n", +@@ -2339,10 +2332,6 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware + blocks++; + } + +- ret = regmap_async_complete(regmap); +- if (ret != 0) +- cs_dsp_err(dsp, "Failed to complete async write: %d\n", ret); +- + if (pos > firmware->size) + cs_dsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", + file, blocks, pos - firmware->size); +@@ -2350,7 +2339,6 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware + cs_dsp_debugfs_save_binname(dsp, file); + + out_fw: +- regmap_async_complete(regmap); + cs_dsp_buf_free(&buf_list); + + if (ret == -EOVERFLOW) +@@ -2561,8 +2549,8 @@ static int cs_dsp_adsp2_enable_core(struct cs_dsp *dsp) + { + int ret; + +- ret = regmap_update_bits_async(dsp->regmap, dsp->base + ADSP2_CONTROL, +- ADSP2_SYS_ENA, ADSP2_SYS_ENA); ++ ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, ++ ADSP2_SYS_ENA, ADSP2_SYS_ENA); + if (ret != 0) + return ret; + +-- +2.39.5 + diff --git a/queue-6.13/ice-avoid-setting-default-rx-vsi-twice-in-switchdev-.patch b/queue-6.13/ice-avoid-setting-default-rx-vsi-twice-in-switchdev-.patch new file mode 100644 index 0000000000..93efb6abea --- /dev/null +++ b/queue-6.13/ice-avoid-setting-default-rx-vsi-twice-in-switchdev-.patch @@ -0,0 +1,57 @@ +From b49c57a78debdb2016c876aa52336c495fdfa654 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Feb 2025 11:06:42 -0800 +Subject: ice: Avoid setting default Rx VSI twice in switchdev setup + +From: Marcin Szycik + +[ 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 +Closes: https://lore.kernel.org/intel-wired-lan/PH0PR11MB50138B635F2E5CEB7075325D961F2@PH0PR11MB5013.namprd11.prod.outlook.com +Reviewed-by: Martyna Szapar-Mudlaw +Signed-off-by: Marcin Szycik +Reviewed-by: Simon Horman +Tested-by: Sujai Buvaneswaran +Signed-off-by: Tony Nguyen +Link: https://patch.msgid.link/20250224190647.3601930-3-anthony.l.nguyen@intel.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_eswitch.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_eswitch.c b/drivers/net/ethernet/intel/ice/ice_eswitch.c +index fb527434b58b1..d649c197cf673 100644 +--- a/drivers/net/ethernet/intel/ice/ice_eswitch.c ++++ b/drivers/net/ethernet/intel/ice/ice_eswitch.c +@@ -38,8 +38,7 @@ static int ice_eswitch_setup_env(struct ice_pf *pf) + if (ice_vsi_add_vlan_zero(uplink_vsi)) + goto err_vlan_zero; + +- if (ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx, true, +- ICE_FLTR_RX)) ++ if (ice_set_dflt_vsi(uplink_vsi)) + goto err_def_rx; + + if (ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx, true, +-- +2.39.5 + diff --git a/queue-6.13/ice-fix-deinitializing-vf-in-error-path.patch b/queue-6.13/ice-fix-deinitializing-vf-in-error-path.patch new file mode 100644 index 0000000000..e763bb656d --- /dev/null +++ b/queue-6.13/ice-fix-deinitializing-vf-in-error-path.patch @@ -0,0 +1,114 @@ +From d2945c3534674ea9a9b0d4efcab319f13e8471b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Feb 2025 11:06:41 -0800 +Subject: ice: Fix deinitializing VF in error path + +From: Marcin Szycik + +[ 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 +Closes: https://lore.kernel.org/intel-wired-lan/PH0PR11MB50138B635F2E5CEB7075325D961F2@PH0PR11MB5013.namprd11.prod.outlook.com +Reviewed-by: Martyna Szapar-Mudlaw +Signed-off-by: Marcin Szycik +Reviewed-by: Simon Horman +Tested-by: Sujai Buvaneswaran +Signed-off-by: Tony Nguyen +Link: https://patch.msgid.link/20250224190647.3601930-2-anthony.l.nguyen@intel.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_sriov.c | 5 +---- + drivers/net/ethernet/intel/ice/ice_vf_lib.c | 8 ++++++++ + drivers/net/ethernet/intel/ice/ice_vf_lib_private.h | 1 + + 3 files changed, 10 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c b/drivers/net/ethernet/intel/ice/ice_sriov.c +index b83f99c01d91b..8aabf7749aa5e 100644 +--- a/drivers/net/ethernet/intel/ice/ice_sriov.c ++++ b/drivers/net/ethernet/intel/ice/ice_sriov.c +@@ -36,6 +36,7 @@ static void ice_free_vf_entries(struct ice_pf *pf) + + hash_for_each_safe(vfs->table, bkt, tmp, vf, entry) { + hash_del_rcu(&vf->entry); ++ ice_deinitialize_vf_entry(vf); + ice_put_vf(vf); + } + } +@@ -193,10 +194,6 @@ void ice_free_vfs(struct ice_pf *pf) + wr32(hw, GLGEN_VFLRSTAT(reg_idx), BIT(bit_idx)); + } + +- /* clear malicious info since the VF is getting released */ +- if (!ice_is_feature_supported(pf, ICE_F_MBX_LIMIT)) +- list_del(&vf->mbx_info.list_entry); +- + mutex_unlock(&vf->cfg_lock); + } + +diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c +index c7c0c2f50c265..815ad0bfe8326 100644 +--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c ++++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c +@@ -1036,6 +1036,14 @@ void ice_initialize_vf_entry(struct ice_vf *vf) + mutex_init(&vf->cfg_lock); + } + ++void ice_deinitialize_vf_entry(struct ice_vf *vf) ++{ ++ struct ice_pf *pf = vf->pf; ++ ++ if (!ice_is_feature_supported(pf, ICE_F_MBX_LIMIT)) ++ list_del(&vf->mbx_info.list_entry); ++} ++ + /** + * ice_dis_vf_qs - Disable the VF queues + * @vf: pointer to the VF structure +diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib_private.h b/drivers/net/ethernet/intel/ice/ice_vf_lib_private.h +index 0c7e77c0a09fa..5392b04049862 100644 +--- a/drivers/net/ethernet/intel/ice/ice_vf_lib_private.h ++++ b/drivers/net/ethernet/intel/ice/ice_vf_lib_private.h +@@ -24,6 +24,7 @@ + #endif + + void ice_initialize_vf_entry(struct ice_vf *vf); ++void ice_deinitialize_vf_entry(struct ice_vf *vf); + void ice_dis_vf_qs(struct ice_vf *vf); + int ice_check_vf_init(struct ice_vf *vf); + enum virtchnl_status_code ice_err_to_virt_err(int err); +-- +2.39.5 + diff --git a/queue-6.13/idpf-fix-checksums-set-in-idpf_rx_rsc.patch b/queue-6.13/idpf-fix-checksums-set-in-idpf_rx_rsc.patch new file mode 100644 index 0000000000..cc4c7ceb5e --- /dev/null +++ b/queue-6.13/idpf-fix-checksums-set-in-idpf_rx_rsc.patch @@ -0,0 +1,80 @@ +From e59d82870b3199b2b8ec9eb97437244c0ff63c32 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Feb 2025 22:12:52 +0000 +Subject: idpf: fix checksums set in idpf_rx_rsc() + +From: Eric Dumazet + +[ 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 +Cc: Alan Brady +Cc: Joshua Hay +Cc: Willem de Bruijn +Acked-by: Przemek Kitszel +Link: https://patch.msgid.link/20250226221253.1927782-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/idpf/idpf_txrx.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c +index 9be6a6b59c4e1..977741c414980 100644 +--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c ++++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c +@@ -3013,7 +3013,6 @@ static int idpf_rx_rsc(struct idpf_rx_queue *rxq, struct sk_buff *skb, + skb_shinfo(skb)->gso_size = rsc_seg_len; + + skb_reset_network_header(skb); +- len = skb->len - skb_transport_offset(skb); + + if (ipv4) { + struct iphdr *ipv4h = ip_hdr(skb); +@@ -3022,6 +3021,7 @@ static int idpf_rx_rsc(struct idpf_rx_queue *rxq, struct sk_buff *skb, + + /* Reset and set transport header offset in skb */ + skb_set_transport_header(skb, sizeof(struct iphdr)); ++ len = skb->len - skb_transport_offset(skb); + + /* Compute the TCP pseudo header checksum*/ + tcp_hdr(skb)->check = +@@ -3031,6 +3031,7 @@ static int idpf_rx_rsc(struct idpf_rx_queue *rxq, struct sk_buff *skb, + + skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; + skb_set_transport_header(skb, sizeof(struct ipv6hdr)); ++ len = skb->len - skb_transport_offset(skb); + tcp_hdr(skb)->check = + ~tcp_v6_check(len, &ipv6h->saddr, &ipv6h->daddr, 0); + } +-- +2.39.5 + diff --git a/queue-6.13/ipvlan-ensure-network-headers-are-in-skb-linear-part.patch b/queue-6.13/ipvlan-ensure-network-headers-are-in-skb-linear-part.patch new file mode 100644 index 0000000000..685e98c04d --- /dev/null +++ b/queue-6.13/ipvlan-ensure-network-headers-are-in-skb-linear-part.patch @@ -0,0 +1,113 @@ +From 2d30c17242d05c5a176e1554c6e8e30c3e9927a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Feb 2025 15:53:36 +0000 +Subject: ipvlan: ensure network headers are in skb linear part + +From: Eric Dumazet + +[ 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 +Cc: Mahesh Bandewar +Link: https://patch.msgid.link/20250220155336.61884-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ipvlan/ipvlan_core.c | 21 ++++++++++++++++----- + 1 file changed, 16 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c +index fd591ddb3884d..ca62188a317ad 100644 +--- a/drivers/net/ipvlan/ipvlan_core.c ++++ b/drivers/net/ipvlan/ipvlan_core.c +@@ -416,20 +416,25 @@ struct ipvl_addr *ipvlan_addr_lookup(struct ipvl_port *port, void *lyr3h, + + static noinline_for_stack int ipvlan_process_v4_outbound(struct sk_buff *skb) + { +- const struct iphdr *ip4h = ip_hdr(skb); + struct net_device *dev = skb->dev; + struct net *net = dev_net(dev); +- struct rtable *rt; + int err, ret = NET_XMIT_DROP; ++ const struct iphdr *ip4h; ++ struct rtable *rt; + struct flowi4 fl4 = { + .flowi4_oif = dev->ifindex, +- .flowi4_tos = inet_dscp_to_dsfield(ip4h_dscp(ip4h)), + .flowi4_flags = FLOWI_FLAG_ANYSRC, + .flowi4_mark = skb->mark, +- .daddr = ip4h->daddr, +- .saddr = ip4h->saddr, + }; + ++ if (!pskb_network_may_pull(skb, sizeof(struct iphdr))) ++ goto err; ++ ++ ip4h = ip_hdr(skb); ++ fl4.daddr = ip4h->daddr; ++ fl4.saddr = ip4h->saddr; ++ fl4.flowi4_tos = inet_dscp_to_dsfield(ip4h_dscp(ip4h)); ++ + rt = ip_route_output_flow(net, &fl4, NULL); + if (IS_ERR(rt)) + goto err; +@@ -488,6 +493,12 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) + struct net_device *dev = skb->dev; + int err, ret = NET_XMIT_DROP; + ++ if (!pskb_network_may_pull(skb, sizeof(struct ipv6hdr))) { ++ DEV_STATS_INC(dev, tx_errors); ++ kfree_skb(skb); ++ return ret; ++ } ++ + err = ipvlan_route_v6_outbound(dev, skb); + if (unlikely(err)) { + DEV_STATS_INC(dev, tx_errors); +-- +2.39.5 + diff --git a/queue-6.13/ipvs-always-clear-ipvs_property-flag-in-skb_scrub_pa.patch b/queue-6.13/ipvs-always-clear-ipvs_property-flag-in-skb_scrub_pa.patch new file mode 100644 index 0000000000..48f967a870 --- /dev/null +++ b/queue-6.13/ipvs-always-clear-ipvs_property-flag-in-skb_scrub_pa.patch @@ -0,0 +1,51 @@ +From c0c4371ccb2db8c28dde88bcef0ab744b3f83885 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Feb 2025 11:35:18 +0800 +Subject: ipvs: Always clear ipvs_property flag in skb_scrub_packet() + +From: Philo Lu + +[ 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 +Acked-by: Julian Anastasov +Link: https://patch.msgid.link/20250222033518.126087-1-lulie@linux.alibaba.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/core/skbuff.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index f251a99f8d421..bed75273f8c47 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -6127,11 +6127,11 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet) + skb->offload_fwd_mark = 0; + skb->offload_l3_fwd_mark = 0; + #endif ++ ipvs_reset(skb); + + if (!xnet) + return; + +- ipvs_reset(skb); + skb->mark = 0; + skb_clear_tstamp(skb); + } +-- +2.39.5 + diff --git a/queue-6.13/net-add-net_passive_inc-and-net_passive_dec.patch b/queue-6.13/net-add-net_passive_inc-and-net_passive_dec.patch new file mode 100644 index 0000000000..9a230452e8 --- /dev/null +++ b/queue-6.13/net-add-net_passive_inc-and-net_passive_dec.patch @@ -0,0 +1,104 @@ +From 0015ab294f7fa831bcf05abf3c23f468b31f8d75 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Feb 2025 11:11:27 -0800 +Subject: net: Add net_passive_inc() and net_passive_dec(). + +From: Kuniyuki Iwashima + +[ 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 +Link: https://lore.kernel.org/netdev/CANn89i+oUCt2VGvrbrweniTendZFEh+nwS=uonc004-aPkWy-Q@mail.gmail.com/ +Signed-off-by: Kuniyuki Iwashima +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20250217191129.19967-2-kuniyu@amazon.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 5c70eb5c593d ("net: better track kernel sockets lifetime") +Signed-off-by: Sasha Levin +--- + include/net/net_namespace.h | 11 +++++++++++ + net/core/net_namespace.c | 8 ++++---- + 2 files changed, 15 insertions(+), 4 deletions(-) + +diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h +index 44be742cf4d60..47181fd749b25 100644 +--- a/include/net/net_namespace.h ++++ b/include/net/net_namespace.h +@@ -295,6 +295,7 @@ static inline int check_net(const struct net *net) + } + + void net_drop_ns(void *); ++void net_passive_dec(struct net *net); + + #else + +@@ -324,8 +325,18 @@ static inline int check_net(const struct net *net) + } + + #define net_drop_ns NULL ++ ++static inline void net_passive_dec(struct net *net) ++{ ++ refcount_dec(&net->passive); ++} + #endif + ++static inline void net_passive_inc(struct net *net) ++{ ++ refcount_inc(&net->passive); ++} ++ + /* Returns true if the netns initialization is completed successfully */ + static inline bool net_initialized(const struct net *net) + { +diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c +index b5cd3ae4f04cf..b71aa96eeee23 100644 +--- a/net/core/net_namespace.c ++++ b/net/core/net_namespace.c +@@ -464,7 +464,7 @@ static void net_complete_free(void) + + } + +-static void net_free(struct net *net) ++void net_passive_dec(struct net *net) + { + if (refcount_dec_and_test(&net->passive)) { + kfree(rcu_access_pointer(net->gen)); +@@ -482,7 +482,7 @@ void net_drop_ns(void *p) + struct net *net = (struct net *)p; + + if (net) +- net_free(net); ++ net_passive_dec(net); + } + + struct net *copy_net_ns(unsigned long flags, +@@ -523,7 +523,7 @@ struct net *copy_net_ns(unsigned long flags, + key_remove_domain(net->key_domain); + #endif + put_user_ns(user_ns); +- net_free(net); ++ net_passive_dec(net); + dec_ucounts: + dec_net_namespaces(ucounts); + return ERR_PTR(rv); +@@ -668,7 +668,7 @@ static void cleanup_net(struct work_struct *work) + key_remove_domain(net->key_domain); + #endif + put_user_ns(net->user_ns); +- net_free(net); ++ net_passive_dec(net); + } + } + +-- +2.39.5 + diff --git a/queue-6.13/net-better-track-kernel-sockets-lifetime.patch b/queue-6.13/net-better-track-kernel-sockets-lifetime.patch new file mode 100644 index 0000000000..79c84af47e --- /dev/null +++ b/queue-6.13/net-better-track-kernel-sockets-lifetime.patch @@ -0,0 +1,257 @@ +From 76fb3658ac3a5a75d7ed592418772e1caf98f736 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Feb 2025 13:18:54 +0000 +Subject: net: better track kernel sockets lifetime + +From: Eric Dumazet + +[ 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 +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20250220131854.4048077-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/sock.h | 1 + + net/core/sock.c | 27 ++++++++++++++++++++++----- + net/mptcp/subflow.c | 5 +---- + net/netlink/af_netlink.c | 10 ---------- + net/rds/tcp.c | 8 ++------ + net/smc/af_smc.c | 5 +---- + net/sunrpc/svcsock.c | 5 +---- + net/sunrpc/xprtsock.c | 8 ++------ + 8 files changed, 30 insertions(+), 39 deletions(-) + +diff --git a/include/net/sock.h b/include/net/sock.h +index 691ca7695d1db..d3efb581c2ff4 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -1750,6 +1750,7 @@ static inline bool sock_allow_reclassification(const struct sock *csk) + struct sock *sk_alloc(struct net *net, int family, gfp_t priority, + struct proto *prot, int kern); + void sk_free(struct sock *sk); ++void sk_net_refcnt_upgrade(struct sock *sk); + void sk_destruct(struct sock *sk); + struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority); + void sk_free_unlock_clone(struct sock *sk); +diff --git a/net/core/sock.c b/net/core/sock.c +index be84885f9290a..9d5dd99cc5817 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -2233,6 +2233,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority, + get_net_track(net, &sk->ns_tracker, priority); + sock_inuse_add(net, 1); + } else { ++ net_passive_inc(net); + __netns_tracker_alloc(net, &sk->ns_tracker, + false, priority); + } +@@ -2257,6 +2258,7 @@ EXPORT_SYMBOL(sk_alloc); + static void __sk_destruct(struct rcu_head *head) + { + struct sock *sk = container_of(head, struct sock, sk_rcu); ++ struct net *net = sock_net(sk); + struct sk_filter *filter; + + if (sk->sk_destruct) +@@ -2288,14 +2290,28 @@ static void __sk_destruct(struct rcu_head *head) + put_cred(sk->sk_peer_cred); + put_pid(sk->sk_peer_pid); + +- if (likely(sk->sk_net_refcnt)) +- put_net_track(sock_net(sk), &sk->ns_tracker); +- else +- __netns_tracker_free(sock_net(sk), &sk->ns_tracker, false); +- ++ if (likely(sk->sk_net_refcnt)) { ++ put_net_track(net, &sk->ns_tracker); ++ } else { ++ __netns_tracker_free(net, &sk->ns_tracker, false); ++ net_passive_dec(net); ++ } + sk_prot_free(sk->sk_prot_creator, sk); + } + ++void sk_net_refcnt_upgrade(struct sock *sk) ++{ ++ struct net *net = sock_net(sk); ++ ++ WARN_ON_ONCE(sk->sk_net_refcnt); ++ __netns_tracker_free(net, &sk->ns_tracker, false); ++ net_passive_dec(net); ++ sk->sk_net_refcnt = 1; ++ get_net_track(net, &sk->ns_tracker, GFP_KERNEL); ++ sock_inuse_add(net, 1); ++} ++EXPORT_SYMBOL_GPL(sk_net_refcnt_upgrade); ++ + void sk_destruct(struct sock *sk) + { + bool use_call_rcu = sock_flag(sk, SOCK_RCU_FREE); +@@ -2392,6 +2408,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) + * is not properly dismantling its kernel sockets at netns + * destroy time. + */ ++ net_passive_inc(sock_net(newsk)); + __netns_tracker_alloc(sock_net(newsk), &newsk->ns_tracker, + false, priority); + } +diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c +index fd021cf8286ef..dfcbef9c46246 100644 +--- a/net/mptcp/subflow.c ++++ b/net/mptcp/subflow.c +@@ -1772,10 +1772,7 @@ int mptcp_subflow_create_socket(struct sock *sk, unsigned short family, + * needs it. + * Update ns_tracker to current stack trace and refcounted tracker. + */ +- __netns_tracker_free(net, &sf->sk->ns_tracker, false); +- sf->sk->sk_net_refcnt = 1; +- get_net_track(net, &sf->sk->ns_tracker, GFP_KERNEL); +- sock_inuse_add(net, 1); ++ sk_net_refcnt_upgrade(sf->sk); + err = tcp_set_ulp(sf->sk, "mptcp"); + if (err) + goto err_free; +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index f4e7b5e4bb59f..e88a1ac160bc4 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -795,16 +795,6 @@ static int netlink_release(struct socket *sock) + + sock_prot_inuse_add(sock_net(sk), &netlink_proto, -1); + +- /* Because struct net might disappear soon, do not keep a pointer. */ +- if (!sk->sk_net_refcnt && sock_net(sk) != &init_net) { +- __netns_tracker_free(sock_net(sk), &sk->ns_tracker, false); +- /* Because of deferred_put_nlk_sk and use of work queue, +- * it is possible netns will be freed before this socket. +- */ +- sock_net_set(sk, &init_net); +- __netns_tracker_alloc(&init_net, &sk->ns_tracker, +- false, GFP_KERNEL); +- } + call_rcu(&nlk->rcu, deferred_put_nlk_sk); + return 0; + } +diff --git a/net/rds/tcp.c b/net/rds/tcp.c +index 0581c53e65170..3cc2f303bf786 100644 +--- a/net/rds/tcp.c ++++ b/net/rds/tcp.c +@@ -504,12 +504,8 @@ bool rds_tcp_tune(struct socket *sock) + release_sock(sk); + return false; + } +- /* Update ns_tracker to current stack trace and refcounted tracker */ +- __netns_tracker_free(net, &sk->ns_tracker, false); +- +- sk->sk_net_refcnt = 1; +- netns_tracker_alloc(net, &sk->ns_tracker, GFP_KERNEL); +- sock_inuse_add(net, 1); ++ sk_net_refcnt_upgrade(sk); ++ put_net(net); + } + rtn = net_generic(net, rds_tcp_netid); + if (rtn->sndbuf_size > 0) { +diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c +index ebc41a7b13dbe..ba834cefb1773 100644 +--- a/net/smc/af_smc.c ++++ b/net/smc/af_smc.c +@@ -3334,10 +3334,7 @@ int smc_create_clcsk(struct net *net, struct sock *sk, int family) + * which need net ref. + */ + sk = smc->clcsock->sk; +- __netns_tracker_free(net, &sk->ns_tracker, false); +- sk->sk_net_refcnt = 1; +- get_net_track(net, &sk->ns_tracker, GFP_KERNEL); +- sock_inuse_add(net, 1); ++ sk_net_refcnt_upgrade(sk); + return 0; + } + +diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c +index cb3bd12f5818b..72e5a01df3d35 100644 +--- a/net/sunrpc/svcsock.c ++++ b/net/sunrpc/svcsock.c +@@ -1541,10 +1541,7 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv, + newlen = error; + + if (protocol == IPPROTO_TCP) { +- __netns_tracker_free(net, &sock->sk->ns_tracker, false); +- sock->sk->sk_net_refcnt = 1; +- get_net_track(net, &sock->sk->ns_tracker, GFP_KERNEL); +- sock_inuse_add(net, 1); ++ sk_net_refcnt_upgrade(sock->sk); + if ((error = kernel_listen(sock, 64)) < 0) + goto bummer; + } +diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c +index 6b80b2aaf7639..83cc095846d35 100644 +--- a/net/sunrpc/xprtsock.c ++++ b/net/sunrpc/xprtsock.c +@@ -1941,12 +1941,8 @@ static struct socket *xs_create_sock(struct rpc_xprt *xprt, + goto out; + } + +- if (protocol == IPPROTO_TCP) { +- __netns_tracker_free(xprt->xprt_net, &sock->sk->ns_tracker, false); +- sock->sk->sk_net_refcnt = 1; +- get_net_track(xprt->xprt_net, &sock->sk->ns_tracker, GFP_KERNEL); +- sock_inuse_add(xprt->xprt_net, 1); +- } ++ if (protocol == IPPROTO_TCP) ++ sk_net_refcnt_upgrade(sock->sk); + + filp = sock_alloc_file(sock, O_NONBLOCK, NULL); + if (IS_ERR(filp)) +-- +2.39.5 + diff --git a/queue-6.13/net-cadence-macb-synchronize-stats-calculations.patch b/queue-6.13/net-cadence-macb-synchronize-stats-calculations.patch new file mode 100644 index 0000000000..87aecba3ee --- /dev/null +++ b/queue-6.13/net-cadence-macb-synchronize-stats-calculations.patch @@ -0,0 +1,115 @@ +From 11ad7012c85b7e870a6183cdb17b0f7d5911f5f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Feb 2025 11:29:50 -0500 +Subject: net: cadence: macb: Synchronize stats calculations + +From: Sean Anderson + +[ 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 +Link: https://patch.msgid.link/20250220162950.95941-1-sean.anderson@linux.dev +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/cadence/macb.h | 2 ++ + drivers/net/ethernet/cadence/macb_main.c | 12 ++++++++++-- + 2 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h +index 5740c98d8c9f0..2847278d9cd48 100644 +--- a/drivers/net/ethernet/cadence/macb.h ++++ b/drivers/net/ethernet/cadence/macb.h +@@ -1279,6 +1279,8 @@ struct macb { + struct clk *rx_clk; + struct clk *tsu_clk; + struct net_device *dev; ++ /* Protects hw_stats and ethtool_stats */ ++ spinlock_t stats_lock; + union { + struct macb_stats macb; + struct gem_stats gem; +diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c +index daa416fb1724e..af2debcaf7dcc 100644 +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -1987,10 +1987,12 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) + + if (status & MACB_BIT(ISR_ROVR)) { + /* We missed at least one packet */ ++ spin_lock(&bp->stats_lock); + if (macb_is_gem(bp)) + bp->hw_stats.gem.rx_overruns++; + else + bp->hw_stats.macb.rx_overruns++; ++ spin_unlock(&bp->stats_lock); + + if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) + queue_writel(queue, ISR, MACB_BIT(ISR_ROVR)); +@@ -3111,6 +3113,7 @@ static struct net_device_stats *gem_get_stats(struct macb *bp) + if (!netif_running(bp->dev)) + return nstat; + ++ spin_lock_irq(&bp->stats_lock); + gem_update_stats(bp); + + nstat->rx_errors = (hwstat->rx_frame_check_sequence_errors + +@@ -3140,6 +3143,7 @@ static struct net_device_stats *gem_get_stats(struct macb *bp) + nstat->tx_aborted_errors = hwstat->tx_excessive_collisions; + nstat->tx_carrier_errors = hwstat->tx_carrier_sense_errors; + nstat->tx_fifo_errors = hwstat->tx_underrun; ++ spin_unlock_irq(&bp->stats_lock); + + return nstat; + } +@@ -3147,12 +3151,13 @@ static struct net_device_stats *gem_get_stats(struct macb *bp) + static void gem_get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, u64 *data) + { +- struct macb *bp; ++ struct macb *bp = netdev_priv(dev); + +- bp = netdev_priv(dev); ++ spin_lock_irq(&bp->stats_lock); + gem_update_stats(bp); + memcpy(data, &bp->ethtool_stats, sizeof(u64) + * (GEM_STATS_LEN + QUEUE_STATS_LEN * MACB_MAX_QUEUES)); ++ spin_unlock_irq(&bp->stats_lock); + } + + static int gem_get_sset_count(struct net_device *dev, int sset) +@@ -3202,6 +3207,7 @@ static struct net_device_stats *macb_get_stats(struct net_device *dev) + return gem_get_stats(bp); + + /* read stats from hardware */ ++ spin_lock_irq(&bp->stats_lock); + macb_update_stats(bp); + + /* Convert HW stats into netdevice stats */ +@@ -3235,6 +3241,7 @@ static struct net_device_stats *macb_get_stats(struct net_device *dev) + nstat->tx_carrier_errors = hwstat->tx_carrier_errors; + nstat->tx_fifo_errors = hwstat->tx_underruns; + /* Don't know about heartbeat or window errors... */ ++ spin_unlock_irq(&bp->stats_lock); + + return nstat; + } +@@ -5106,6 +5113,7 @@ static int macb_probe(struct platform_device *pdev) + } + } + spin_lock_init(&bp->lock); ++ spin_lock_init(&bp->stats_lock); + + /* setup capabilities */ + macb_configure_caps(bp, macb_config); +-- +2.39.5 + diff --git a/queue-6.13/net-clear-old-fragment-checksum-value-in-napi_reuse_.patch b/queue-6.13/net-clear-old-fragment-checksum-value-in-napi_reuse_.patch new file mode 100644 index 0000000000..2f34cc96c8 --- /dev/null +++ b/queue-6.13/net-clear-old-fragment-checksum-value-in-napi_reuse_.patch @@ -0,0 +1,77 @@ +From 9301842d370999abe766148aaa2d144b679a4dca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Feb 2025 13:28:52 +0200 +Subject: net: Clear old fragment checksum value in napi_reuse_skb + +From: Mohammad Heib + +[ 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: + +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 + + +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 +Reviewed-by: Shannon Nelson +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20250225112852.2507709-1-mheib@redhat.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/gro.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/core/gro.c b/net/core/gro.c +index 78b320b631744..0ad549b07e039 100644 +--- a/net/core/gro.c ++++ b/net/core/gro.c +@@ -653,6 +653,7 @@ static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) + skb->pkt_type = PACKET_HOST; + + skb->encapsulation = 0; ++ skb->ip_summed = CHECKSUM_NONE; + skb_shinfo(skb)->gso_type = 0; + skb_shinfo(skb)->gso_size = 0; + if (unlikely(skb->slow_gro)) { +-- +2.39.5 + diff --git a/queue-6.13/net-dsa-rtl8366rb-fix-compilation-problem.patch b/queue-6.13/net-dsa-rtl8366rb-fix-compilation-problem.patch new file mode 100644 index 0000000000..31350195f9 --- /dev/null +++ b/queue-6.13/net-dsa-rtl8366rb-fix-compilation-problem.patch @@ -0,0 +1,684 @@ +From 15e3121b65d26934a530e85020b2851edd2fa1de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Feb 2025 19:48:15 +0100 +Subject: net: dsa: rtl8366rb: Fix compilation problem + +From: Linus Walleij + +[ 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 +Closes: https://lore.kernel.org/oe-kbuild-all/202502070525.xMUImayb-lkp@intel.com/ +Signed-off-by: Linus Walleij +Reviewed-by: Vladimir Oltean +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 ++#include ++#include ++#include "rtl83xx.h" ++#include "rtl8366rb.h" ++ ++static inline u32 rtl8366rb_led_group_port_mask(u8 led_group, u8 port) ++{ ++ switch (led_group) { ++ case 0: ++ return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port)); ++ case 1: ++ return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port)); ++ case 2: ++ return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port)); ++ case 3: ++ return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port)); ++ default: ++ return 0; ++ } ++} ++ ++static int rb8366rb_get_port_led(struct rtl8366rb_led *led) ++{ ++ struct realtek_priv *priv = led->priv; ++ u8 led_group = led->led_group; ++ u8 port_num = led->port_num; ++ int ret; ++ u32 val; ++ ++ ret = regmap_read(priv->map, RTL8366RB_LED_X_X_CTRL_REG(led_group), ++ &val); ++ if (ret) { ++ dev_err(priv->dev, "error reading LED on port %d group %d\n", ++ led_group, port_num); ++ return ret; ++ } ++ ++ return !!(val & rtl8366rb_led_group_port_mask(led_group, port_num)); ++} ++ ++static int rb8366rb_set_port_led(struct rtl8366rb_led *led, bool enable) ++{ ++ struct realtek_priv *priv = led->priv; ++ u8 led_group = led->led_group; ++ u8 port_num = led->port_num; ++ int ret; ++ ++ ret = regmap_update_bits(priv->map, ++ RTL8366RB_LED_X_X_CTRL_REG(led_group), ++ rtl8366rb_led_group_port_mask(led_group, ++ port_num), ++ enable ? 0xffff : 0); ++ if (ret) { ++ dev_err(priv->dev, "error updating LED on port %d group %d\n", ++ led_group, port_num); ++ return ret; ++ } ++ ++ /* Change the LED group to manual controlled LEDs if required */ ++ ret = rb8366rb_set_ledgroup_mode(priv, led_group, ++ RTL8366RB_LEDGROUP_FORCE); ++ ++ if (ret) { ++ dev_err(priv->dev, "error updating LED GROUP group %d\n", ++ led_group); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int ++rtl8366rb_cled_brightness_set_blocking(struct led_classdev *ldev, ++ enum led_brightness brightness) ++{ ++ struct rtl8366rb_led *led = container_of(ldev, struct rtl8366rb_led, ++ cdev); ++ ++ return rb8366rb_set_port_led(led, brightness == LED_ON); ++} ++ ++static int rtl8366rb_setup_led(struct realtek_priv *priv, struct dsa_port *dp, ++ struct fwnode_handle *led_fwnode) ++{ ++ struct rtl8366rb *rb = priv->chip_data; ++ struct led_init_data init_data = { }; ++ enum led_default_state state; ++ struct rtl8366rb_led *led; ++ u32 led_group; ++ int ret; ++ ++ ret = fwnode_property_read_u32(led_fwnode, "reg", &led_group); ++ if (ret) ++ return ret; ++ ++ if (led_group >= RTL8366RB_NUM_LEDGROUPS) { ++ dev_warn(priv->dev, "Invalid LED reg %d defined for port %d", ++ led_group, dp->index); ++ return -EINVAL; ++ } ++ ++ led = &rb->leds[dp->index][led_group]; ++ led->port_num = dp->index; ++ led->led_group = led_group; ++ led->priv = priv; ++ ++ state = led_init_default_state_get(led_fwnode); ++ switch (state) { ++ case LEDS_DEFSTATE_ON: ++ led->cdev.brightness = 1; ++ rb8366rb_set_port_led(led, 1); ++ break; ++ case LEDS_DEFSTATE_KEEP: ++ led->cdev.brightness = ++ rb8366rb_get_port_led(led); ++ break; ++ case LEDS_DEFSTATE_OFF: ++ default: ++ led->cdev.brightness = 0; ++ rb8366rb_set_port_led(led, 0); ++ } ++ ++ led->cdev.max_brightness = 1; ++ led->cdev.brightness_set_blocking = ++ rtl8366rb_cled_brightness_set_blocking; ++ init_data.fwnode = led_fwnode; ++ init_data.devname_mandatory = true; ++ ++ init_data.devicename = kasprintf(GFP_KERNEL, "Realtek-%d:0%d:%d", ++ dp->ds->index, dp->index, led_group); ++ if (!init_data.devicename) ++ return -ENOMEM; ++ ++ ret = devm_led_classdev_register_ext(priv->dev, &led->cdev, &init_data); ++ if (ret) { ++ dev_warn(priv->dev, "Failed to init LED %d for port %d", ++ led_group, dp->index); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++int rtl8366rb_setup_leds(struct realtek_priv *priv) ++{ ++ struct dsa_switch *ds = &priv->ds; ++ struct device_node *leds_np; ++ struct dsa_port *dp; ++ int ret = 0; ++ ++ dsa_switch_for_each_port(dp, ds) { ++ if (!dp->dn) ++ continue; ++ ++ leds_np = of_get_child_by_name(dp->dn, "leds"); ++ if (!leds_np) { ++ dev_dbg(priv->dev, "No leds defined for port %d", ++ dp->index); ++ continue; ++ } ++ ++ for_each_child_of_node_scoped(leds_np, led_np) { ++ ret = rtl8366rb_setup_led(priv, dp, ++ of_fwnode_handle(led_np)); ++ if (ret) ++ break; ++ } ++ ++ of_node_put(leds_np); ++ if (ret) ++ return ret; ++ } ++ return 0; ++} +diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c +index 23374178a1760..6bf8427f14fbd 100644 +--- a/drivers/net/dsa/realtek/rtl8366rb.c ++++ b/drivers/net/dsa/realtek/rtl8366rb.c +@@ -26,11 +26,7 @@ + #include "realtek-smi.h" + #include "realtek-mdio.h" + #include "rtl83xx.h" +- +-#define RTL8366RB_PORT_NUM_CPU 5 +-#define RTL8366RB_NUM_PORTS 6 +-#define RTL8366RB_PHY_NO_MAX 4 +-#define RTL8366RB_PHY_ADDR_MAX 31 ++#include "rtl8366rb.h" + + /* Switch Global Configuration register */ + #define RTL8366RB_SGCR 0x0000 +@@ -175,39 +171,6 @@ + */ + #define RTL8366RB_VLAN_INGRESS_CTRL2_REG 0x037f + +-/* LED control registers */ +-/* The LED blink rate is global; it is used by all triggers in all groups. */ +-#define RTL8366RB_LED_BLINKRATE_REG 0x0430 +-#define RTL8366RB_LED_BLINKRATE_MASK 0x0007 +-#define RTL8366RB_LED_BLINKRATE_28MS 0x0000 +-#define RTL8366RB_LED_BLINKRATE_56MS 0x0001 +-#define RTL8366RB_LED_BLINKRATE_84MS 0x0002 +-#define RTL8366RB_LED_BLINKRATE_111MS 0x0003 +-#define RTL8366RB_LED_BLINKRATE_222MS 0x0004 +-#define RTL8366RB_LED_BLINKRATE_446MS 0x0005 +- +-/* LED trigger event for each group */ +-#define RTL8366RB_LED_CTRL_REG 0x0431 +-#define RTL8366RB_LED_CTRL_OFFSET(led_group) \ +- (4 * (led_group)) +-#define RTL8366RB_LED_CTRL_MASK(led_group) \ +- (0xf << RTL8366RB_LED_CTRL_OFFSET(led_group)) +- +-/* The RTL8366RB_LED_X_X registers are used to manually set the LED state only +- * when the corresponding LED group in RTL8366RB_LED_CTRL_REG is +- * RTL8366RB_LEDGROUP_FORCE. Otherwise, it is ignored. +- */ +-#define RTL8366RB_LED_0_1_CTRL_REG 0x0432 +-#define RTL8366RB_LED_2_3_CTRL_REG 0x0433 +-#define RTL8366RB_LED_X_X_CTRL_REG(led_group) \ +- ((led_group) <= 1 ? \ +- RTL8366RB_LED_0_1_CTRL_REG : \ +- RTL8366RB_LED_2_3_CTRL_REG) +-#define RTL8366RB_LED_0_X_CTRL_MASK GENMASK(5, 0) +-#define RTL8366RB_LED_X_1_CTRL_MASK GENMASK(11, 6) +-#define RTL8366RB_LED_2_X_CTRL_MASK GENMASK(5, 0) +-#define RTL8366RB_LED_X_3_CTRL_MASK GENMASK(11, 6) +- + #define RTL8366RB_MIB_COUNT 33 + #define RTL8366RB_GLOBAL_MIB_COUNT 1 + #define RTL8366RB_MIB_COUNTER_PORT_OFFSET 0x0050 +@@ -243,7 +206,6 @@ + #define RTL8366RB_PORT_STATUS_AN_MASK 0x0080 + + #define RTL8366RB_NUM_VLANS 16 +-#define RTL8366RB_NUM_LEDGROUPS 4 + #define RTL8366RB_NUM_VIDS 4096 + #define RTL8366RB_PRIORITYMAX 7 + #define RTL8366RB_NUM_FIDS 8 +@@ -350,46 +312,6 @@ + #define RTL8366RB_GREEN_FEATURE_TX BIT(0) + #define RTL8366RB_GREEN_FEATURE_RX BIT(2) + +-enum rtl8366_ledgroup_mode { +- RTL8366RB_LEDGROUP_OFF = 0x0, +- RTL8366RB_LEDGROUP_DUP_COL = 0x1, +- RTL8366RB_LEDGROUP_LINK_ACT = 0x2, +- RTL8366RB_LEDGROUP_SPD1000 = 0x3, +- RTL8366RB_LEDGROUP_SPD100 = 0x4, +- RTL8366RB_LEDGROUP_SPD10 = 0x5, +- RTL8366RB_LEDGROUP_SPD1000_ACT = 0x6, +- RTL8366RB_LEDGROUP_SPD100_ACT = 0x7, +- RTL8366RB_LEDGROUP_SPD10_ACT = 0x8, +- RTL8366RB_LEDGROUP_SPD100_10_ACT = 0x9, +- RTL8366RB_LEDGROUP_FIBER = 0xa, +- RTL8366RB_LEDGROUP_AN_FAULT = 0xb, +- RTL8366RB_LEDGROUP_LINK_RX = 0xc, +- RTL8366RB_LEDGROUP_LINK_TX = 0xd, +- RTL8366RB_LEDGROUP_MASTER = 0xe, +- RTL8366RB_LEDGROUP_FORCE = 0xf, +- +- __RTL8366RB_LEDGROUP_MODE_MAX +-}; +- +-struct rtl8366rb_led { +- u8 port_num; +- u8 led_group; +- struct realtek_priv *priv; +- struct led_classdev cdev; +-}; +- +-/** +- * struct rtl8366rb - RTL8366RB-specific data +- * @max_mtu: per-port max MTU setting +- * @pvid_enabled: if PVID is set for respective port +- * @leds: per-port and per-ledgroup led info +- */ +-struct rtl8366rb { +- unsigned int max_mtu[RTL8366RB_NUM_PORTS]; +- bool pvid_enabled[RTL8366RB_NUM_PORTS]; +- struct rtl8366rb_led leds[RTL8366RB_NUM_PORTS][RTL8366RB_NUM_LEDGROUPS]; +-}; +- + static struct rtl8366_mib_counter rtl8366rb_mib_counters[] = { + { 0, 0, 4, "IfInOctets" }, + { 0, 4, 4, "EtherStatsOctets" }, +@@ -830,9 +752,10 @@ static int rtl8366rb_jam_table(const struct rtl8366rb_jam_tbl_entry *jam_table, + return 0; + } + +-static int rb8366rb_set_ledgroup_mode(struct realtek_priv *priv, +- u8 led_group, +- enum rtl8366_ledgroup_mode mode) ++/* This code is used also with LEDs disabled */ ++int rb8366rb_set_ledgroup_mode(struct realtek_priv *priv, ++ u8 led_group, ++ enum rtl8366_ledgroup_mode mode) + { + int ret; + u32 val; +@@ -849,144 +772,7 @@ static int rb8366rb_set_ledgroup_mode(struct realtek_priv *priv, + return 0; + } + +-static inline u32 rtl8366rb_led_group_port_mask(u8 led_group, u8 port) +-{ +- switch (led_group) { +- case 0: +- return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port)); +- case 1: +- return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port)); +- case 2: +- return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port)); +- case 3: +- return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port)); +- default: +- return 0; +- } +-} +- +-static int rb8366rb_get_port_led(struct rtl8366rb_led *led) +-{ +- struct realtek_priv *priv = led->priv; +- u8 led_group = led->led_group; +- u8 port_num = led->port_num; +- int ret; +- u32 val; +- +- ret = regmap_read(priv->map, RTL8366RB_LED_X_X_CTRL_REG(led_group), +- &val); +- if (ret) { +- dev_err(priv->dev, "error reading LED on port %d group %d\n", +- led_group, port_num); +- return ret; +- } +- +- return !!(val & rtl8366rb_led_group_port_mask(led_group, port_num)); +-} +- +-static int rb8366rb_set_port_led(struct rtl8366rb_led *led, bool enable) +-{ +- struct realtek_priv *priv = led->priv; +- u8 led_group = led->led_group; +- u8 port_num = led->port_num; +- int ret; +- +- ret = regmap_update_bits(priv->map, +- RTL8366RB_LED_X_X_CTRL_REG(led_group), +- rtl8366rb_led_group_port_mask(led_group, +- port_num), +- enable ? 0xffff : 0); +- if (ret) { +- dev_err(priv->dev, "error updating LED on port %d group %d\n", +- led_group, port_num); +- return ret; +- } +- +- /* Change the LED group to manual controlled LEDs if required */ +- ret = rb8366rb_set_ledgroup_mode(priv, led_group, +- RTL8366RB_LEDGROUP_FORCE); +- +- if (ret) { +- dev_err(priv->dev, "error updating LED GROUP group %d\n", +- led_group); +- return ret; +- } +- +- return 0; +-} +- +-static int +-rtl8366rb_cled_brightness_set_blocking(struct led_classdev *ldev, +- enum led_brightness brightness) +-{ +- struct rtl8366rb_led *led = container_of(ldev, struct rtl8366rb_led, +- cdev); +- +- return rb8366rb_set_port_led(led, brightness == LED_ON); +-} +- +-static int rtl8366rb_setup_led(struct realtek_priv *priv, struct dsa_port *dp, +- struct fwnode_handle *led_fwnode) +-{ +- struct rtl8366rb *rb = priv->chip_data; +- struct led_init_data init_data = { }; +- enum led_default_state state; +- struct rtl8366rb_led *led; +- u32 led_group; +- int ret; +- +- ret = fwnode_property_read_u32(led_fwnode, "reg", &led_group); +- if (ret) +- return ret; +- +- if (led_group >= RTL8366RB_NUM_LEDGROUPS) { +- dev_warn(priv->dev, "Invalid LED reg %d defined for port %d", +- led_group, dp->index); +- return -EINVAL; +- } +- +- led = &rb->leds[dp->index][led_group]; +- led->port_num = dp->index; +- led->led_group = led_group; +- led->priv = priv; +- +- state = led_init_default_state_get(led_fwnode); +- switch (state) { +- case LEDS_DEFSTATE_ON: +- led->cdev.brightness = 1; +- rb8366rb_set_port_led(led, 1); +- break; +- case LEDS_DEFSTATE_KEEP: +- led->cdev.brightness = +- rb8366rb_get_port_led(led); +- break; +- case LEDS_DEFSTATE_OFF: +- default: +- led->cdev.brightness = 0; +- rb8366rb_set_port_led(led, 0); +- } +- +- led->cdev.max_brightness = 1; +- led->cdev.brightness_set_blocking = +- rtl8366rb_cled_brightness_set_blocking; +- init_data.fwnode = led_fwnode; +- init_data.devname_mandatory = true; +- +- init_data.devicename = kasprintf(GFP_KERNEL, "Realtek-%d:0%d:%d", +- dp->ds->index, dp->index, led_group); +- if (!init_data.devicename) +- return -ENOMEM; +- +- ret = devm_led_classdev_register_ext(priv->dev, &led->cdev, &init_data); +- if (ret) { +- dev_warn(priv->dev, "Failed to init LED %d for port %d", +- led_group, dp->index); +- return ret; +- } +- +- return 0; +-} +- ++/* This code is used also with LEDs disabled */ + static int rtl8366rb_setup_all_leds_off(struct realtek_priv *priv) + { + int ret = 0; +@@ -1007,38 +793,6 @@ static int rtl8366rb_setup_all_leds_off(struct realtek_priv *priv) + return ret; + } + +-static int rtl8366rb_setup_leds(struct realtek_priv *priv) +-{ +- struct dsa_switch *ds = &priv->ds; +- struct device_node *leds_np; +- struct dsa_port *dp; +- int ret = 0; +- +- dsa_switch_for_each_port(dp, ds) { +- if (!dp->dn) +- continue; +- +- leds_np = of_get_child_by_name(dp->dn, "leds"); +- if (!leds_np) { +- dev_dbg(priv->dev, "No leds defined for port %d", +- dp->index); +- continue; +- } +- +- for_each_child_of_node_scoped(leds_np, led_np) { +- ret = rtl8366rb_setup_led(priv, dp, +- of_fwnode_handle(led_np)); +- if (ret) +- break; +- } +- +- of_node_put(leds_np); +- if (ret) +- return ret; +- } +- return 0; +-} +- + static int rtl8366rb_setup(struct dsa_switch *ds) + { + struct realtek_priv *priv = ds->priv; +diff --git a/drivers/net/dsa/realtek/rtl8366rb.h b/drivers/net/dsa/realtek/rtl8366rb.h +new file mode 100644 +index 0000000000000..685ff3275faa1 +--- /dev/null ++++ b/drivers/net/dsa/realtek/rtl8366rb.h +@@ -0,0 +1,107 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++ ++#ifndef _RTL8366RB_H ++#define _RTL8366RB_H ++ ++#include "realtek.h" ++ ++#define RTL8366RB_PORT_NUM_CPU 5 ++#define RTL8366RB_NUM_PORTS 6 ++#define RTL8366RB_PHY_NO_MAX 4 ++#define RTL8366RB_NUM_LEDGROUPS 4 ++#define RTL8366RB_PHY_ADDR_MAX 31 ++ ++/* LED control registers */ ++/* The LED blink rate is global; it is used by all triggers in all groups. */ ++#define RTL8366RB_LED_BLINKRATE_REG 0x0430 ++#define RTL8366RB_LED_BLINKRATE_MASK 0x0007 ++#define RTL8366RB_LED_BLINKRATE_28MS 0x0000 ++#define RTL8366RB_LED_BLINKRATE_56MS 0x0001 ++#define RTL8366RB_LED_BLINKRATE_84MS 0x0002 ++#define RTL8366RB_LED_BLINKRATE_111MS 0x0003 ++#define RTL8366RB_LED_BLINKRATE_222MS 0x0004 ++#define RTL8366RB_LED_BLINKRATE_446MS 0x0005 ++ ++/* LED trigger event for each group */ ++#define RTL8366RB_LED_CTRL_REG 0x0431 ++#define RTL8366RB_LED_CTRL_OFFSET(led_group) \ ++ (4 * (led_group)) ++#define RTL8366RB_LED_CTRL_MASK(led_group) \ ++ (0xf << RTL8366RB_LED_CTRL_OFFSET(led_group)) ++ ++/* The RTL8366RB_LED_X_X registers are used to manually set the LED state only ++ * when the corresponding LED group in RTL8366RB_LED_CTRL_REG is ++ * RTL8366RB_LEDGROUP_FORCE. Otherwise, it is ignored. ++ */ ++#define RTL8366RB_LED_0_1_CTRL_REG 0x0432 ++#define RTL8366RB_LED_2_3_CTRL_REG 0x0433 ++#define RTL8366RB_LED_X_X_CTRL_REG(led_group) \ ++ ((led_group) <= 1 ? \ ++ RTL8366RB_LED_0_1_CTRL_REG : \ ++ RTL8366RB_LED_2_3_CTRL_REG) ++#define RTL8366RB_LED_0_X_CTRL_MASK GENMASK(5, 0) ++#define RTL8366RB_LED_X_1_CTRL_MASK GENMASK(11, 6) ++#define RTL8366RB_LED_2_X_CTRL_MASK GENMASK(5, 0) ++#define RTL8366RB_LED_X_3_CTRL_MASK GENMASK(11, 6) ++ ++enum rtl8366_ledgroup_mode { ++ RTL8366RB_LEDGROUP_OFF = 0x0, ++ RTL8366RB_LEDGROUP_DUP_COL = 0x1, ++ RTL8366RB_LEDGROUP_LINK_ACT = 0x2, ++ RTL8366RB_LEDGROUP_SPD1000 = 0x3, ++ RTL8366RB_LEDGROUP_SPD100 = 0x4, ++ RTL8366RB_LEDGROUP_SPD10 = 0x5, ++ RTL8366RB_LEDGROUP_SPD1000_ACT = 0x6, ++ RTL8366RB_LEDGROUP_SPD100_ACT = 0x7, ++ RTL8366RB_LEDGROUP_SPD10_ACT = 0x8, ++ RTL8366RB_LEDGROUP_SPD100_10_ACT = 0x9, ++ RTL8366RB_LEDGROUP_FIBER = 0xa, ++ RTL8366RB_LEDGROUP_AN_FAULT = 0xb, ++ RTL8366RB_LEDGROUP_LINK_RX = 0xc, ++ RTL8366RB_LEDGROUP_LINK_TX = 0xd, ++ RTL8366RB_LEDGROUP_MASTER = 0xe, ++ RTL8366RB_LEDGROUP_FORCE = 0xf, ++ ++ __RTL8366RB_LEDGROUP_MODE_MAX ++}; ++ ++#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8366RB_LEDS) ++ ++struct rtl8366rb_led { ++ u8 port_num; ++ u8 led_group; ++ struct realtek_priv *priv; ++ struct led_classdev cdev; ++}; ++ ++int rtl8366rb_setup_leds(struct realtek_priv *priv); ++ ++#else ++ ++static inline int rtl8366rb_setup_leds(struct realtek_priv *priv) ++{ ++ return 0; ++} ++ ++#endif /* IS_ENABLED(CONFIG_LEDS_CLASS) */ ++ ++/** ++ * struct rtl8366rb - RTL8366RB-specific data ++ * @max_mtu: per-port max MTU setting ++ * @pvid_enabled: if PVID is set for respective port ++ * @leds: per-port and per-ledgroup led info ++ */ ++struct rtl8366rb { ++ unsigned int max_mtu[RTL8366RB_NUM_PORTS]; ++ bool pvid_enabled[RTL8366RB_NUM_PORTS]; ++#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8366RB_LEDS) ++ struct rtl8366rb_led leds[RTL8366RB_NUM_PORTS][RTL8366RB_NUM_LEDGROUPS]; ++#endif ++}; ++ ++/* This code is used also with LEDs disabled */ ++int rb8366rb_set_ledgroup_mode(struct realtek_priv *priv, ++ u8 led_group, ++ enum rtl8366_ledgroup_mode mode); ++ ++#endif /* _RTL8366RB_H */ +-- +2.39.5 + diff --git a/queue-6.13/net-ethernet-ti-am65-cpsw-select-page_pool.patch b/queue-6.13/net-ethernet-ti-am65-cpsw-select-page_pool.patch new file mode 100644 index 0000000000..738b99f5b4 --- /dev/null +++ b/queue-6.13/net-ethernet-ti-am65-cpsw-select-page_pool.patch @@ -0,0 +1,39 @@ +From b3f7ba8c4e36e67e6ab27051f370aa5a0de7dad0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Feb 2025 06:17:16 +0100 +Subject: net: ethernet: ti: am65-cpsw: select PAGE_POOL + +From: Sascha Hauer + +[ 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 +Reviewed-by: Michal Swiatkowski +Link: https://patch.msgid.link/20250224-net-am654-nuss-kconfig-v2-1-c124f4915c92@pengutronix.de +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/ti/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig +index 0d5a862cd78a6..3a13d60a947a8 100644 +--- a/drivers/net/ethernet/ti/Kconfig ++++ b/drivers/net/ethernet/ti/Kconfig +@@ -99,6 +99,7 @@ config TI_K3_AM65_CPSW_NUSS + select NET_DEVLINK + select TI_DAVINCI_MDIO + select PHYLINK ++ select PAGE_POOL + select TI_K3_CPPI_DESC_POOL + imply PHY_TI_GMII_SEL + depends on TI_K3_AM65_CPTS || !TI_K3_AM65_CPTS +-- +2.39.5 + diff --git a/queue-6.13/net-ipv6-fix-dst-ref-loop-on-input-in-rpl-lwt.patch b/queue-6.13/net-ipv6-fix-dst-ref-loop-on-input-in-rpl-lwt.patch new file mode 100644 index 0000000000..f99cfef710 --- /dev/null +++ b/queue-6.13/net-ipv6-fix-dst-ref-loop-on-input-in-rpl-lwt.patch @@ -0,0 +1,60 @@ +From f6fefb4f950495236321cf8deafe6d0f7efb02e4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Feb 2025 18:51:39 +0100 +Subject: net: ipv6: fix dst ref loop on input in rpl lwt + +From: Justin Iurman + +[ Upstream commit 13e55fbaec176119cff68a7e1693b251c8883c5f ] + +Prevent a dst ref loop on input in rpl_iptunnel. + +Fixes: a7a29f9c361f ("net: ipv6: add rpl sr tunnel") +Cc: Alexander Aring +Cc: Ido Schimmel +Reviewed-by: Ido Schimmel +Signed-off-by: Justin Iurman +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/ipv6/rpl_iptunnel.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/net/ipv6/rpl_iptunnel.c b/net/ipv6/rpl_iptunnel.c +index 0ac4283acdf20..7c05ac846646f 100644 +--- a/net/ipv6/rpl_iptunnel.c ++++ b/net/ipv6/rpl_iptunnel.c +@@ -262,10 +262,18 @@ static int rpl_input(struct sk_buff *skb) + { + struct dst_entry *orig_dst = skb_dst(skb); + struct dst_entry *dst = NULL; ++ struct lwtunnel_state *lwtst; + struct rpl_lwt *rlwt; + int err; + +- rlwt = rpl_lwt_lwtunnel(orig_dst->lwtstate); ++ /* We cannot dereference "orig_dst" once ip6_route_input() or ++ * skb_dst_drop() is called. However, in order to detect a dst loop, we ++ * need the address of its lwtstate. So, save the address of lwtstate ++ * now and use it later as a comparison. ++ */ ++ lwtst = orig_dst->lwtstate; ++ ++ rlwt = rpl_lwt_lwtunnel(lwtst); + + local_bh_disable(); + dst = dst_cache_get(&rlwt->cache); +@@ -280,7 +288,9 @@ static int rpl_input(struct sk_buff *skb) + if (!dst) { + ip6_route_input(skb); + dst = skb_dst(skb); +- if (!dst->error) { ++ ++ /* cache only if we don't create a dst reference loop */ ++ if (!dst->error && lwtst != dst->lwtstate) { + local_bh_disable(); + dst_cache_set_ip6(&rlwt->cache, dst, + &ipv6_hdr(skb)->saddr); +-- +2.39.5 + diff --git a/queue-6.13/net-ipv6-fix-dst-ref-loop-on-input-in-seg6-lwt.patch b/queue-6.13/net-ipv6-fix-dst-ref-loop-on-input-in-seg6-lwt.patch new file mode 100644 index 0000000000..0b00c7977b --- /dev/null +++ b/queue-6.13/net-ipv6-fix-dst-ref-loop-on-input-in-seg6-lwt.patch @@ -0,0 +1,60 @@ +From 1310547e7c9552a802ff73c5a82660f4c6985fd4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Feb 2025 18:51:38 +0100 +Subject: net: ipv6: fix dst ref loop on input in seg6 lwt + +From: Justin Iurman + +[ 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 +Cc: Ido Schimmel +Reviewed-by: Ido Schimmel +Signed-off-by: Justin Iurman +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/ipv6/seg6_iptunnel.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c +index 33833b2064c07..51583461ae29b 100644 +--- a/net/ipv6/seg6_iptunnel.c ++++ b/net/ipv6/seg6_iptunnel.c +@@ -472,10 +472,18 @@ static int seg6_input_core(struct net *net, struct sock *sk, + { + struct dst_entry *orig_dst = skb_dst(skb); + struct dst_entry *dst = NULL; ++ struct lwtunnel_state *lwtst; + struct seg6_lwt *slwt; + int err; + +- slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate); ++ /* We cannot dereference "orig_dst" once ip6_route_input() or ++ * skb_dst_drop() is called. However, in order to detect a dst loop, we ++ * need the address of its lwtstate. So, save the address of lwtstate ++ * now and use it later as a comparison. ++ */ ++ lwtst = orig_dst->lwtstate; ++ ++ slwt = seg6_lwt_lwtunnel(lwtst); + + local_bh_disable(); + dst = dst_cache_get(&slwt->cache); +@@ -490,7 +498,9 @@ static int seg6_input_core(struct net *net, struct sock *sk, + if (!dst) { + ip6_route_input(skb); + dst = skb_dst(skb); +- if (!dst->error) { ++ ++ /* cache only if we don't create a dst reference loop */ ++ if (!dst->error && lwtst != dst->lwtstate) { + local_bh_disable(); + dst_cache_set_ip6(&slwt->cache, dst, + &ipv6_hdr(skb)->saddr); +-- +2.39.5 + diff --git a/queue-6.13/net-loopback-avoid-sending-ip-packets-without-an-eth.patch b/queue-6.13/net-loopback-avoid-sending-ip-packets-without-an-eth.patch new file mode 100644 index 0000000000..355718548a --- /dev/null +++ b/queue-6.13/net-loopback-avoid-sending-ip-packets-without-an-eth.patch @@ -0,0 +1,94 @@ +From e2b100508a9ecdb9caa072bce47189daff3a90e4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Feb 2025 09:25:59 +0200 +Subject: net: loopback: Avoid sending IP packets without an Ethernet header + +From: Ido Schimmel + +[ 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 +Closes: https://lore.kernel.org/netdev/20250210084931.23a5c2e4@hermes.local/ +Signed-off-by: Ido Schimmel +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20250220072559.782296-1-idosch@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/loopback.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c +index 1993b90b1a5f9..491e56b3263fd 100644 +--- a/drivers/net/loopback.c ++++ b/drivers/net/loopback.c +@@ -244,8 +244,22 @@ static netdev_tx_t blackhole_netdev_xmit(struct sk_buff *skb, + return NETDEV_TX_OK; + } + ++static int blackhole_neigh_output(struct neighbour *n, struct sk_buff *skb) ++{ ++ kfree_skb(skb); ++ return 0; ++} ++ ++static int blackhole_neigh_construct(struct net_device *dev, ++ struct neighbour *n) ++{ ++ n->output = blackhole_neigh_output; ++ return 0; ++} ++ + static const struct net_device_ops blackhole_netdev_ops = { + .ndo_start_xmit = blackhole_netdev_xmit, ++ .ndo_neigh_construct = blackhole_neigh_construct, + }; + + /* This is a dst-dummy device used specifically for invalidated +-- +2.39.5 + diff --git a/queue-6.13/net-mlx5-fix-vport-qos-cleanup-on-error.patch b/queue-6.13/net-mlx5-fix-vport-qos-cleanup-on-error.patch new file mode 100644 index 0000000000..fa81f11b5e --- /dev/null +++ b/queue-6.13/net-mlx5-fix-vport-qos-cleanup-on-error.patch @@ -0,0 +1,47 @@ +From 7d5e053b99e7e065fe4175eea175834bf9551250 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Feb 2025 09:26:06 +0200 +Subject: net/mlx5: Fix vport QoS cleanup on error + +From: Carolina Jubran + +[ 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 +Reviewed-by: Cosmin Ratiu +Reviewed-by: Dragos Tatulea +Signed-off-by: Tariq Toukan +Link: https://patch.msgid.link/20250225072608.526866-2-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c +index 8b7c843446e11..07a28073a49ea 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c +@@ -591,8 +591,11 @@ static int mlx5_esw_qos_vport_enable(struct mlx5_vport *vport, enum sched_node_t + sched_node->vport = vport; + vport->qos.sched_node = sched_node; + err = esw_qos_vport_enable(vport, parent, extack); +- if (err) ++ if (err) { ++ __esw_qos_free_node(sched_node); + esw_qos_put(esw); ++ vport->qos.sched_node = NULL; ++ } + + return err; + } +-- +2.39.5 + diff --git a/queue-6.13/net-mlx5-irq-fix-null-string-in-debug-print.patch b/queue-6.13/net-mlx5-irq-fix-null-string-in-debug-print.patch new file mode 100644 index 0000000000..59f228d764 --- /dev/null +++ b/queue-6.13/net-mlx5-irq-fix-null-string-in-debug-print.patch @@ -0,0 +1,42 @@ +From f9737883ee0fb9796f778c16ce42c262c3242f3b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Feb 2025 09:26:08 +0200 +Subject: net/mlx5: IRQ, Fix null string in debug print + +From: Shay Drory + +[ 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 +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202501141055.SwfIphN0-lkp@intel.com/ +Reviewed-by: Moshe Shemesh +Signed-off-by: Tariq Toukan +Reviewed-by: Kalesh AP +Link: https://patch.msgid.link/20250225072608.526866-4-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c +index 7db9cab9bedf6..d9362eabc6a1c 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c +@@ -572,7 +572,7 @@ irq_pool_alloc(struct mlx5_core_dev *dev, int start, int size, char *name, + pool->min_threshold = min_threshold * MLX5_EQ_REFS_PER_IRQ; + pool->max_threshold = max_threshold * MLX5_EQ_REFS_PER_IRQ; + mlx5_core_dbg(dev, "pool->name = %s, pool->size = %d, pool->start = %d", +- name, size, start); ++ name ? name : "mlx5_pcif_pool", size, start); + return pool; + } + +-- +2.39.5 + diff --git a/queue-6.13/net-mlx5-restore-missing-trace-event-when-enabling-v.patch b/queue-6.13/net-mlx5-restore-missing-trace-event-when-enabling-v.patch new file mode 100644 index 0000000000..7eac44041c --- /dev/null +++ b/queue-6.13/net-mlx5-restore-missing-trace-event-when-enabling-v.patch @@ -0,0 +1,41 @@ +From 50af5d8f11f5534ae942c4243d8c7fc0b9f59987 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Feb 2025 09:26:07 +0200 +Subject: net/mlx5: Restore missing trace event when enabling vport QoS + +From: Carolina Jubran + +[ 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 +Reviewed-by: Dragos Tatulea +Signed-off-by: Tariq Toukan +Link: https://patch.msgid.link/20250225072608.526866-3-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c +index 07a28073a49ea..823c1ba456cd1 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c +@@ -564,6 +564,9 @@ static int esw_qos_vport_enable(struct mlx5_vport *vport, struct mlx5_esw_sched_ + return err; + + esw_qos_normalize_min_rate(parent->esw, parent, extack); ++ trace_mlx5_esw_vport_qos_create(vport->dev, vport, ++ vport->qos.sched_node->max_rate, ++ vport->qos.sched_node->bw_share); + + return 0; + } +-- +2.39.5 + diff --git a/queue-6.13/net-mvpp2-cls-fixed-non-ip-flow-with-vlan-tag-flow-d.patch b/queue-6.13/net-mvpp2-cls-fixed-non-ip-flow-with-vlan-tag-flow-d.patch new file mode 100644 index 0000000000..de0b67133a --- /dev/null +++ b/queue-6.13/net-mvpp2-cls-fixed-non-ip-flow-with-vlan-tag-flow-d.patch @@ -0,0 +1,40 @@ +From edcd284edb4d6c425ab566e01628be5c908f0a70 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Maxime Chevallier +Link: https://patch.msgid.link/20250225042058.2643838-1-hchaudhari@marvell.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c +index 1641791a2d5b4..8ed83fb988624 100644 +--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c ++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c +@@ -324,7 +324,7 @@ static const struct mvpp2_cls_flow cls_flows[MVPP2_N_PRS_FLOWS] = { + MVPP2_PRS_RI_VLAN_MASK), + /* Non IP flow, with vlan tag */ + MVPP2_DEF_FLOW(MVPP22_FLOW_ETHERNET, MVPP2_FL_NON_IP_TAG, +- MVPP22_CLS_HEK_OPT_VLAN, ++ MVPP22_CLS_HEK_TAGGED, + 0, 0), + }; + +-- +2.39.5 + diff --git a/queue-6.13/net-set-the-minimum-for-net_hotdata.netdev_budget_us.patch b/queue-6.13/net-set-the-minimum-for-net_hotdata.netdev_budget_us.patch new file mode 100644 index 0000000000..b15ca9faa3 --- /dev/null +++ b/queue-6.13/net-set-the-minimum-for-net_hotdata.netdev_budget_us.patch @@ -0,0 +1,58 @@ +From b07c5fd4043e7bc296f34796e90b145ce8c33a20 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Feb 2025 12:07:52 +0100 +Subject: net: set the minimum for net_hotdata.netdev_budget_usecs + +From: Jiri Slaby (SUSE) + +[ 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) +Cc: Dmitry Yakunin +Cc: Konstantin Khlebnikov +Link: https://patch.msgid.link/20250220110752.137639-1-jirislaby@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/sysctl_net_core.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c +index ad2741f1346af..c7769ee0d9c55 100644 +--- a/net/core/sysctl_net_core.c ++++ b/net/core/sysctl_net_core.c +@@ -34,6 +34,7 @@ static int min_sndbuf = SOCK_MIN_SNDBUF; + static int min_rcvbuf = SOCK_MIN_RCVBUF; + static int max_skb_frags = MAX_SKB_FRAGS; + static int min_mem_pcpu_rsv = SK_MEMORY_PCPU_RESERVE; ++static int netdev_budget_usecs_min = 2 * USEC_PER_SEC / HZ; + + static int net_msg_warn; /* Unused, but still a sysctl */ + +@@ -587,7 +588,7 @@ static struct ctl_table net_core_table[] = { + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, +- .extra1 = SYSCTL_ZERO, ++ .extra1 = &netdev_budget_usecs_min, + }, + { + .procname = "fb_tunnels_only_for_init_net", +-- +2.39.5 + diff --git a/queue-6.13/net-ti-icss-iep-reject-perout-generation-request.patch b/queue-6.13/net-ti-icss-iep-reject-perout-generation-request.patch new file mode 100644 index 0000000000..ddadc4a584 --- /dev/null +++ b/queue-6.13/net-ti-icss-iep-reject-perout-generation-request.patch @@ -0,0 +1,60 @@ +From c32e456dac8819711f66036bee8ff4505b1ff4e4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Feb 2025 14:54:41 +0530 +Subject: net: ti: icss-iep: Reject perout generation request + +From: Meghana Malladi + +[ 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 +Reviewed-by: Vadim Fedorenko +Link: https://patch.msgid.link/20250227092441.1848419-1-m-malladi@ti.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/ti/icssg/icss_iep.c | 21 +-------------------- + 1 file changed, 1 insertion(+), 20 deletions(-) + +diff --git a/drivers/net/ethernet/ti/icssg/icss_iep.c b/drivers/net/ethernet/ti/icssg/icss_iep.c +index 768578c0d9587..d59c1744840af 100644 +--- a/drivers/net/ethernet/ti/icssg/icss_iep.c ++++ b/drivers/net/ethernet/ti/icssg/icss_iep.c +@@ -474,26 +474,7 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep, + static int icss_iep_perout_enable(struct icss_iep *iep, + struct ptp_perout_request *req, int on) + { +- int ret = 0; +- +- mutex_lock(&iep->ptp_clk_mutex); +- +- if (iep->pps_enabled) { +- ret = -EBUSY; +- goto exit; +- } +- +- if (iep->perout_enabled == !!on) +- goto exit; +- +- ret = icss_iep_perout_enable_hw(iep, req, on); +- if (!ret) +- iep->perout_enabled = !!on; +- +-exit: +- mutex_unlock(&iep->ptp_clk_mutex); +- +- return ret; ++ return -EOPNOTSUPP; + } + + static void icss_iep_cap_cmp_work(struct work_struct *work) +-- +2.39.5 + diff --git a/queue-6.13/rxrpc-rxperf-fix-missing-decoding-of-terminal-magic-.patch b/queue-6.13/rxrpc-rxperf-fix-missing-decoding-of-terminal-magic-.patch new file mode 100644 index 0000000000..0f3f11d939 --- /dev/null +++ b/queue-6.13/rxrpc-rxperf-fix-missing-decoding-of-terminal-magic-.patch @@ -0,0 +1,51 @@ +From 5b6e95f83bad38706690a944e5c53d34d65e5a69 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Feb 2025 19:22:44 +0000 +Subject: rxrpc: rxperf: Fix missing decoding of terminal magic cookie + +From: David Howells + +[ 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 +cc: Marc Dionne +cc: Simon Horman +cc: linux-afs@lists.infradead.org +Link: https://patch.msgid.link/20250218192250.296870-2-dhowells@redhat.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/rxrpc/rxperf.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/net/rxrpc/rxperf.c b/net/rxrpc/rxperf.c +index 085e7892d3104..b1536da2246b8 100644 +--- a/net/rxrpc/rxperf.c ++++ b/net/rxrpc/rxperf.c +@@ -478,6 +478,18 @@ static int rxperf_deliver_request(struct rxperf_call *call) + call->unmarshal++; + fallthrough; + case 2: ++ ret = rxperf_extract_data(call, true); ++ if (ret < 0) ++ return ret; ++ ++ /* Deal with the terminal magic cookie. */ ++ call->iov_len = 4; ++ call->kvec[0].iov_len = call->iov_len; ++ call->kvec[0].iov_base = call->tmp; ++ iov_iter_kvec(&call->iter, READ, call->kvec, 1, call->iov_len); ++ call->unmarshal++; ++ fallthrough; ++ case 3: + ret = rxperf_extract_data(call, false); + if (ret < 0) + return ret; +-- +2.39.5 + diff --git a/queue-6.13/selftests-drv-net-check-if-combined-count-exists.patch b/queue-6.13/selftests-drv-net-check-if-combined-count-exists.patch new file mode 100644 index 0000000000..f3f03becba --- /dev/null +++ b/queue-6.13/selftests-drv-net-check-if-combined-count-exists.patch @@ -0,0 +1,82 @@ +From e62ed381795330e1ad29585b85ea012e8c9c5435 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Feb 2025 18:19:57 +0000 +Subject: selftests: drv-net: Check if combined-count exists + +From: Joe Damato + +[ 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 +Reviewed-by: David Wei +Link: https://patch.msgid.link/20250226181957.212189-1-jdamato@fastly.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.13/series b/queue-6.13/series index d24a1d39a9..a26c8277a3 100644 --- a/queue-6.13/series +++ b/queue-6.13/series @@ -22,3 +22,41 @@ scsi-ufs-core-set-default-runtime-system-pm-levels-b.patch rdma-mlx5-fix-bind-qp-error-cleanup-flow.patch rdma-bnxt_re-fix-the-page-details-for-the-srq-create.patch sunrpc-suppress-warnings-for-unused-procfs-functions.patch +alsa-usb-audio-avoid-dropping-midi-events-at-closing.patch +bluetooth-l2cap-fix-l2cap_ecred_conn_rsp-response.patch +rxrpc-rxperf-fix-missing-decoding-of-terminal-magic-.patch +afs-fix-the-server_list-to-unuse-a-displaced-server-.patch +afs-give-an-afs_server-object-a-ref-on-the-afs_cell-.patch +net-add-net_passive_inc-and-net_passive_dec.patch +net-better-track-kernel-sockets-lifetime.patch +net-loopback-avoid-sending-ip-packets-without-an-eth.patch +net-set-the-minimum-for-net_hotdata.netdev_budget_us.patch +ipvlan-ensure-network-headers-are-in-skb-linear-part.patch +net-cadence-macb-synchronize-stats-calculations.patch +net-dsa-rtl8366rb-fix-compilation-problem.patch +asoc-es8328-fix-route-from-dac-to-output.patch +asoc-fsl-rename-stream-name-of-sai-dai-driver.patch +ipvs-always-clear-ipvs_property-flag-in-skb_scrub_pa.patch +drm-xe-oa-allow-oa_exponent-value-of-0.patch +firmware-cs_dsp-remove-async-regmap-writes.patch +asoc-cs35l56-prevent-races-when-soft-resetting-using.patch +alsa-hda-realtek-fix-wrong-mic-setup-for-asus-vivobo.patch +drm-amdgpu-gfx-only-call-mes-for-enforce-isolation-i.patch +drm-amdgpu-mes-keep-enforce-isolation-up-to-date.patch +drm-amd-display-restore-edid-reading-from-a-given-i2.patch +net-ethernet-ti-am65-cpsw-select-page_pool.patch +tcp-devmem-don-t-write-truncated-dmabuf-cmsgs-to-use.patch +ice-fix-deinitializing-vf-in-error-path.patch +ice-avoid-setting-default-rx-vsi-twice-in-switchdev-.patch +tcp-defer-ts_recent-changes-until-req-is-owned.patch +drm-xe-cancel-pending-job-timer-before-freeing-sched.patch +net-clear-old-fragment-checksum-value-in-napi_reuse_.patch +net-mvpp2-cls-fixed-non-ip-flow-with-vlan-tag-flow-d.patch +net-mlx5-fix-vport-qos-cleanup-on-error.patch +net-mlx5-restore-missing-trace-event-when-enabling-v.patch +net-mlx5-irq-fix-null-string-in-debug-print.patch +net-ipv6-fix-dst-ref-loop-on-input-in-seg6-lwt.patch +net-ipv6-fix-dst-ref-loop-on-input-in-rpl-lwt.patch +selftests-drv-net-check-if-combined-count-exists.patch +idpf-fix-checksums-set-in-idpf_rx_rsc.patch +net-ti-icss-iep-reject-perout-generation-request.patch diff --git a/queue-6.13/tcp-defer-ts_recent-changes-until-req-is-owned.patch b/queue-6.13/tcp-defer-ts_recent-changes-until-req-is-owned.patch new file mode 100644 index 0000000000..b0813b2043 --- /dev/null +++ b/queue-6.13/tcp-defer-ts_recent-changes-until-req-is-owned.patch @@ -0,0 +1,92 @@ +From 155ce15f782771ac41f18ac159ad61b645b474b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Feb 2025 17:00:47 +0800 +Subject: tcp: Defer ts_recent changes until req is owned + +From: Wang Hai + +[ 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 +Reviewed-by: Jason Xing +Reviewed-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv4/tcp_minisocks.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c +index 7121d8573928c..789e495d3bd6a 100644 +--- a/net/ipv4/tcp_minisocks.c ++++ b/net/ipv4/tcp_minisocks.c +@@ -810,12 +810,6 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, + + /* In sequence, PAWS is OK. */ + +- /* TODO: We probably should defer ts_recent change once +- * we take ownership of @req. +- */ +- if (tmp_opt.saw_tstamp && !after(TCP_SKB_CB(skb)->seq, tcp_rsk(req)->rcv_nxt)) +- WRITE_ONCE(req->ts_recent, tmp_opt.rcv_tsval); +- + if (TCP_SKB_CB(skb)->seq == tcp_rsk(req)->rcv_isn) { + /* Truncate SYN, it is out of window starting + at tcp_rsk(req)->rcv_isn + 1. */ +@@ -864,6 +858,10 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, + if (!child) + goto listen_overflow; + ++ if (own_req && tmp_opt.saw_tstamp && ++ !after(TCP_SKB_CB(skb)->seq, tcp_rsk(req)->rcv_nxt)) ++ tcp_sk(child)->rx_opt.ts_recent = tmp_opt.rcv_tsval; ++ + if (own_req && rsk_drop_req(req)) { + reqsk_queue_removed(&inet_csk(req->rsk_listener)->icsk_accept_queue, req); + inet_csk_reqsk_queue_drop_and_put(req->rsk_listener, req); +-- +2.39.5 + diff --git a/queue-6.13/tcp-devmem-don-t-write-truncated-dmabuf-cmsgs-to-use.patch b/queue-6.13/tcp-devmem-don-t-write-truncated-dmabuf-cmsgs-to-use.patch new file mode 100644 index 0000000000..d3e10b2fb3 --- /dev/null +++ b/queue-6.13/tcp-devmem-don-t-write-truncated-dmabuf-cmsgs-to-use.patch @@ -0,0 +1,129 @@ +From 1e3d288ec2da8a2996e10b347ada6523d0bfd4af Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Feb 2025 09:44:01 -0800 +Subject: tcp: devmem: don't write truncated dmabuf CMSGs to userspace + +From: Stanislav Fomichev + +[ 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 +Signed-off-by: Stanislav Fomichev +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20250224174401.3582695-1-sdf@fomichev.me +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 +