--- /dev/null
+From 00d462758fc0893c507f2d9c440b880e590d22ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 13:07:17 +0100
+Subject: ASoC: cs42l43: Reset clamp override on jack removal
+
+From: Charles Keepax <ckeepax@opensource.cirrus.com>
+
+[ Upstream commit 5fc7d2b5cab47f2ac712f689140b1fed978fb91c ]
+
+Some of the manually selected jack configurations will disable the
+headphone clamp override. Restore this on jack removal, such that
+the state is consistent for a new insert.
+
+Fixes: fc918cbe874e ("ASoC: cs42l43: Add support for the cs42l43")
+Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Link: https://patch.msgid.link/20250409120717.1294528-1-ckeepax@opensource.cirrus.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/cs42l43-jack.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/sound/soc/codecs/cs42l43-jack.c b/sound/soc/codecs/cs42l43-jack.c
+index 9f5f1a92561d1..0b8e88b19888e 100644
+--- a/sound/soc/codecs/cs42l43-jack.c
++++ b/sound/soc/codecs/cs42l43-jack.c
+@@ -690,6 +690,9 @@ static void cs42l43_clear_jack(struct cs42l43_codec *priv)
+ CS42L43_PGA_WIDESWING_MODE_EN_MASK, 0);
+ regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CTRL,
+ CS42L43_JACK_STEREO_CONFIG_MASK, 0);
++ regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CLAMP_CTRL,
++ CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
++ CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK);
+ regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
+ CS42L43_HSDET_MODE_MASK | CS42L43_HSDET_MANUAL_MODE_MASK,
+ 0x2 << CS42L43_HSDET_MODE_SHIFT);
+--
+2.39.5
+
--- /dev/null
+From 8a8268e0a294fcae9d9df523103304ea369b68ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Mar 2025 09:08:54 -0400
+Subject: ASoC: dwc: always enable/disable i2s irqs
+
+From: Brady Norander <bradynorander@gmail.com>
+
+[ Upstream commit 2b727b3f8a04fe52f55316ccb8792cfd9b2dd05d ]
+
+Commit a42e988 ("ASoC: dwc: add DMA handshake control") changed the
+behavior of the driver to not enable or disable i2s irqs if using DMA. This
+breaks platforms such as AMD ACP. Audio playback appears to work but no
+audio can be heard. Revert to the old behavior by always enabling and
+disabling i2s irqs while keeping DMA handshake control.
+
+Fixes: a42e988b626 ("ASoC: dwc: add DMA handshake control")
+Signed-off-by: Brady Norander <bradynorander@gmail.com>
+Link: https://patch.msgid.link/20250330130852.37881-3-bradynorander@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/dwc/dwc-i2s.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c
+index 9ea4be56d3b70..43edad6c887dc 100644
+--- a/sound/soc/dwc/dwc-i2s.c
++++ b/sound/soc/dwc/dwc-i2s.c
+@@ -199,12 +199,10 @@ static void i2s_start(struct dw_i2s_dev *dev,
+ else
+ i2s_write_reg(dev->i2s_base, IRER, 1);
+
+- /* I2S needs to enable IRQ to make a handshake with DMAC on the JH7110 SoC */
+- if (dev->use_pio || dev->is_jh7110)
+- i2s_enable_irqs(dev, substream->stream, config->chan_nr);
+- else
++ if (!(dev->use_pio || dev->is_jh7110))
+ i2s_enable_dma(dev, substream->stream);
+
++ i2s_enable_irqs(dev, substream->stream, config->chan_nr);
+ i2s_write_reg(dev->i2s_base, CER, 1);
+ }
+
+@@ -218,11 +216,12 @@ static void i2s_stop(struct dw_i2s_dev *dev,
+ else
+ i2s_write_reg(dev->i2s_base, IRER, 0);
+
+- if (dev->use_pio || dev->is_jh7110)
+- i2s_disable_irqs(dev, substream->stream, 8);
+- else
++ if (!(dev->use_pio || dev->is_jh7110))
+ i2s_disable_dma(dev, substream->stream);
+
++ i2s_disable_irqs(dev, substream->stream, 8);
++
++
+ if (!dev->active) {
+ i2s_write_reg(dev->i2s_base, CER, 0);
+ i2s_write_reg(dev->i2s_base, IER, 0);
+--
+2.39.5
+
--- /dev/null
+From 1a0da194bcd25758040fe7124d1a946e925a32b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 22:14:11 +0800
+Subject: ASoC: Intel: avs: Fix null-ptr-deref in avs_component_probe()
+
+From: Henry Martin <bsdhenrymartin@gmail.com>
+
+[ Upstream commit 95f723cf141b95e3b3a5b92cf2ea98a863fe7275 ]
+
+devm_kasprintf() returns NULL when memory allocation fails. Currently,
+avs_component_probe() does not check for this case, which results in a
+NULL pointer dereference.
+
+Fixes: 739c031110da ("ASoC: Intel: avs: Provide support for fallback topology")
+Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
+Reviewed-by: Ethan Carter Edwards <ethan@ethancedwards.com>
+Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com>
+Link: https://patch.msgid.link/20250402141411.44972-1-bsdhenrymartin@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/avs/pcm.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c
+index bb1e77ac78e04..781019685b941 100644
+--- a/sound/soc/intel/avs/pcm.c
++++ b/sound/soc/intel/avs/pcm.c
+@@ -808,7 +808,8 @@ static int avs_component_probe(struct snd_soc_component *component)
+ else
+ mach->tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL,
+ "hda-generic-tplg.bin");
+-
++ if (!mach->tplg_filename)
++ return -ENOMEM;
+ filename = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix,
+ mach->tplg_filename);
+ if (!filename)
+--
+2.39.5
+
--- /dev/null
+From eb258ca113bf05d87fd181d39ed356e2ff712177 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 09:30:15 +0200
+Subject: ata: libata-sata: Save all fields from sense data descriptor
+
+From: Niklas Cassel <cassel@kernel.org>
+
+[ Upstream commit 399eab7f92fb73ffe621294a2d6bec8fc9f3b36b ]
+
+When filling the taskfile result for a successful NCQ command, we use
+the SDB FIS from the FIS Receive Area, see e.g. ahci_qc_ncq_fill_rtf().
+
+However, the SDB FIS only has fields STATUS and ERROR.
+
+For a successful NCQ command that has sense data, we will have a
+successful sense data descriptor, in the Sense Data for Successful NCQ
+Commands log.
+
+Since we have access to additional taskfile result fields, fill in these
+additional fields in qc->result_tf.
+
+This matches how for failing/aborted NCQ commands, we will use e.g.
+ahci_qc_fill_rtf() to fill in some fields, but then for the command that
+actually caused the NCQ error, we will use ata_eh_read_log_10h(), which
+provides additional fields, saving additional fields/overriding the
+qc->result_tf that was fetched using ahci_qc_fill_rtf().
+
+Fixes: 18bd7718b5c4 ("scsi: ata: libata: Handle completion of CDL commands using policy 0xD")
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Reviewed-by: Igor Pylypiv <ipylypiv@google.com>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/libata-sata.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c
+index a701e1538482f..be72030a500d4 100644
+--- a/drivers/ata/libata-sata.c
++++ b/drivers/ata/libata-sata.c
+@@ -1365,6 +1365,8 @@ int ata_eh_read_sense_success_ncq_log(struct ata_link *link)
+ unsigned int err_mask, tag;
+ u8 *sense, sk = 0, asc = 0, ascq = 0;
+ u64 sense_valid, val;
++ u16 extended_sense;
++ bool aux_icc_valid;
+ int ret = 0;
+
+ err_mask = ata_read_log_page(dev, ATA_LOG_SENSE_NCQ, 0, buf, 2);
+@@ -1384,6 +1386,8 @@ int ata_eh_read_sense_success_ncq_log(struct ata_link *link)
+
+ sense_valid = (u64)buf[8] | ((u64)buf[9] << 8) |
+ ((u64)buf[10] << 16) | ((u64)buf[11] << 24);
++ extended_sense = get_unaligned_le16(&buf[14]);
++ aux_icc_valid = extended_sense & BIT(15);
+
+ ata_qc_for_each_raw(ap, qc, tag) {
+ if (!(qc->flags & ATA_QCFLAG_EH) ||
+@@ -1411,6 +1415,17 @@ int ata_eh_read_sense_success_ncq_log(struct ata_link *link)
+ continue;
+ }
+
++ qc->result_tf.nsect = sense[6];
++ qc->result_tf.hob_nsect = sense[7];
++ qc->result_tf.lbal = sense[8];
++ qc->result_tf.lbam = sense[9];
++ qc->result_tf.lbah = sense[10];
++ qc->result_tf.hob_lbal = sense[11];
++ qc->result_tf.hob_lbam = sense[12];
++ qc->result_tf.hob_lbah = sense[13];
++ if (aux_icc_valid)
++ qc->result_tf.auxiliary = get_unaligned_le32(&sense[16]);
++
+ /* Set sense without also setting scsicmd->result */
+ scsi_build_sense_buffer(dev->flags & ATA_DFLAG_D_SENSE,
+ qc->scsicmd->sense_buffer, sk,
+--
+2.39.5
+
--- /dev/null
+From 947ee20de8c6116c88f814dc21315a4267fdfe9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Apr 2025 17:25:54 +0800
+Subject: block: fix resource leak in blk_register_queue() error path
+
+From: Zheng Qixing <zhengqixing@huawei.com>
+
+[ Upstream commit 40f2eb9b531475dd01b683fdaf61ca3cfd03a51e ]
+
+When registering a queue fails after blk_mq_sysfs_register() is
+successful but the function later encounters an error, we need
+to clean up the blk_mq_sysfs resources.
+
+Add the missing blk_mq_sysfs_unregister() call in the error path
+to properly clean up these resources and prevent a memory leak.
+
+Fixes: 320ae51feed5 ("blk-mq: new multi-queue block IO queueing mechanism")
+Signed-off-by: Zheng Qixing <zhengqixing@huawei.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20250412092554.475218-1-zhengqixing@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-sysfs.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
+index 4990a19e60133..74839f6f2e0cb 100644
+--- a/block/blk-sysfs.c
++++ b/block/blk-sysfs.c
+@@ -854,6 +854,8 @@ int blk_register_queue(struct gendisk *disk)
+ out_debugfs_remove:
+ blk_debugfs_remove(disk);
+ mutex_unlock(&q->sysfs_lock);
++ if (queue_is_mq(q))
++ blk_mq_sysfs_unregister(disk);
+ out_put_queue_kobj:
+ kobject_put(&disk->queue_kobj);
+ mutex_unlock(&q->sysfs_dir_lock);
+--
+2.39.5
+
--- /dev/null
+From 3cfc10d15a1858a462e602e6ddef9ba1c94a8693 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 14:01:41 +0300
+Subject: Bluetooth: btrtl: Prevent potential NULL dereference
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 324dddea321078a6eeb535c2bff5257be74c9799 ]
+
+The btrtl_initialize() function checks that rtl_load_file() either
+had an error or it loaded a zero length file. However, if it loaded
+a zero length file then the error code is not set correctly. It
+results in an error pointer vs NULL bug, followed by a NULL pointer
+dereference. This was detected by Smatch:
+
+drivers/bluetooth/btrtl.c:592 btrtl_initialize() warn: passing zero to 'ERR_PTR'
+
+Fixes: 26503ad25de8 ("Bluetooth: btrtl: split the device initialization into smaller parts")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btrtl.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c
+index 1e7c1f9db9e4b..7f67e460f7f49 100644
+--- a/drivers/bluetooth/btrtl.c
++++ b/drivers/bluetooth/btrtl.c
+@@ -1194,6 +1194,8 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev,
+ rtl_dev_err(hdev, "mandatory config file %s not found",
+ btrtl_dev->ic_info->cfg_name);
+ ret = btrtl_dev->cfg_len;
++ if (!ret)
++ ret = -EINVAL;
+ goto err_free;
+ }
+ }
+--
+2.39.5
+
--- /dev/null
+From b51b2079dab4f72ff609f1c9898ac897a473914c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 13:02:08 -0400
+Subject: Bluetooth: hci_event: Fix sending MGMT_EV_DEVICE_FOUND for invalid
+ address
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit eb73b5a9157221f405b4fe32751da84ee46b7a25 ]
+
+This fixes sending MGMT_EV_DEVICE_FOUND for invalid address
+(00:00:00:00:00:00) which is a regression introduced by
+a2ec905d1e16 ("Bluetooth: fix kernel oops in store_pending_adv_report")
+since in the attempt to skip storing data for extended advertisement it
+actually made the code to skip the entire if statement supposed to send
+MGMT_EV_DEVICE_FOUND without attempting to use the last_addr_adv which
+is garanteed to be invalid for extended advertisement since we never
+store anything on it.
+
+Link: https://github.com/bluez/bluez/issues/1157
+Link: https://github.com/bluez/bluez/issues/1149#issuecomment-2767215658
+Fixes: a2ec905d1e16 ("Bluetooth: fix kernel oops in store_pending_adv_report")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 1e689d8c00a50..4029330e29a99 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -6149,11 +6149,12 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
+ * event or send an immediate device found event if the data
+ * should not be stored for later.
+ */
+- if (!ext_adv && !has_pending_adv_report(hdev)) {
++ if (!has_pending_adv_report(hdev)) {
+ /* If the report will trigger a SCAN_REQ store it for
+ * later merging.
+ */
+- if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
++ if (!ext_adv && (type == LE_ADV_IND ||
++ type == LE_ADV_SCAN_IND)) {
+ store_pending_adv_report(hdev, bdaddr, bdaddr_type,
+ rssi, flags, data, len);
+ return;
+--
+2.39.5
+
--- /dev/null
+From 57868acbd7748c50b00675ebc97ba5450408d2ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 10:53:06 +0200
+Subject: Bluetooth: l2cap: Check encryption key size on incoming connection
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Frédéric Danis <frederic.danis@collabora.com>
+
+[ Upstream commit 522e9ed157e3c21b4dd623c79967f72c21e45b78 ]
+
+This is required for passing GAP/SEC/SEM/BI-04-C PTS test case:
+ Security Mode 4 Level 4, Responder - Invalid Encryption Key Size
+ - 128 bit
+
+This tests the security key with size from 1 to 15 bytes while the
+Security Mode 4 Level 4 requests 16 bytes key size.
+
+Currently PTS fails with the following logs:
+- expected:Connection Response:
+ Code: [3 (0x03)] Code
+ Identifier: (lt)WildCard: Exists(gt)
+ Length: [8 (0x0008)]
+ Destination CID: (lt)WildCard: Exists(gt)
+ Source CID: [64 (0x0040)]
+ Result: [3 (0x0003)] Connection refused - Security block
+ Status: (lt)WildCard: Exists(gt),
+but received:Connection Response:
+ Code: [3 (0x03)] Code
+ Identifier: [1 (0x01)]
+ Length: [8 (0x0008)]
+ Destination CID: [64 (0x0040)]
+ Source CID: [64 (0x0040)]
+ Result: [0 (0x0000)] Connection Successful
+ Status: [0 (0x0000)] No further information available
+
+And HCI logs:
+< HCI Command: Read Encrypti.. (0x05|0x0008) plen 2
+ Handle: 14 Address: 00:1B:DC:F2:24:10 (Vencer Co., Ltd.)
+> HCI Event: Command Complete (0x0e) plen 7
+ Read Encryption Key Size (0x05|0x0008) ncmd 1
+ Status: Success (0x00)
+ Handle: 14 Address: 00:1B:DC:F2:24:10 (Vencer Co., Ltd.)
+ Key size: 7
+> ACL Data RX: Handle 14 flags 0x02 dlen 12
+ L2CAP: Connection Request (0x02) ident 1 len 4
+ PSM: 4097 (0x1001)
+ Source CID: 64
+< ACL Data TX: Handle 14 flags 0x00 dlen 16
+ L2CAP: Connection Response (0x03) ident 1 len 8
+ Destination CID: 64
+ Source CID: 64
+ Result: Connection successful (0x0000)
+ Status: No further information available (0x0000)
+
+Fixes: 288c06973daa ("Bluetooth: Enforce key size of 16 bytes on FIPS level")
+Signed-off-by: Frédéric Danis <frederic.danis@collabora.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 8d6fc18695033..1258532228bbb 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -3954,7 +3954,8 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
+
+ /* Check if the ACL is secure enough (if not SDP) */
+ if (psm != cpu_to_le16(L2CAP_PSM_SDP) &&
+- !hci_conn_check_link_mode(conn->hcon)) {
++ (!hci_conn_check_link_mode(conn->hcon) ||
++ !l2cap_check_enc_key_size(conn->hcon))) {
+ conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
+ result = L2CAP_CR_SEC_BLOCK;
+ goto response;
+--
+2.39.5
+
--- /dev/null
+From 583d368cfc324166e294c5de93dbe29f93fb01a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 11:58:08 +0200
+Subject: cpufreq/sched: Fix the usage of CPUFREQ_NEED_UPDATE_LIMITS
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit cfde542df7dd51d26cf667f4af497878ddffd85a ]
+
+Commit 8e461a1cb43d ("cpufreq: schedutil: Fix superfluous updates caused
+by need_freq_update") modified sugov_should_update_freq() to set the
+need_freq_update flag only for drivers with CPUFREQ_NEED_UPDATE_LIMITS
+set, but that flag generally needs to be set when the policy limits
+change because the driver callback may need to be invoked for the new
+limits to take effect.
+
+However, if the return value of cpufreq_driver_resolve_freq() after
+applying the new limits is still equal to the previously selected
+frequency, the driver callback needs to be invoked only in the case
+when CPUFREQ_NEED_UPDATE_LIMITS is set (which means that the driver
+specifically wants its callback to be invoked every time the policy
+limits change).
+
+Update the code accordingly to avoid missing policy limits changes for
+drivers without CPUFREQ_NEED_UPDATE_LIMITS.
+
+Fixes: 8e461a1cb43d ("cpufreq: schedutil: Fix superfluous updates caused by need_freq_update")
+Closes: https://lore.kernel.org/lkml/Z_Tlc6Qs-tYpxWYb@linaro.org/
+Reported-by: Stephan Gerhold <stephan.gerhold@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Christian Loehle <christian.loehle@arm.com>
+Link: https://patch.msgid.link/3010358.e9J7NaK4W3@rjwysocki.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/cpufreq_schedutil.c | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
+index a49f136014ce6..259521b179aa1 100644
+--- a/kernel/sched/cpufreq_schedutil.c
++++ b/kernel/sched/cpufreq_schedutil.c
+@@ -83,7 +83,7 @@ static bool sugov_should_update_freq(struct sugov_policy *sg_policy, u64 time)
+
+ if (unlikely(sg_policy->limits_changed)) {
+ sg_policy->limits_changed = false;
+- sg_policy->need_freq_update = cpufreq_driver_test_flags(CPUFREQ_NEED_UPDATE_LIMITS);
++ sg_policy->need_freq_update = true;
+ return true;
+ }
+
+@@ -95,10 +95,22 @@ static bool sugov_should_update_freq(struct sugov_policy *sg_policy, u64 time)
+ static bool sugov_update_next_freq(struct sugov_policy *sg_policy, u64 time,
+ unsigned int next_freq)
+ {
+- if (sg_policy->need_freq_update)
++ if (sg_policy->need_freq_update) {
+ sg_policy->need_freq_update = false;
+- else if (sg_policy->next_freq == next_freq)
++ /*
++ * The policy limits have changed, but if the return value of
++ * cpufreq_driver_resolve_freq() after applying the new limits
++ * is still equal to the previously selected frequency, the
++ * driver callback need not be invoked unless the driver
++ * specifically wants that to happen on every update of the
++ * policy limits.
++ */
++ if (sg_policy->next_freq == next_freq &&
++ !cpufreq_driver_test_flags(CPUFREQ_NEED_UPDATE_LIMITS))
++ return false;
++ } else if (sg_policy->next_freq == next_freq) {
+ return false;
++ }
+
+ sg_policy->next_freq = next_freq;
+ sg_policy->last_freq_update_time = time;
+--
+2.39.5
+
--- /dev/null
+From 54486cbec715f15873a12fca363f39d21dc2c257 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 22:36:46 +0530
+Subject: cxgb4: fix memory leak in cxgb4_init_ethtool_filters() error path
+
+From: Abdun Nihaal <abdun.nihaal@gmail.com>
+
+[ Upstream commit 00ffb3724ce743578163f5ade2884374554ca021 ]
+
+In the for loop used to allocate the loc_array and bmap for each port, a
+memory leak is possible when the allocation for loc_array succeeds,
+but the allocation for bmap fails. This is because when the control flow
+goes to the label free_eth_finfo, only the allocations starting from
+(i-1)th iteration are freed.
+
+Fix that by freeing the loc_array in the bmap allocation error path.
+
+Fixes: d915c299f1da ("cxgb4: add skeleton for ethtool n-tuple filters")
+Signed-off-by: Abdun Nihaal <abdun.nihaal@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20250414170649.89156-1-abdun.nihaal@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
+index 8477a93cee6bd..b77897aa06c4f 100644
+--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
+@@ -2273,6 +2273,7 @@ int cxgb4_init_ethtool_filters(struct adapter *adap)
+ eth_filter->port[i].bmap = bitmap_zalloc(nentries, GFP_KERNEL);
+ if (!eth_filter->port[i].bmap) {
+ ret = -ENOMEM;
++ kvfree(eth_filter->port[i].loc_array);
+ goto free_eth_finfo;
+ }
+ }
+--
+2.39.5
+
--- /dev/null
+From b8364f1b6ea1a582da82d981a387a9988c53fb61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 16:35:34 -0700
+Subject: igc: add lock preventing multiple simultaneous PTM transactions
+
+From: Christopher S M Hall <christopher.s.hall@intel.com>
+
+[ Upstream commit 1a931c4f5e6862e61a4b130cb76b422e1415f644 ]
+
+Add a mutex around the PTM transaction to prevent multiple transactors
+
+Multiple processes try to initiate a PTM transaction, one or all may
+fail. This can be reproduced by running two instances of the
+following:
+
+$ sudo phc2sys -O 0 -i tsn0 -m
+
+PHC2SYS exits with:
+
+"ioctl PTP_OFFSET_PRECISE: Connection timed out" when the PTM transaction
+ fails
+
+Note: Normally two instance of PHC2SYS will not run, but one process
+ should not break another.
+
+Fixes: a90ec8483732 ("igc: Add support for PTP getcrosststamp()")
+Signed-off-by: Christopher S M Hall <christopher.s.hall@intel.com>
+Reviewed-by: Corinna Vinschen <vinschen@redhat.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Tested-by: Mor Bar-Gabay <morx.bar.gabay@intel.com>
+Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc.h | 1 +
+ drivers/net/ethernet/intel/igc/igc_ptp.c | 20 ++++++++++++++++++--
+ 2 files changed, 19 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
+index 85cc163965062..49702169a3d8a 100644
+--- a/drivers/net/ethernet/intel/igc/igc.h
++++ b/drivers/net/ethernet/intel/igc/igc.h
+@@ -266,6 +266,7 @@ struct igc_adapter {
+ struct timespec64 prev_ptp_time; /* Pre-reset PTP clock */
+ ktime_t ptp_reset_start; /* Reset time in clock mono */
+ struct system_time_snapshot snapshot;
++ struct mutex ptm_lock; /* Only allow one PTM transaction at a time */
+
+ char fw_version[32];
+
+diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c
+index c5387610ca3df..b6bb01a486d9d 100644
+--- a/drivers/net/ethernet/intel/igc/igc_ptp.c
++++ b/drivers/net/ethernet/intel/igc/igc_ptp.c
+@@ -943,6 +943,7 @@ static void igc_ptm_log_error(struct igc_adapter *adapter, u32 ptm_stat)
+ }
+ }
+
++/* The PTM lock: adapter->ptm_lock must be held when calling igc_ptm_trigger() */
+ static void igc_ptm_trigger(struct igc_hw *hw)
+ {
+ u32 ctrl;
+@@ -959,6 +960,7 @@ static void igc_ptm_trigger(struct igc_hw *hw)
+ wrfl();
+ }
+
++/* The PTM lock: adapter->ptm_lock must be held when calling igc_ptm_reset() */
+ static void igc_ptm_reset(struct igc_hw *hw)
+ {
+ u32 ctrl;
+@@ -1037,9 +1039,16 @@ static int igc_ptp_getcrosststamp(struct ptp_clock_info *ptp,
+ {
+ struct igc_adapter *adapter = container_of(ptp, struct igc_adapter,
+ ptp_caps);
++ int ret;
+
+- return get_device_system_crosststamp(igc_phc_get_syncdevicetime,
+- adapter, &adapter->snapshot, cts);
++ /* This blocks until any in progress PTM transactions complete */
++ mutex_lock(&adapter->ptm_lock);
++
++ ret = get_device_system_crosststamp(igc_phc_get_syncdevicetime,
++ adapter, &adapter->snapshot, cts);
++ mutex_unlock(&adapter->ptm_lock);
++
++ return ret;
+ }
+
+ /**
+@@ -1116,6 +1125,7 @@ void igc_ptp_init(struct igc_adapter *adapter)
+
+ spin_lock_init(&adapter->ptp_tx_lock);
+ spin_lock_init(&adapter->tmreg_lock);
++ mutex_init(&adapter->ptm_lock);
+
+ adapter->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
+ adapter->tstamp_config.tx_type = HWTSTAMP_TX_OFF;
+@@ -1128,6 +1138,7 @@ void igc_ptp_init(struct igc_adapter *adapter)
+ if (IS_ERR(adapter->ptp_clock)) {
+ adapter->ptp_clock = NULL;
+ netdev_err(netdev, "ptp_clock_register failed\n");
++ mutex_destroy(&adapter->ptm_lock);
+ } else if (adapter->ptp_clock) {
+ netdev_info(netdev, "PHC added\n");
+ adapter->ptp_flags |= IGC_PTP_ENABLED;
+@@ -1157,10 +1168,12 @@ static void igc_ptm_stop(struct igc_adapter *adapter)
+ struct igc_hw *hw = &adapter->hw;
+ u32 ctrl;
+
++ mutex_lock(&adapter->ptm_lock);
+ ctrl = rd32(IGC_PTM_CTRL);
+ ctrl &= ~IGC_PTM_CTRL_EN;
+
+ wr32(IGC_PTM_CTRL, ctrl);
++ mutex_unlock(&adapter->ptm_lock);
+ }
+
+ /**
+@@ -1202,6 +1215,7 @@ void igc_ptp_stop(struct igc_adapter *adapter)
+ netdev_info(adapter->netdev, "PHC removed\n");
+ adapter->ptp_flags &= ~IGC_PTP_ENABLED;
+ }
++ mutex_destroy(&adapter->ptm_lock);
+ }
+
+ /**
+@@ -1241,6 +1255,7 @@ void igc_ptp_reset(struct igc_adapter *adapter)
+ if (!igc_is_crosststamp_supported(adapter))
+ break;
+
++ mutex_lock(&adapter->ptm_lock);
+ wr32(IGC_PCIE_DIG_DELAY, IGC_PCIE_DIG_DELAY_DEFAULT);
+ wr32(IGC_PCIE_PHY_DELAY, IGC_PCIE_PHY_DELAY_DEFAULT);
+
+@@ -1264,6 +1279,7 @@ void igc_ptp_reset(struct igc_adapter *adapter)
+ netdev_err(adapter->netdev, "Timeout reading IGC_PTM_STAT register\n");
+
+ igc_ptm_reset(hw);
++ mutex_unlock(&adapter->ptm_lock);
+ break;
+ default:
+ /* No work to do. */
+--
+2.39.5
+
--- /dev/null
+From 46302b5993c5f44bb8865e7d16f4c5b8d828c377 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 16:35:33 -0700
+Subject: igc: cleanup PTP module if probe fails
+
+From: Christopher S M Hall <christopher.s.hall@intel.com>
+
+[ Upstream commit 1f025759ba394dd53e434d2668cb0597886d9b69 ]
+
+Make sure that the PTP module is cleaned up if the igc_probe() fails by
+calling igc_ptp_stop() on exit.
+
+Fixes: d89f88419f99 ("igc: Add skeletal frame for Intel(R) 2.5G Ethernet Controller support")
+Signed-off-by: Christopher S M Hall <christopher.s.hall@intel.com>
+Reviewed-by: Corinna Vinschen <vinschen@redhat.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Tested-by: Mor Bar-Gabay <morx.bar.gabay@intel.com>
+Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc_main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
+index ae93b45cf55e8..e2f5c4384455e 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -6951,6 +6951,7 @@ static int igc_probe(struct pci_dev *pdev,
+
+ err_register:
+ igc_release_hw_control(adapter);
++ igc_ptp_stop(adapter);
+ err_eeprom:
+ if (!igc_check_reset_block(hw))
+ igc_reset_phy(hw);
+--
+2.39.5
+
--- /dev/null
+From 13762339f3c4128908e50fcc365fc526572cfa7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 16:35:29 -0700
+Subject: igc: fix PTM cycle trigger logic
+
+From: Christopher S M Hall <christopher.s.hall@intel.com>
+
+[ Upstream commit 8e404ad95d2c10c261e2ef6992c7c12dde03df0e ]
+
+Writing to clear the PTM status 'valid' bit while the PTM cycle is
+triggered results in unreliable PTM operation. To fix this, clear the
+PTM 'trigger' and status after each PTM transaction.
+
+The issue can be reproduced with the following:
+
+$ sudo phc2sys -R 1000 -O 0 -i tsn0 -m
+
+Note: 1000 Hz (-R 1000) is unrealistically large, but provides a way to
+quickly reproduce the issue.
+
+PHC2SYS exits with:
+
+"ioctl PTP_OFFSET_PRECISE: Connection timed out" when the PTM transaction
+ fails
+
+This patch also fixes a hang in igc_probe() when loading the igc
+driver in the kdump kernel on systems supporting PTM.
+
+The igc driver running in the base kernel enables PTM trigger in
+igc_probe(). Therefore the driver is always in PTM trigger mode,
+except in brief periods when manually triggering a PTM cycle.
+
+When a crash occurs, the NIC is reset while PTM trigger is enabled.
+Due to a hardware problem, the NIC is subsequently in a bad busmaster
+state and doesn't handle register reads/writes. When running
+igc_probe() in the kdump kernel, the first register access to a NIC
+register hangs driver probing and ultimately breaks kdump.
+
+With this patch, igc has PTM trigger disabled most of the time,
+and the trigger is only enabled for very brief (10 - 100 us) periods
+when manually triggering a PTM cycle. Chances that a crash occurs
+during a PTM trigger are not 0, but extremely reduced.
+
+Fixes: a90ec8483732 ("igc: Add support for PTP getcrosststamp()")
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Tested-by: Mor Bar-Gabay <morx.bar.gabay@intel.com>
+Tested-by: Avigail Dahan <avigailx.dahan@intel.com>
+Signed-off-by: Christopher S M Hall <christopher.s.hall@intel.com>
+Reviewed-by: Corinna Vinschen <vinschen@redhat.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Tested-by: Corinna Vinschen <vinschen@redhat.com>
+Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc_defines.h | 1 +
+ drivers/net/ethernet/intel/igc/igc_ptp.c | 70 ++++++++++++--------
+ 2 files changed, 42 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h
+index a18af5c87cde4..2a84beaf5e680 100644
+--- a/drivers/net/ethernet/intel/igc/igc_defines.h
++++ b/drivers/net/ethernet/intel/igc/igc_defines.h
+@@ -581,6 +581,7 @@
+ #define IGC_PTM_STAT_T4M1_OVFL BIT(3) /* T4 minus T1 overflow */
+ #define IGC_PTM_STAT_ADJUST_1ST BIT(4) /* 1588 timer adjusted during 1st PTM cycle */
+ #define IGC_PTM_STAT_ADJUST_CYC BIT(5) /* 1588 timer adjusted during non-1st PTM cycle */
++#define IGC_PTM_STAT_ALL GENMASK(5, 0) /* Used to clear all status */
+
+ /* PCIe PTM Cycle Control */
+ #define IGC_PTM_CYCLE_CTRL_CYC_TIME(msec) ((msec) & 0x3ff) /* PTM Cycle Time (msec) */
+diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c
+index 928f38792203a..097a481e6b73d 100644
+--- a/drivers/net/ethernet/intel/igc/igc_ptp.c
++++ b/drivers/net/ethernet/intel/igc/igc_ptp.c
+@@ -943,13 +943,40 @@ static void igc_ptm_log_error(struct igc_adapter *adapter, u32 ptm_stat)
+ }
+ }
+
++static void igc_ptm_trigger(struct igc_hw *hw)
++{
++ u32 ctrl;
++
++ /* To "manually" start the PTM cycle we need to set the
++ * trigger (TRIG) bit
++ */
++ ctrl = rd32(IGC_PTM_CTRL);
++ ctrl |= IGC_PTM_CTRL_TRIG;
++ wr32(IGC_PTM_CTRL, ctrl);
++ /* Perform flush after write to CTRL register otherwise
++ * transaction may not start
++ */
++ wrfl();
++}
++
++static void igc_ptm_reset(struct igc_hw *hw)
++{
++ u32 ctrl;
++
++ ctrl = rd32(IGC_PTM_CTRL);
++ ctrl &= ~IGC_PTM_CTRL_TRIG;
++ wr32(IGC_PTM_CTRL, ctrl);
++ /* Write to clear all status */
++ wr32(IGC_PTM_STAT, IGC_PTM_STAT_ALL);
++}
++
+ static int igc_phc_get_syncdevicetime(ktime_t *device,
+ struct system_counterval_t *system,
+ void *ctx)
+ {
+- u32 stat, t2_curr_h, t2_curr_l, ctrl;
+ struct igc_adapter *adapter = ctx;
+ struct igc_hw *hw = &adapter->hw;
++ u32 stat, t2_curr_h, t2_curr_l;
+ int err, count = 100;
+ ktime_t t1, t2_curr;
+
+@@ -963,25 +990,13 @@ static int igc_phc_get_syncdevicetime(ktime_t *device,
+ * are transitory. Repeating the process returns valid
+ * data eventually.
+ */
+-
+- /* To "manually" start the PTM cycle we need to clear and
+- * then set again the TRIG bit.
+- */
+- ctrl = rd32(IGC_PTM_CTRL);
+- ctrl &= ~IGC_PTM_CTRL_TRIG;
+- wr32(IGC_PTM_CTRL, ctrl);
+- ctrl |= IGC_PTM_CTRL_TRIG;
+- wr32(IGC_PTM_CTRL, ctrl);
+-
+- /* The cycle only starts "for real" when software notifies
+- * that it has read the registers, this is done by setting
+- * VALID bit.
+- */
+- wr32(IGC_PTM_STAT, IGC_PTM_STAT_VALID);
++ igc_ptm_trigger(hw);
+
+ err = readx_poll_timeout(rd32, IGC_PTM_STAT, stat,
+ stat, IGC_PTM_STAT_SLEEP,
+ IGC_PTM_STAT_TIMEOUT);
++ igc_ptm_reset(hw);
++
+ if (err < 0) {
+ netdev_err(adapter->netdev, "Timeout reading IGC_PTM_STAT register\n");
+ return err;
+@@ -990,15 +1005,7 @@ static int igc_phc_get_syncdevicetime(ktime_t *device,
+ if ((stat & IGC_PTM_STAT_VALID) == IGC_PTM_STAT_VALID)
+ break;
+
+- if (stat & ~IGC_PTM_STAT_VALID) {
+- /* An error occurred, log it. */
+- igc_ptm_log_error(adapter, stat);
+- /* The STAT register is write-1-to-clear (W1C),
+- * so write the previous error status to clear it.
+- */
+- wr32(IGC_PTM_STAT, stat);
+- continue;
+- }
++ igc_ptm_log_error(adapter, stat);
+ } while (--count);
+
+ if (!count) {
+@@ -1202,7 +1209,7 @@ void igc_ptp_stop(struct igc_adapter *adapter)
+ void igc_ptp_reset(struct igc_adapter *adapter)
+ {
+ struct igc_hw *hw = &adapter->hw;
+- u32 cycle_ctrl, ctrl;
++ u32 cycle_ctrl, ctrl, stat;
+ unsigned long flags;
+ u32 timadj;
+
+@@ -1237,14 +1244,19 @@ void igc_ptp_reset(struct igc_adapter *adapter)
+ ctrl = IGC_PTM_CTRL_EN |
+ IGC_PTM_CTRL_START_NOW |
+ IGC_PTM_CTRL_SHRT_CYC(IGC_PTM_SHORT_CYC_DEFAULT) |
+- IGC_PTM_CTRL_PTM_TO(IGC_PTM_TIMEOUT_DEFAULT) |
+- IGC_PTM_CTRL_TRIG;
++ IGC_PTM_CTRL_PTM_TO(IGC_PTM_TIMEOUT_DEFAULT);
+
+ wr32(IGC_PTM_CTRL, ctrl);
+
+ /* Force the first cycle to run. */
+- wr32(IGC_PTM_STAT, IGC_PTM_STAT_VALID);
++ igc_ptm_trigger(hw);
++
++ if (readx_poll_timeout_atomic(rd32, IGC_PTM_STAT, stat,
++ stat, IGC_PTM_STAT_SLEEP,
++ IGC_PTM_STAT_TIMEOUT))
++ netdev_err(adapter->netdev, "Timeout reading IGC_PTM_STAT register\n");
+
++ igc_ptm_reset(hw);
+ break;
+ default:
+ /* No work to do. */
+--
+2.39.5
+
--- /dev/null
+From a9e5d26f29f7d85c4d35433afc910f76b6959f54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 16:35:32 -0700
+Subject: igc: handle the IGC_PTP_ENABLED flag correctly
+
+From: Christopher S M Hall <christopher.s.hall@intel.com>
+
+[ Upstream commit 26a3910afd111f7c1a96dace6dc02f3225063896 ]
+
+All functions in igc_ptp.c called from igc_main.c should check the
+IGC_PTP_ENABLED flag. Adding check for this flag to stop and reset
+functions.
+
+Fixes: 5f2958052c58 ("igc: Add basic skeleton for PTP")
+Signed-off-by: Christopher S M Hall <christopher.s.hall@intel.com>
+Reviewed-by: Corinna Vinschen <vinschen@redhat.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Tested-by: Mor Bar-Gabay <morx.bar.gabay@intel.com>
+Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc_ptp.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c
+index adb31cccaf9a5..c5387610ca3df 100644
+--- a/drivers/net/ethernet/intel/igc/igc_ptp.c
++++ b/drivers/net/ethernet/intel/igc/igc_ptp.c
+@@ -1191,8 +1191,12 @@ void igc_ptp_suspend(struct igc_adapter *adapter)
+ **/
+ void igc_ptp_stop(struct igc_adapter *adapter)
+ {
++ if (!(adapter->ptp_flags & IGC_PTP_ENABLED))
++ return;
++
+ igc_ptp_suspend(adapter);
+
++ adapter->ptp_flags &= ~IGC_PTP_ENABLED;
+ if (adapter->ptp_clock) {
+ ptp_clock_unregister(adapter->ptp_clock);
+ netdev_info(adapter->netdev, "PHC removed\n");
+@@ -1213,6 +1217,9 @@ void igc_ptp_reset(struct igc_adapter *adapter)
+ unsigned long flags;
+ u32 timadj;
+
++ if (!(adapter->ptp_flags & IGC_PTP_ENABLED))
++ return;
++
+ /* reset the tstamp_config */
+ igc_ptp_set_timestamp_mode(adapter, &adapter->tstamp_config);
+
+--
+2.39.5
+
--- /dev/null
+From 7bded129510c76a5e572698dd3a512980b386f2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 16:35:30 -0700
+Subject: igc: increase wait time before retrying PTM
+
+From: Christopher S M Hall <christopher.s.hall@intel.com>
+
+[ Upstream commit 714cd033da6fea4cf54a11b3cfd070afde3f31df ]
+
+The i225/i226 hardware retries if it receives an inappropriate response
+from the upstream device. If the device retries too quickly, the root
+port does not respond.
+
+The wait between attempts was reduced from 10us to 1us in commit
+6b8aa753a9f9 ("igc: Decrease PTM short interval from 10 us to 1 us"), which
+said:
+
+ With the 10us interval, we were seeing PTM transactions take around
+ 12us. Hardware team suggested this interval could be lowered to 1us
+ which was confirmed with PCIe sniffer. With the 1us interval, PTM
+ dialogs took around 2us.
+
+While a 1us short cycle time was thought to be theoretically sufficient, it
+turns out in practice it is not quite long enough. It is unclear if the
+problem is in the root port or an issue in i225/i226.
+
+Increase the wait from 1us to 4us. Increasing to 2us appeared to work in
+practice on the setups we have available. A value of 4us was chosen due to
+the limited hardware available for testing, with a goal of ensuring we wait
+long enough without overly penalizing the response time when unnecessary.
+
+The issue can be reproduced with the following:
+
+$ sudo phc2sys -R 1000 -O 0 -i tsn0 -m
+
+Note: 1000 Hz (-R 1000) is unrealistically large, but provides a way to
+quickly reproduce the issue.
+
+PHC2SYS exits with:
+
+"ioctl PTP_OFFSET_PRECISE: Connection timed out" when the PTM transaction
+ fails
+
+Fixes: 6b8aa753a9f9 ("igc: Decrease PTM short interval from 10 us to 1 us")
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Tested-by: Mor Bar-Gabay <morx.bar.gabay@intel.com>
+Tested-by: Avigail Dahan <avigailx.dahan@intel.com>
+Signed-off-by: Christopher S M Hall <christopher.s.hall@intel.com>
+Reviewed-by: Corinna Vinschen <vinschen@redhat.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc_defines.h | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h
+index 2a84beaf5e680..cf8b5ac51caaa 100644
+--- a/drivers/net/ethernet/intel/igc/igc_defines.h
++++ b/drivers/net/ethernet/intel/igc/igc_defines.h
+@@ -562,7 +562,10 @@
+ #define IGC_PTM_CTRL_SHRT_CYC(usec) (((usec) & 0x3f) << 2)
+ #define IGC_PTM_CTRL_PTM_TO(usec) (((usec) & 0xff) << 8)
+
+-#define IGC_PTM_SHORT_CYC_DEFAULT 1 /* Default short cycle interval */
++/* A short cycle time of 1us theoretically should work, but appears to be too
++ * short in practice.
++ */
++#define IGC_PTM_SHORT_CYC_DEFAULT 4 /* Default short cycle interval */
+ #define IGC_PTM_CYC_TIME_DEFAULT 5 /* Default PTM cycle time */
+ #define IGC_PTM_TIMEOUT_DEFAULT 255 /* Default timeout for PTM errors */
+
+--
+2.39.5
+
--- /dev/null
+From 3be1d8984f8bcdc7a35b3c4ae16f63246d9b0823 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 16:35:31 -0700
+Subject: igc: move ktime snapshot into PTM retry loop
+
+From: Christopher S M Hall <christopher.s.hall@intel.com>
+
+[ Upstream commit cd7f7328d691937102732f39f97ead35b15bf803 ]
+
+Move ktime_get_snapshot() into the loop. If a retry does occur, a more
+recent snapshot will result in a more accurate cross-timestamp.
+
+Fixes: a90ec8483732 ("igc: Add support for PTP getcrosststamp()")
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Tested-by: Mor Bar-Gabay <morx.bar.gabay@intel.com>
+Tested-by: Avigail Dahan <avigailx.dahan@intel.com>
+Signed-off-by: Christopher S M Hall <christopher.s.hall@intel.com>
+Reviewed-by: Corinna Vinschen <vinschen@redhat.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc_ptp.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c
+index 097a481e6b73d..adb31cccaf9a5 100644
+--- a/drivers/net/ethernet/intel/igc/igc_ptp.c
++++ b/drivers/net/ethernet/intel/igc/igc_ptp.c
+@@ -980,16 +980,16 @@ static int igc_phc_get_syncdevicetime(ktime_t *device,
+ int err, count = 100;
+ ktime_t t1, t2_curr;
+
+- /* Get a snapshot of system clocks to use as historic value. */
+- ktime_get_snapshot(&adapter->snapshot);
+-
++ /* Doing this in a loop because in the event of a
++ * badly timed (ha!) system clock adjustment, we may
++ * get PTM errors from the PCI root, but these errors
++ * are transitory. Repeating the process returns valid
++ * data eventually.
++ */
+ do {
+- /* Doing this in a loop because in the event of a
+- * badly timed (ha!) system clock adjustment, we may
+- * get PTM errors from the PCI root, but these errors
+- * are transitory. Repeating the process returns valid
+- * data eventually.
+- */
++ /* Get a snapshot of system clocks to use as historic value. */
++ ktime_get_snapshot(&adapter->snapshot);
++
+ igc_ptm_trigger(hw);
+
+ err = readx_poll_timeout(rd32, IGC_PTM_STAT, stat,
+--
+2.39.5
+
--- /dev/null
+From d91cb4130c06f4b047b9e343e47b0c3a9adb2bd0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 10:58:03 +0200
+Subject: kunit: qemu_configs: SH: Respect kunit cmdline
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
+
+[ Upstream commit b26c1a85f3fc3cc749380ff94199377fc2d0c203 ]
+
+The default SH kunit configuration sets CONFIG_CMDLINE_OVERWRITE which
+completely disregards the cmdline passed from the bootloader/QEMU in favor
+of the builtin CONFIG_CMDLINE.
+However the kunit tool needs to pass arguments to the in-kernel kunit core,
+for filters and other runtime parameters.
+
+Enable CONFIG_CMDLINE_EXTEND instead, so kunit arguments are respected.
+
+Link: https://lore.kernel.org/r/20250407-kunit-sh-v1-1-f5432a54cf2f@linutronix.de
+Fixes: 8110a3cab05e ("kunit: tool: Add support for SH under QEMU")
+Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
+Reviewed-by: David Gow <davidgow@google.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/kunit/qemu_configs/sh.py | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/kunit/qemu_configs/sh.py b/tools/testing/kunit/qemu_configs/sh.py
+index 78a474a5b95f3..f00cb89fdef6a 100644
+--- a/tools/testing/kunit/qemu_configs/sh.py
++++ b/tools/testing/kunit/qemu_configs/sh.py
+@@ -7,7 +7,9 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
+ CONFIG_MEMORY_START=0x0c000000
+ CONFIG_SH_RTS7751R2D=y
+ CONFIG_RTS7751R2D_PLUS=y
+-CONFIG_SERIAL_SH_SCI=y''',
++CONFIG_SERIAL_SH_SCI=y
++CONFIG_CMDLINE_EXTEND=y
++''',
+ qemu_arch='sh4',
+ kernel_path='arch/sh/boot/zImage',
+ kernel_command_line='console=ttySC1',
+--
+2.39.5
+
--- /dev/null
+From 7468016cca87785ad9e48ab5e85117f9df893d21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 09:53:22 +0800
+Subject: md/md-bitmap: fix stats collection for external bitmaps
+
+From: Zheng Qixing <zhengqixing@huawei.com>
+
+[ Upstream commit 6ec1f0239485028445d213d91cfee5242f3211ba ]
+
+The bitmap_get_stats() function incorrectly returns -ENOENT for external
+bitmaps.
+
+Remove the external bitmap check as the statistics should be available
+regardless of bitmap storage location.
+
+Return -EINVAL only for invalid bitmap with no storage (neither in
+superblock nor in external file).
+
+Note: "bitmap_info.external" here refers to a bitmap stored in a separate
+file (bitmap_file), not to external metadata.
+
+Fixes: 8d28d0ddb986 ("md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime")
+Signed-off-by: Zheng Qixing <zhengqixing@huawei.com>
+Link: https://lore.kernel.org/linux-raid/20250403015322.2873369-1-zhengqixing@huaweicloud.com
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md-bitmap.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
+index deb40a8ba3999..8317e07b326d0 100644
+--- a/drivers/md/md-bitmap.c
++++ b/drivers/md/md-bitmap.c
+@@ -2119,9 +2119,8 @@ int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats)
+
+ if (!bitmap)
+ return -ENOENT;
+- if (bitmap->mddev->bitmap_info.external)
+- return -ENOENT;
+- if (!bitmap->storage.sb_page) /* no superblock */
++ if (!bitmap->mddev->bitmap_info.external &&
++ !bitmap->storage.sb_page)
+ return -EINVAL;
+ sb = kmap_local_page(bitmap->storage.sb_page);
+ stats->sync_size = le64_to_cpu(sb->sync_size);
+--
+2.39.5
+
--- /dev/null
+From 05a9bb148e664b7a46af9861f6a5dd364394e50c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Mar 2025 09:57:46 +0800
+Subject: md/raid10: fix missing discard IO accounting
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit d05af90d6218e9c8f1c2026990c3f53c1b41bfb0 ]
+
+md_account_bio() is not called from raid10_handle_discard(), now that we
+handle bitmap inside md_account_bio(), also fix missing
+bitmap_startwrite for discard.
+
+Test whole disk discard for 20G raid10:
+
+Before:
+Device d/s dMB/s drqm/s %drqm d_await dareq-sz
+md0 48.00 16.00 0.00 0.00 5.42 341.33
+
+After:
+Device d/s dMB/s drqm/s %drqm d_await dareq-sz
+md0 68.00 20462.00 0.00 0.00 2.65 308133.65
+
+Link: https://lore.kernel.org/linux-raid/20250325015746.3195035-1-yukuai1@huaweicloud.com
+Fixes: 528bc2cf2fcc ("md/raid10: enable io accounting")
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Acked-by: Coly Li <colyli@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid10.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index c300fd609ef08..36b6bf3f8b29f 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -1756,6 +1756,7 @@ static int raid10_handle_discard(struct mddev *mddev, struct bio *bio)
+ * The discard bio returns only first r10bio finishes
+ */
+ if (first_copy) {
++ md_account_bio(mddev, &bio);
+ r10_bio->master_bio = bio;
+ set_bit(R10BIO_Discard, &r10_bio->state);
+ first_copy = false;
+--
+2.39.5
+
--- /dev/null
+From dcf7a57eb3c321b7e60968d6998c8f9a914be75f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 22:04:34 +0200
+Subject: net: b53: enable BPDU reception for management port
+
+From: Jonas Gorski <jonas.gorski@gmail.com>
+
+[ Upstream commit 36355ddfe8955f226a88a543ed354b9f6b84cd70 ]
+
+For STP to work, receiving BPDUs is essential, but the appropriate bit
+was never set. Without GC_RX_BPDU_EN, the switch chip will filter all
+BPDUs, even if an appropriate PVID VLAN was setup.
+
+Fixes: ff39c2d68679 ("net: dsa: b53: Add bridge support")
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Link: https://patch.msgid.link/20250414200434.194422-1-jonas.gorski@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/b53/b53_common.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
+index 4a2c9a9134d8c..cfcda893f1a16 100644
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -724,6 +724,15 @@ static void b53_enable_mib(struct b53_device *dev)
+ b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, gc);
+ }
+
++static void b53_enable_stp(struct b53_device *dev)
++{
++ u8 gc;
++
++ b53_read8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, &gc);
++ gc |= GC_RX_BPDU_EN;
++ b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, gc);
++}
++
+ static u16 b53_default_pvid(struct b53_device *dev)
+ {
+ if (is5325(dev) || is5365(dev))
+@@ -863,6 +872,7 @@ static int b53_switch_reset(struct b53_device *dev)
+ }
+
+ b53_enable_mib(dev);
++ b53_enable_stp(dev);
+
+ return b53_flush_arl(dev, FAST_AGE_STATIC);
+ }
+--
+2.39.5
+
--- /dev/null
+From 2090e6084790e422c283440ae28e4ab47ce49436 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 22:00:20 +0200
+Subject: net: bridge: switchdev: do not notify new brentries as changed
+
+From: Jonas Gorski <jonas.gorski@gmail.com>
+
+[ Upstream commit eb25de13bd9cf025413a04f25e715d0e99847e30 ]
+
+When adding a bridge vlan that is pvid or untagged after the vlan has
+already been added to any other switchdev backed port, the vlan change
+will be propagated as changed, since the flags change.
+
+This causes the vlan to not be added to the hardware for DSA switches,
+since the DSA handler ignores any vlans for the CPU or DSA ports that
+are changed.
+
+E.g. the following order of operations would work:
+
+$ ip link add swbridge type bridge vlan_filtering 1 vlan_default_pvid 0
+$ ip link set lan1 master swbridge
+$ bridge vlan add dev swbridge vid 1 pvid untagged self
+$ bridge vlan add dev lan1 vid 1 pvid untagged
+
+but this order would break:
+
+$ ip link add swbridge type bridge vlan_filtering 1 vlan_default_pvid 0
+$ ip link set lan1 master swbridge
+$ bridge vlan add dev lan1 vid 1 pvid untagged
+$ bridge vlan add dev swbridge vid 1 pvid untagged self
+
+Additionally, the vlan on the bridge itself would become undeletable:
+
+$ bridge vlan
+port vlan-id
+lan1 1 PVID Egress Untagged
+swbridge 1 PVID Egress Untagged
+$ bridge vlan del dev swbridge vid 1 self
+$ bridge vlan
+port vlan-id
+lan1 1 PVID Egress Untagged
+swbridge 1 Egress Untagged
+
+since the vlan was never added to DSA's vlan list, so deleting it will
+cause an error, causing the bridge code to not remove it.
+
+Fix this by checking if flags changed only for vlans that are already
+brentry and pass changed as false for those that become brentries, as
+these are a new vlan (member) from the switchdev point of view.
+
+Since *changed is set to true for becomes_brentry = true regardless of
+would_change's value, this will not change any rtnetlink notification
+delivery, just the value passed on to switchdev in vlan->changed.
+
+Fixes: 8d23a54f5bee ("net: bridge: switchdev: differentiate new VLANs from changed ones")
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
+Link: https://patch.msgid.link/20250414200020.192715-1-jonas.gorski@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/br_vlan.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
+index be714b4d7b430..a1c22eab71ffe 100644
+--- a/net/bridge/br_vlan.c
++++ b/net/bridge/br_vlan.c
+@@ -715,8 +715,8 @@ static int br_vlan_add_existing(struct net_bridge *br,
+ u16 flags, bool *changed,
+ struct netlink_ext_ack *extack)
+ {
+- bool would_change = __vlan_flags_would_change(vlan, flags);
+ bool becomes_brentry = false;
++ bool would_change = false;
+ int err;
+
+ if (!br_vlan_is_brentry(vlan)) {
+@@ -725,6 +725,8 @@ static int br_vlan_add_existing(struct net_bridge *br,
+ return -EINVAL;
+
+ becomes_brentry = true;
++ } else {
++ would_change = __vlan_flags_would_change(vlan, flags);
+ }
+
+ /* Master VLANs that aren't brentries weren't notified before,
+--
+2.39.5
+
--- /dev/null
+From b3a87046b225c7a4df87a96edfe524c15357592b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 00:30:20 +0300
+Subject: net: dsa: avoid refcount warnings when ds->ops->tag_8021q_vlan_del()
+ fails
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 514eff7b0aa1c5eb645ddbb8676ef3e2d88a8b99 ]
+
+This is very similar to the problem and solution from commit
+232deb3f9567 ("net: dsa: avoid refcount warnings when
+->port_{fdb,mdb}_del returns error"), except for the
+dsa_port_do_tag_8021q_vlan_del() operation.
+
+Fixes: c64b9c05045a ("net: dsa: tag_8021q: add proper cross-chip notifier support")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250414213020.2959021-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/dsa/tag_8021q.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/dsa/tag_8021q.c b/net/dsa/tag_8021q.c
+index cbdfc392f7e0d..a5420421e462e 100644
+--- a/net/dsa/tag_8021q.c
++++ b/net/dsa/tag_8021q.c
+@@ -197,7 +197,7 @@ static int dsa_port_do_tag_8021q_vlan_del(struct dsa_port *dp, u16 vid)
+
+ err = ds->ops->tag_8021q_vlan_del(ds, port, vid);
+ if (err) {
+- refcount_inc(&v->refcount);
++ refcount_set(&v->refcount, 1);
+ return err;
+ }
+
+--
+2.39.5
+
--- /dev/null
+From dcdf91441c08173df50d5721b8b20f3339691498 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 00:29:30 +0300
+Subject: net: dsa: clean up FDB, MDB, VLAN entries on unbind
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 7afb5fb42d4950f33af2732b8147c552659f79b7 ]
+
+As explained in many places such as commit b117e1e8a86d ("net: dsa:
+delete dsa_legacy_fdb_add and dsa_legacy_fdb_del"), DSA is written given
+the assumption that higher layers have balanced additions/deletions.
+As such, it only makes sense to be extremely vocal when those
+assumptions are violated and the driver unbinds with entries still
+present.
+
+But Ido Schimmel points out a very simple situation where that is wrong:
+https://lore.kernel.org/netdev/ZDazSM5UsPPjQuKr@shredder/
+(also briefly discussed by me in the aforementioned commit).
+
+Basically, while the bridge bypass operations are not something that DSA
+explicitly documents, and for the majority of DSA drivers this API
+simply causes them to go to promiscuous mode, that isn't the case for
+all drivers. Some have the necessary requirements for bridge bypass
+operations to do something useful - see dsa_switch_supports_uc_filtering().
+
+Although in tools/testing/selftests/net/forwarding/local_termination.sh,
+we made an effort to popularize better mechanisms to manage address
+filters on DSA interfaces from user space - namely macvlan for unicast,
+and setsockopt(IP_ADD_MEMBERSHIP) - through mtools - for multicast, the
+fact is that 'bridge fdb add ... self static local' also exists as
+kernel UAPI, and might be useful to someone, even if only for a quick
+hack.
+
+It seems counter-productive to block that path by implementing shim
+.ndo_fdb_add and .ndo_fdb_del operations which just return -EOPNOTSUPP
+in order to prevent the ndo_dflt_fdb_add() and ndo_dflt_fdb_del() from
+running, although we could do that.
+
+Accepting that cleanup is necessary seems to be the only option.
+Especially since we appear to be coming back at this from a different
+angle as well. Russell King is noticing that the WARN_ON() triggers even
+for VLANs:
+https://lore.kernel.org/netdev/Z_li8Bj8bD4-BYKQ@shell.armlinux.org.uk/
+
+What happens in the bug report above is that dsa_port_do_vlan_del() fails,
+then the VLAN entry lingers on, and then we warn on unbind and leak it.
+
+This is not a straight revert of the blamed commit, but we now add an
+informational print to the kernel log (to still have a way to see
+that bugs exist), and some extra comments gathered from past years'
+experience, to justify the logic.
+
+Fixes: 0832cd9f1f02 ("net: dsa: warn if port lists aren't empty in dsa_port_teardown")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250414212930.2956310-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/dsa/dsa.c | 38 +++++++++++++++++++++++++++++++++++---
+ 1 file changed, 35 insertions(+), 3 deletions(-)
+
+diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
+index ccbdb98109f80..399675c5fcc7f 100644
+--- a/net/dsa/dsa.c
++++ b/net/dsa/dsa.c
+@@ -1483,12 +1483,44 @@ static int dsa_switch_parse(struct dsa_switch *ds, struct dsa_chip_data *cd)
+
+ static void dsa_switch_release_ports(struct dsa_switch *ds)
+ {
++ struct dsa_mac_addr *a, *tmp;
+ struct dsa_port *dp, *next;
++ struct dsa_vlan *v, *n;
+
+ dsa_switch_for_each_port_safe(dp, next, ds) {
+- WARN_ON(!list_empty(&dp->fdbs));
+- WARN_ON(!list_empty(&dp->mdbs));
+- WARN_ON(!list_empty(&dp->vlans));
++ /* These are either entries that upper layers lost track of
++ * (probably due to bugs), or installed through interfaces
++ * where one does not necessarily have to remove them, like
++ * ndo_dflt_fdb_add().
++ */
++ list_for_each_entry_safe(a, tmp, &dp->fdbs, list) {
++ dev_info(ds->dev,
++ "Cleaning up unicast address %pM vid %u from port %d\n",
++ a->addr, a->vid, dp->index);
++ list_del(&a->list);
++ kfree(a);
++ }
++
++ list_for_each_entry_safe(a, tmp, &dp->mdbs, list) {
++ dev_info(ds->dev,
++ "Cleaning up multicast address %pM vid %u from port %d\n",
++ a->addr, a->vid, dp->index);
++ list_del(&a->list);
++ kfree(a);
++ }
++
++ /* These are entries that upper layers have lost track of,
++ * probably due to bugs, but also due to dsa_port_do_vlan_del()
++ * having failed and the VLAN entry still lingering on.
++ */
++ list_for_each_entry_safe(v, n, &dp->vlans, list) {
++ dev_info(ds->dev,
++ "Cleaning up vid %u from port %d\n",
++ v->vid, dp->index);
++ list_del(&v->list);
++ kfree(v);
++ }
++
+ list_del(&dp->list);
+ kfree(dp);
+ }
+--
+2.39.5
+
--- /dev/null
+From 5a863d4118afdf70b72847ce85d5cc7b77fa9948 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 00:30:01 +0300
+Subject: net: dsa: free routing table on probe failure
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 8bf108d7161ffc6880ad13a0cc109de3cf631727 ]
+
+If complete = true in dsa_tree_setup(), it means that we are the last
+switch of the tree which is successfully probing, and we should be
+setting up all switches from our probe path.
+
+After "complete" becomes true, dsa_tree_setup_cpu_ports() or any
+subsequent function may fail. If that happens, the entire tree setup is
+in limbo: the first N-1 switches have successfully finished probing
+(doing nothing but having allocated persistent memory in the tree's
+dst->ports, and maybe dst->rtable), and switch N failed to probe, ending
+the tree setup process before anything is tangible from the user's PoV.
+
+If switch N fails to probe, its memory (ports) will be freed and removed
+from dst->ports. However, the dst->rtable elements pointing to its ports,
+as created by dsa_link_touch(), will remain there, and will lead to
+use-after-free if dereferenced.
+
+If dsa_tree_setup_switches() returns -EPROBE_DEFER, which is entirely
+possible because that is where ds->ops->setup() is, we get a kasan
+report like this:
+
+==================================================================
+BUG: KASAN: slab-use-after-free in mv88e6xxx_setup_upstream_port+0x240/0x568
+Read of size 8 at addr ffff000004f56020 by task kworker/u8:3/42
+
+Call trace:
+ __asan_report_load8_noabort+0x20/0x30
+ mv88e6xxx_setup_upstream_port+0x240/0x568
+ mv88e6xxx_setup+0xebc/0x1eb0
+ dsa_register_switch+0x1af4/0x2ae0
+ mv88e6xxx_register_switch+0x1b8/0x2a8
+ mv88e6xxx_probe+0xc4c/0xf60
+ mdio_probe+0x78/0xb8
+ really_probe+0x2b8/0x5a8
+ __driver_probe_device+0x164/0x298
+ driver_probe_device+0x78/0x258
+ __device_attach_driver+0x274/0x350
+
+Allocated by task 42:
+ __kasan_kmalloc+0x84/0xa0
+ __kmalloc_cache_noprof+0x298/0x490
+ dsa_switch_touch_ports+0x174/0x3d8
+ dsa_register_switch+0x800/0x2ae0
+ mv88e6xxx_register_switch+0x1b8/0x2a8
+ mv88e6xxx_probe+0xc4c/0xf60
+ mdio_probe+0x78/0xb8
+ really_probe+0x2b8/0x5a8
+ __driver_probe_device+0x164/0x298
+ driver_probe_device+0x78/0x258
+ __device_attach_driver+0x274/0x350
+
+Freed by task 42:
+ __kasan_slab_free+0x48/0x68
+ kfree+0x138/0x418
+ dsa_register_switch+0x2694/0x2ae0
+ mv88e6xxx_register_switch+0x1b8/0x2a8
+ mv88e6xxx_probe+0xc4c/0xf60
+ mdio_probe+0x78/0xb8
+ really_probe+0x2b8/0x5a8
+ __driver_probe_device+0x164/0x298
+ driver_probe_device+0x78/0x258
+ __device_attach_driver+0x274/0x350
+
+The simplest way to fix the bug is to delete the routing table in its
+entirety. dsa_tree_setup_routing_table() has no problem in regenerating
+it even if we deleted links between ports other than those of switch N,
+because dsa_link_touch() first checks whether the port pair already
+exists in dst->rtable, allocating if not.
+
+The deletion of the routing table in its entirety already exists in
+dsa_tree_teardown(), so refactor that into a function that can also be
+called from the tree setup error path.
+
+In my analysis of the commit to blame, it is the one which added
+dsa_link elements to dst->rtable. Prior to that, each switch had its own
+ds->rtable which is freed when the switch fails to probe. But the tree
+is potentially persistent memory.
+
+Fixes: c5f51765a1f6 ("net: dsa: list DSA links in the fabric")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250414213001.2957964-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/dsa/dsa.c | 21 ++++++++++++++-------
+ 1 file changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
+index 399675c5fcc7f..07736edc8b6a5 100644
+--- a/net/dsa/dsa.c
++++ b/net/dsa/dsa.c
+@@ -867,6 +867,16 @@ static void dsa_tree_teardown_lags(struct dsa_switch_tree *dst)
+ kfree(dst->lags);
+ }
+
++static void dsa_tree_teardown_routing_table(struct dsa_switch_tree *dst)
++{
++ struct dsa_link *dl, *next;
++
++ list_for_each_entry_safe(dl, next, &dst->rtable, list) {
++ list_del(&dl->list);
++ kfree(dl);
++ }
++}
++
+ static int dsa_tree_setup(struct dsa_switch_tree *dst)
+ {
+ bool complete;
+@@ -884,7 +894,7 @@ static int dsa_tree_setup(struct dsa_switch_tree *dst)
+
+ err = dsa_tree_setup_cpu_ports(dst);
+ if (err)
+- return err;
++ goto teardown_rtable;
+
+ err = dsa_tree_setup_switches(dst);
+ if (err)
+@@ -916,14 +926,14 @@ static int dsa_tree_setup(struct dsa_switch_tree *dst)
+ dsa_tree_teardown_switches(dst);
+ teardown_cpu_ports:
+ dsa_tree_teardown_cpu_ports(dst);
++teardown_rtable:
++ dsa_tree_teardown_routing_table(dst);
+
+ return err;
+ }
+
+ static void dsa_tree_teardown(struct dsa_switch_tree *dst)
+ {
+- struct dsa_link *dl, *next;
+-
+ if (!dst->setup)
+ return;
+
+@@ -937,10 +947,7 @@ static void dsa_tree_teardown(struct dsa_switch_tree *dst)
+
+ dsa_tree_teardown_cpu_ports(dst);
+
+- list_for_each_entry_safe(dl, next, &dst->rtable, list) {
+- list_del(&dl->list);
+- kfree(dl);
+- }
++ dsa_tree_teardown_routing_table(dst);
+
+ pr_info("DSA: tree %d torn down\n", dst->index);
+
+--
+2.39.5
+
--- /dev/null
+From faac64f622df51a8267d2068dd9473d9166c53bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 00:28:50 +0300
+Subject: net: dsa: mv88e6xxx: avoid unregistering devlink regions which were
+ never registered
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit c84f6ce918a9e6f4996597cbc62536bbf2247c96 ]
+
+Russell King reports that a system with mv88e6xxx dereferences a NULL
+pointer when unbinding this driver:
+https://lore.kernel.org/netdev/Z_lRkMlTJ1KQ0kVX@shell.armlinux.org.uk/
+
+The crash seems to be in devlink_region_destroy(), which is not NULL
+tolerant but is given a NULL devlink global region pointer.
+
+At least on some chips, some devlink regions are conditionally registered
+since the blamed commit, see mv88e6xxx_setup_devlink_regions_global():
+
+ if (cond && !cond(chip))
+ continue;
+
+These are MV88E6XXX_REGION_STU and MV88E6XXX_REGION_PVT. If the chip
+does not have an STU or PVT, it should crash like this.
+
+To fix the issue, avoid unregistering those regions which are NULL, i.e.
+were skipped at mv88e6xxx_setup_devlink_regions_global() time.
+
+Fixes: 836021a2d0e0 ("net: dsa: mv88e6xxx: Export cross-chip PVT as devlink region")
+Tested-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250414212850.2953957-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/mv88e6xxx/devlink.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/dsa/mv88e6xxx/devlink.c b/drivers/net/dsa/mv88e6xxx/devlink.c
+index a08dab75e0c0c..f57fde02077d2 100644
+--- a/drivers/net/dsa/mv88e6xxx/devlink.c
++++ b/drivers/net/dsa/mv88e6xxx/devlink.c
+@@ -743,7 +743,8 @@ void mv88e6xxx_teardown_devlink_regions_global(struct dsa_switch *ds)
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mv88e6xxx_regions); i++)
+- dsa_devlink_region_destroy(chip->regions[i]);
++ if (chip->regions[i])
++ dsa_devlink_region_destroy(chip->regions[i]);
+ }
+
+ void mv88e6xxx_teardown_devlink_regions_port(struct dsa_switch *ds, int port)
+--
+2.39.5
+
--- /dev/null
+From 813b7cd04d12fa6d6ff6e4dd18ead6e0156884f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 00:29:13 +0300
+Subject: net: dsa: mv88e6xxx: fix -ENOENT when deleting VLANs and MST is
+ unsupported
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit ea08dfc35f83cfc73493c52f63ae4f2e29edfe8d ]
+
+Russell King reports that on the ZII dev rev B, deleting a bridge VLAN
+from a user port fails with -ENOENT:
+https://lore.kernel.org/netdev/Z_lQXNP0s5-IiJzd@shell.armlinux.org.uk/
+
+This comes from mv88e6xxx_port_vlan_leave() -> mv88e6xxx_mst_put(),
+which tries to find an MST entry in &chip->msts associated with the SID,
+but fails and returns -ENOENT as such.
+
+But we know that this chip does not support MST at all, so that is not
+surprising. The question is why does the guard in mv88e6xxx_mst_put()
+not exit early:
+
+ if (!sid)
+ return 0;
+
+And the answer seems to be simple: the sid comes from vlan.sid which
+supposedly was previously populated by mv88e6xxx_vtu_get().
+But some chip->info->ops->vtu_getnext() implementations do not populate
+vlan.sid, for example see mv88e6185_g1_vtu_getnext(). In that case,
+later in mv88e6xxx_port_vlan_leave() we are using a garbage sid which is
+just residual stack memory.
+
+Testing for sid == 0 covers all cases of a non-bridge VLAN or a bridge
+VLAN mapped to the default MSTI. For some chips, SID 0 is valid and
+installed by mv88e6xxx_stu_setup(). A chip which does not support the
+STU would implicitly only support mapping all VLANs to the default MSTI,
+so although SID 0 is not valid, it would be sufficient, if we were to
+zero-initialize the vlan structure, to fix the bug, due to the
+coincidence that a test for vlan.sid == 0 already exists and leads to
+the same (correct) behavior.
+
+Another option which would be sufficient would be to add a test for
+mv88e6xxx_has_stu() inside mv88e6xxx_mst_put(), symmetric to the one
+which already exists in mv88e6xxx_mst_get(). But that placement means
+the caller will have to dereference vlan.sid, which means it will access
+uninitialized memory, which is not nice even if it ignores it later.
+
+So we end up making both modifications, in order to not rely just on the
+sid == 0 coincidence, but also to avoid having uninitialized structure
+fields which might get temporarily accessed.
+
+Fixes: acaf4d2e36b3 ("net: dsa: mv88e6xxx: MST Offloading")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250414212913.2955253-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/mv88e6xxx/chip.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
+index 662509c3da1f0..da7260e505a2e 100644
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -1742,6 +1742,8 @@ static int mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid,
+ if (!chip->info->ops->vtu_getnext)
+ return -EOPNOTSUPP;
+
++ memset(entry, 0, sizeof(*entry));
++
+ entry->vid = vid ? vid - 1 : mv88e6xxx_max_vid(chip);
+ entry->valid = false;
+
+@@ -1877,7 +1879,16 @@ static int mv88e6xxx_mst_put(struct mv88e6xxx_chip *chip, u8 sid)
+ struct mv88e6xxx_mst *mst, *tmp;
+ int err;
+
+- if (!sid)
++ /* If the SID is zero, it is for a VLAN mapped to the default MSTI,
++ * and mv88e6xxx_stu_setup() made sure it is always present, and thus,
++ * should not be removed here.
++ *
++ * If the chip lacks STU support, numerically the "sid" variable will
++ * happen to also be zero, but we don't want to rely on that fact, so
++ * we explicitly test that first. In that case, there is also nothing
++ * to do here.
++ */
++ if (!mv88e6xxx_has_stu(chip) || !sid)
+ return 0;
+
+ list_for_each_entry_safe(mst, tmp, &chip->msts, node) {
+--
+2.39.5
+
--- /dev/null
+From 8bb885c80221a2ad814e1700c96715a3b49b6fdf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Apr 2025 01:51:07 +0100
+Subject: net: ethernet: mtk_eth_soc: correct the max weight of the queue limit
+ for 100Mbps
+
+From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
+
+[ Upstream commit 6b02eb372c6776c9abb8bc81cf63f96039c24664 ]
+
+Without this patch, the maximum weight of the queue limit will be
+incorrect when linked at 100Mbps due to an apparent typo.
+
+Fixes: f63959c7eec31 ("net: ethernet: mtk_eth_soc: implement multi-queue support for per-port queues")
+Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://patch.msgid.link/74111ba0bdb13743313999ed467ce564e8189006.1744764277.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index bdc424123ee6c..a22a5bdc7ce62 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -724,7 +724,7 @@ static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
+ case SPEED_100:
+ val |= MTK_QTX_SCH_MAX_RATE_EN |
+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 103) |
+- FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 3);
++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 3) |
+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1);
+ break;
+ case SPEED_1000:
+@@ -747,7 +747,7 @@ static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
+ case SPEED_100:
+ val |= MTK_QTX_SCH_MAX_RATE_EN |
+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 1) |
+- FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 5);
++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 5) |
+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1);
+ break;
+ case SPEED_1000:
+--
+2.39.5
+
--- /dev/null
+From 5a7a2d9c3ba340e3f56334a5cece90ec5febf3a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Apr 2025 01:51:25 +0100
+Subject: net: ethernet: mtk_eth_soc: revise QDMA packet scheduler settings
+
+From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
+
+[ Upstream commit 1b66124135f5f8640bd540fadda4b20cdd23114b ]
+
+The QDMA packet scheduler suffers from a performance issue.
+Fix this by picking up changes from MediaTek's SDK which change to use
+Token Bucket instead of Leaky Bucket and fix the SPEED_1000 configuration.
+
+Fixes: 160d3a9b1929 ("net: ethernet: mtk_eth_soc: introduce MTK_NETSYS_V2 support")
+Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://patch.msgid.link/18040f60f9e2f5855036b75b28c4332a2d2ebdd8.1744764277.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index a22a5bdc7ce62..c201ea20e4047 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -752,8 +752,8 @@ static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
+ break;
+ case SPEED_1000:
+ val |= MTK_QTX_SCH_MAX_RATE_EN |
+- FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 10) |
+- FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 5) |
++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 1) |
++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 6) |
+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 10);
+ break;
+ default:
+@@ -3244,7 +3244,7 @@ static int mtk_start_dma(struct mtk_eth *eth)
+ if (mtk_is_netsys_v2_or_greater(eth))
+ val |= MTK_MUTLI_CNT | MTK_RESV_BUF |
+ MTK_WCOMP_EN | MTK_DMAD_WR_WDONE |
+- MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN;
++ MTK_CHK_DDONE_EN;
+ else
+ val |= MTK_RX_BT_32DWORDS;
+ mtk_w32(eth, val, reg_map->qdma.glo_cfg);
+--
+2.39.5
+
--- /dev/null
+From c1236413950942040174467f02f3cb787a261cc2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 10:39:42 +0200
+Subject: net: ethernet: ti: am65-cpsw: fix port_np reference counting
+
+From: Michael Walle <mwalle@kernel.org>
+
+[ Upstream commit 903d2b9f9efc5b3339d74015fcfc0d9fff276c4c ]
+
+A reference to the device tree node is stored in a private struct, thus
+the reference count has to be incremented. Also, decrement the count on
+device removal and in the error path.
+
+Fixes: 93a76530316a ("net: ethernet: ti: introduce am65x/j721e gigabit eth subsystem driver")
+Signed-off-by: Michael Walle <mwalle@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250414083942.4015060-1-mwalle@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/am65-cpsw-nuss.c | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+index dbca0b2889bc5..9c8376b271891 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+@@ -2076,7 +2076,7 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
+ of_property_read_bool(port_np, "ti,mac-only");
+
+ /* get phy/link info */
+- port->slave.port_np = port_np;
++ port->slave.port_np = of_node_get(port_np);
+ ret = of_get_phy_mode(port_np, &port->slave.phy_if);
+ if (ret) {
+ dev_err(dev, "%pOF read phy-mode err %d\n",
+@@ -2134,6 +2134,17 @@ static void am65_cpsw_nuss_phylink_cleanup(struct am65_cpsw_common *common)
+ }
+ }
+
++static void am65_cpsw_remove_dt(struct am65_cpsw_common *common)
++{
++ struct am65_cpsw_port *port;
++ int i;
++
++ for (i = 0; i < common->port_num; i++) {
++ port = &common->ports[i];
++ of_node_put(port->slave.port_np);
++ }
++}
++
+ static int
+ am65_cpsw_nuss_init_port_ndev(struct am65_cpsw_common *common, u32 port_idx)
+ {
+@@ -3009,6 +3020,7 @@ static int am65_cpsw_nuss_probe(struct platform_device *pdev)
+ err_free_phylink:
+ am65_cpsw_nuss_phylink_cleanup(common);
+ am65_cpts_release(common->cpts);
++ am65_cpsw_remove_dt(common);
+ err_of_clear:
+ if (common->mdio_dev)
+ of_platform_device_destroy(common->mdio_dev, NULL);
+@@ -3040,6 +3052,7 @@ static int am65_cpsw_nuss_remove(struct platform_device *pdev)
+ am65_cpsw_nuss_phylink_cleanup(common);
+ am65_cpts_release(common->cpts);
+ am65_cpsw_disable_serdes_phy(common);
++ am65_cpsw_remove_dt(common);
+
+ if (common->mdio_dev)
+ of_platform_device_destroy(common->mdio_dev, NULL);
+--
+2.39.5
+
--- /dev/null
+From c4e924bb520296f9b3ad328908f8dfb113289e61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 May 2024 09:59:49 +0200
+Subject: net: ethernet: ti: am65-cpsw-nuss: rename phy_node -> port_np
+
+From: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+
+[ Upstream commit 78269025e192ec8122ddd87a1ec2805598d8a1ab ]
+
+Rename phy_node to port_np to better reflect what it actually is,
+because the new phylink API takes netdev node (or DSA port node),
+and resolves the phandle internally.
+
+Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+Link: https://lore.kernel.org/r/20240528075954.3608118-2-alexander.sverdlin@siemens.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 903d2b9f9efc ("net: ethernet: ti: am65-cpsw: fix port_np reference counting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/am65-cpsw-nuss.c | 6 +++---
+ drivers/net/ethernet/ti/am65-cpsw-nuss.h | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+index 8ffc1fbb036f9..dbca0b2889bc5 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+@@ -626,7 +626,7 @@ static int am65_cpsw_nuss_ndo_slave_open(struct net_device *ndev)
+ /* mac_sl should be configured via phy-link interface */
+ am65_cpsw_sl_ctl_reset(port);
+
+- ret = phylink_of_phy_connect(port->slave.phylink, port->slave.phy_node, 0);
++ ret = phylink_of_phy_connect(port->slave.phylink, port->slave.port_np, 0);
+ if (ret)
+ goto error_cleanup;
+
+@@ -2076,7 +2076,7 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
+ of_property_read_bool(port_np, "ti,mac-only");
+
+ /* get phy/link info */
+- port->slave.phy_node = port_np;
++ port->slave.port_np = port_np;
+ ret = of_get_phy_mode(port_np, &port->slave.phy_if);
+ if (ret) {
+ dev_err(dev, "%pOF read phy-mode err %d\n",
+@@ -2217,7 +2217,7 @@ am65_cpsw_nuss_init_port_ndev(struct am65_cpsw_common *common, u32 port_idx)
+ }
+
+ phylink = phylink_create(&port->slave.phylink_config,
+- of_node_to_fwnode(port->slave.phy_node),
++ of_node_to_fwnode(port->slave.port_np),
+ port->slave.phy_if,
+ &am65_cpsw_phylink_mac_ops);
+ if (IS_ERR(phylink))
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.h b/drivers/net/ethernet/ti/am65-cpsw-nuss.h
+index f3dad2ab9828b..f107198e25721 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.h
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.h
+@@ -29,7 +29,7 @@ struct am65_cpts;
+ struct am65_cpsw_slave_data {
+ bool mac_only;
+ struct cpsw_sl *mac_sl;
+- struct device_node *phy_node;
++ struct device_node *port_np;
+ phy_interface_t phy_if;
+ struct phy *ifphy;
+ struct phy *serdes_phy;
+--
+2.39.5
+
--- /dev/null
+From 3c7f4d9d4fa8e0a0b47526ff9674bd01e9638fb0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 11:53:19 +0800
+Subject: net: mctp: Set SOCK_RCU_FREE
+
+From: Matt Johnston <matt@codeconstruct.com.au>
+
+[ Upstream commit 52024cd6ec71a6ca934d0cc12452bd8d49850679 ]
+
+Bind lookup runs under RCU, so ensure that a socket doesn't go away in
+the middle of a lookup.
+
+Fixes: 833ef3b91de6 ("mctp: Populate socket implementation")
+Signed-off-by: Matt Johnston <matt@codeconstruct.com.au>
+Link: https://patch.msgid.link/20250410-mctp-rcu-sock-v1-1-872de9fdc877@codeconstruct.com.au
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mctp/af_mctp.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/mctp/af_mctp.c b/net/mctp/af_mctp.c
+index 28be85d055330..8032cfba22d1c 100644
+--- a/net/mctp/af_mctp.c
++++ b/net/mctp/af_mctp.c
+@@ -550,6 +550,9 @@ static int mctp_sk_hash(struct sock *sk)
+ {
+ struct net *net = sock_net(sk);
+
++ /* Bind lookup runs under RCU, remain live during that. */
++ sock_set_flag(sk, SOCK_RCU_FREE);
++
+ mutex_lock(&net->mctp.bind_lock);
+ sk_add_node_rcu(sk, &net->mctp.binds);
+ mutex_unlock(&net->mctp.bind_lock);
+--
+2.39.5
+
--- /dev/null
+From 6058cee2718eac536f92fc0590254438ff158d8d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Apr 2025 21:19:24 +0530
+Subject: net: ngbe: fix memory leak in ngbe_probe() error path
+
+From: Abdun Nihaal <abdun.nihaal@gmail.com>
+
+[ Upstream commit 88fa80021b77732bc98f73fb69d69c7cc37b9f0d ]
+
+When ngbe_sw_init() is called, memory is allocated for wx->rss_key
+in wx_init_rss_key(). However, in ngbe_probe() function, the subsequent
+error paths after ngbe_sw_init() don't free the rss_key. Fix that by
+freeing it in error path along with wx->mac_table.
+
+Also change the label to which execution jumps when ngbe_sw_init()
+fails, because otherwise, it could lead to a double free for rss_key,
+when the mac_table allocation fails in wx_sw_init().
+
+Fixes: 02338c484ab6 ("net: ngbe: Initialize sw info and register netdev")
+Signed-off-by: Abdun Nihaal <abdun.nihaal@gmail.com>
+Reviewed-by: Kory Maincent <kory.maincent@bootlin.com>
+Reviewed-by: Jiawen Wu <jiawenwu@trustnetic.com>
+Link: https://patch.msgid.link/20250412154927.25908-1-abdun.nihaal@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/wangxun/ngbe/ngbe_main.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c b/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
+index a4d63d2f3c5bb..91f0f23c176a0 100644
+--- a/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
++++ b/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
+@@ -589,7 +589,7 @@ static int ngbe_probe(struct pci_dev *pdev,
+ /* setup the private structure */
+ err = ngbe_sw_init(wx);
+ if (err)
+- goto err_free_mac_table;
++ goto err_pci_release_regions;
+
+ /* check if flash load is done after hw power up */
+ err = wx_check_flash_load(wx, NGBE_SPI_ILDR_STATUS_PERST);
+@@ -687,6 +687,7 @@ static int ngbe_probe(struct pci_dev *pdev,
+ err_clear_interrupt_scheme:
+ wx_clear_interrupt_scheme(wx);
+ err_free_mac_table:
++ kfree(wx->rss_key);
+ kfree(wx->mac_table);
+ err_pci_release_regions:
+ pci_release_selected_regions(pdev,
+--
+2.39.5
+
--- /dev/null
+From 7924e4213c411d941a9faf4ff70ad609e83b59af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Apr 2025 12:40:18 +0200
+Subject: net: openvswitch: fix nested key length validation in the set()
+ action
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 65d91192aa66f05710cfddf6a14b5a25ee554dba ]
+
+It's not safe to access nla_len(ovs_key) if the data is smaller than
+the netlink header. Check that the attribute is OK first.
+
+Fixes: ccb1352e76cf ("net: Add Open vSwitch kernel components.")
+Reported-by: syzbot+b07a9da40df1576b8048@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=b07a9da40df1576b8048
+Tested-by: syzbot+b07a9da40df1576b8048@syzkaller.appspotmail.com
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Reviewed-by: Eelco Chaudron <echaudro@redhat.com>
+Acked-by: Aaron Conole <aconole@redhat.com>
+Link: https://patch.msgid.link/20250412104052.2073688-1-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/openvswitch/flow_netlink.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
+index 9c13e14034d3b..089ab1826e1d5 100644
+--- a/net/openvswitch/flow_netlink.c
++++ b/net/openvswitch/flow_netlink.c
+@@ -2862,7 +2862,8 @@ static int validate_set(const struct nlattr *a,
+ size_t key_len;
+
+ /* There can be only one key in a action */
+- if (nla_total_size(nla_len(ovs_key)) != nla_len(a))
++ if (!nla_ok(ovs_key, nla_len(a)) ||
++ nla_total_size(nla_len(ovs_key)) != nla_len(a))
+ return -EINVAL;
+
+ key_len = nla_len(ovs_key);
+--
+2.39.5
+
--- /dev/null
+From 73748631f5bf24364071fda84ada916e5deb1de9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 16:27:53 +0530
+Subject: net: ti: icss-iep: Add phase offset configuration for perout signal
+
+From: Meghana Malladi <m-malladi@ti.com>
+
+[ Upstream commit 220cb1be647a7ca4e60241405c66f8f612c9b046 ]
+
+icss_iep_perout_enable_hw() is a common function for generating
+both pps and perout signals. When enabling pps, the application needs
+to only pass enable/disable argument, whereas for perout it supports
+different flags to configure the signal.
+
+In case the app passes a valid phase offset value, the signal should
+start toggling after that phase offset, else start immediately or
+as soon as possible. ICSS_IEP_SYNC_START_REG register take number of
+clock cycles to wait before starting the signal after activation time.
+Set appropriate value to this register to support phase offset.
+
+Signed-off-by: Meghana Malladi <m-malladi@ti.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Kory Maincent <kory.maincent@bootlin.com>
+Link: https://patch.msgid.link/20250304105753.1552159-3-m-malladi@ti.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 7349c9e99793 ("net: ti: icss-iep: Fix possible NULL pointer dereference for perout request")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/icssg/icss_iep.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/ti/icssg/icss_iep.c b/drivers/net/ethernet/ti/icssg/icss_iep.c
+index 923ac58c9de5b..6006276ecce6f 100644
+--- a/drivers/net/ethernet/ti/icssg/icss_iep.c
++++ b/drivers/net/ethernet/ti/icssg/icss_iep.c
+@@ -477,6 +477,7 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep,
+ struct ptp_perout_request *req, int on)
+ {
+ struct timespec64 ts;
++ u64 ns_start;
+ u64 ns_width;
+ int ret;
+ u64 cmp;
+@@ -486,6 +487,14 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep,
+ ts.tv_nsec = req->on.nsec;
+ ns_width = timespec64_to_ns(&ts);
+
++ if (req->flags & PTP_PEROUT_PHASE) {
++ ts.tv_sec = req->phase.sec;
++ ts.tv_nsec = req->phase.nsec;
++ ns_start = timespec64_to_ns(&ts);
++ } else {
++ ns_start = 0;
++ }
++
+ if (iep->ops && iep->ops->perout_enable) {
+ ret = iep->ops->perout_enable(iep->clockops_data, req, on, &cmp);
+ if (ret)
+@@ -500,7 +509,8 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep,
+ regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG,
+ div_u64(ns_width, iep->def_inc));
+ regmap_write(iep->map, ICSS_IEP_SYNC0_PERIOD_REG, 0);
+- regmap_write(iep->map, ICSS_IEP_SYNC_START_REG, 0);
++ regmap_write(iep->map, ICSS_IEP_SYNC_START_REG,
++ div_u64(ns_start, iep->def_inc));
+ regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG, 0); /* one-shot mode */
+ /* Enable CMP 1 */
+ regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
+@@ -527,6 +537,8 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep,
+
+ regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG,
+ div_u64(ns_width, iep->def_inc));
++ regmap_write(iep->map, ICSS_IEP_SYNC_START_REG,
++ div_u64(ns_start, iep->def_inc));
+ /* Enable Sync in single shot mode */
+ regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG,
+ IEP_SYNC_CTRL_SYNC_N_EN(0) | IEP_SYNC_CTRL_SYNC_EN);
+@@ -557,7 +569,8 @@ static int icss_iep_perout_enable(struct icss_iep *iep,
+ int ret = 0;
+
+ /* Reject requests with unsupported flags */
+- if (req->flags & ~PTP_PEROUT_DUTY_CYCLE)
++ if (req->flags & ~(PTP_PEROUT_DUTY_CYCLE |
++ PTP_PEROUT_PHASE))
+ return -EOPNOTSUPP;
+
+ mutex_lock(&iep->ptp_clk_mutex);
+@@ -607,6 +620,7 @@ static int icss_iep_pps_enable(struct icss_iep *iep, int on)
+ if (on) {
+ ns = icss_iep_gettime(iep, NULL);
+ ts = ns_to_timespec64(ns);
++ rq.perout.flags = 0;
+ rq.perout.period.sec = 1;
+ rq.perout.period.nsec = 0;
+ rq.perout.start.sec = ts.tv_sec + 2;
+--
+2.39.5
+
--- /dev/null
+From 953b7d95818058973c7519fc40bf94ee80b10248 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 16:27:52 +0530
+Subject: net: ti: icss-iep: Add pwidth configuration for perout signal
+
+From: Meghana Malladi <m-malladi@ti.com>
+
+[ Upstream commit e5b456a14215e3c0e84844c2926861b972e03632 ]
+
+icss_iep_perout_enable_hw() is a common function for generating
+both pps and perout signals. When enabling pps, the application needs
+to only pass enable/disable argument, whereas for perout it supports
+different flags to configure the signal.
+
+But icss_iep_perout_enable_hw() function is missing to hook the
+configuration params passed by the app, causing perout to behave
+same a pps (except being able to configure the period). As duty cycle
+is also one feature which can configured for perout, incorporate this
+in the function to get the expected signal.
+
+Signed-off-by: Meghana Malladi <m-malladi@ti.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Kory Maincent <kory.maincent@bootlin.com>
+Link: https://patch.msgid.link/20250304105753.1552159-2-m-malladi@ti.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 7349c9e99793 ("net: ti: icss-iep: Fix possible NULL pointer dereference for perout request")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/icssg/icss_iep.c | 47 ++++++++++++++++++++++--
+ 1 file changed, 44 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/ti/icssg/icss_iep.c b/drivers/net/ethernet/ti/icssg/icss_iep.c
+index 3f9a030471fe2..923ac58c9de5b 100644
+--- a/drivers/net/ethernet/ti/icssg/icss_iep.c
++++ b/drivers/net/ethernet/ti/icssg/icss_iep.c
+@@ -476,9 +476,16 @@ static void icss_iep_update_to_next_boundary(struct icss_iep *iep, u64 start_ns)
+ static int icss_iep_perout_enable_hw(struct icss_iep *iep,
+ struct ptp_perout_request *req, int on)
+ {
++ struct timespec64 ts;
++ u64 ns_width;
+ int ret;
+ u64 cmp;
+
++ /* Calculate width of the signal for PPS/PEROUT handling */
++ ts.tv_sec = req->on.sec;
++ ts.tv_nsec = req->on.nsec;
++ ns_width = timespec64_to_ns(&ts);
++
+ if (iep->ops && iep->ops->perout_enable) {
+ ret = iep->ops->perout_enable(iep->clockops_data, req, on, &cmp);
+ if (ret)
+@@ -489,8 +496,9 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep,
+ regmap_write(iep->map, ICSS_IEP_CMP1_REG0, lower_32_bits(cmp));
+ if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT)
+ regmap_write(iep->map, ICSS_IEP_CMP1_REG1, upper_32_bits(cmp));
+- /* Configure SYNC, 1ms pulse width */
+- regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG, 1000000);
++ /* Configure SYNC, based on req on width */
++ regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG,
++ div_u64(ns_width, iep->def_inc));
+ regmap_write(iep->map, ICSS_IEP_SYNC0_PERIOD_REG, 0);
+ regmap_write(iep->map, ICSS_IEP_SYNC_START_REG, 0);
+ regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG, 0); /* one-shot mode */
+@@ -517,6 +525,8 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep,
+ + req->period.nsec;
+ icss_iep_update_to_next_boundary(iep, start_ns);
+
++ regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG,
++ div_u64(ns_width, iep->def_inc));
+ /* Enable Sync in single shot mode */
+ regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG,
+ IEP_SYNC_CTRL_SYNC_N_EN(0) | IEP_SYNC_CTRL_SYNC_EN);
+@@ -544,7 +554,36 @@ 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)
+ {
+- return -EOPNOTSUPP;
++ int ret = 0;
++
++ /* Reject requests with unsupported flags */
++ if (req->flags & ~PTP_PEROUT_DUTY_CYCLE)
++ return -EOPNOTSUPP;
++
++ mutex_lock(&iep->ptp_clk_mutex);
++
++ if (iep->pps_enabled) {
++ ret = -EBUSY;
++ goto exit;
++ }
++
++ if (iep->perout_enabled == !!on)
++ goto exit;
++
++ /* Set default "on" time (1ms) for the signal if not passed by the app */
++ if (!(req->flags & PTP_PEROUT_DUTY_CYCLE)) {
++ req->on.sec = 0;
++ req->on.nsec = NSEC_PER_MSEC;
++ }
++
++ ret = icss_iep_perout_enable_hw(iep, req, on);
++ if (!ret)
++ iep->perout_enabled = !!on;
++
++exit:
++ mutex_unlock(&iep->ptp_clk_mutex);
++
++ return ret;
+ }
+
+ static int icss_iep_pps_enable(struct icss_iep *iep, int on)
+@@ -572,6 +611,8 @@ static int icss_iep_pps_enable(struct icss_iep *iep, int on)
+ rq.perout.period.nsec = 0;
+ rq.perout.start.sec = ts.tv_sec + 2;
+ rq.perout.start.nsec = 0;
++ rq.perout.on.sec = 0;
++ rq.perout.on.nsec = NSEC_PER_MSEC;
+ ret = icss_iep_perout_enable_hw(iep, &rq.perout, on);
+ } else {
+ ret = icss_iep_perout_enable_hw(iep, &rq.perout, on);
+--
+2.39.5
+
--- /dev/null
+From 7d4f02f816b8d13ab9feacc9647241ce61197f88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 14:35:43 +0530
+Subject: net: ti: icss-iep: Fix possible NULL pointer dereference for perout
+ request
+
+From: Meghana Malladi <m-malladi@ti.com>
+
+[ Upstream commit 7349c9e9979333abfce42da5f9025598083b59c9 ]
+
+The ICSS IEP driver tracks perout and pps enable state with flags.
+Currently when disabling pps and perout signals during icss_iep_exit(),
+results in NULL pointer dereference for perout.
+
+To fix the null pointer dereference issue, the icss_iep_perout_enable_hw
+function can be modified to directly clear the IEP CMP registers when
+disabling PPS or PEROUT, without referencing the ptp_perout_request
+structure, as its contents are irrelevant in this case.
+
+Fixes: 9b115361248d ("net: ti: icssg-prueth: Fix clearing of IEP_CMP_CFG registers during iep_init")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/all/7b1c7c36-363a-4085-b26c-4f210bee1df6@stanley.mountain/
+Signed-off-by: Meghana Malladi <m-malladi@ti.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20250415090543.717991-4-m-malladi@ti.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/icssg/icss_iep.c | 121 +++++++++++------------
+ 1 file changed, 58 insertions(+), 63 deletions(-)
+
+diff --git a/drivers/net/ethernet/ti/icssg/icss_iep.c b/drivers/net/ethernet/ti/icssg/icss_iep.c
+index 6006276ecce6f..f3315c6515156 100644
+--- a/drivers/net/ethernet/ti/icssg/icss_iep.c
++++ b/drivers/net/ethernet/ti/icssg/icss_iep.c
+@@ -482,6 +482,22 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep,
+ int ret;
+ u64 cmp;
+
++ if (!on) {
++ /* Disable CMP 1 */
++ regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
++ IEP_CMP_CFG_CMP_EN(1), 0);
++
++ /* clear CMP regs */
++ regmap_write(iep->map, ICSS_IEP_CMP1_REG0, 0);
++ if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT)
++ regmap_write(iep->map, ICSS_IEP_CMP1_REG1, 0);
++
++ /* Disable sync */
++ regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG, 0);
++
++ return 0;
++ }
++
+ /* Calculate width of the signal for PPS/PEROUT handling */
+ ts.tv_sec = req->on.sec;
+ ts.tv_nsec = req->on.nsec;
+@@ -500,64 +516,39 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep,
+ if (ret)
+ return ret;
+
+- if (on) {
+- /* Configure CMP */
+- regmap_write(iep->map, ICSS_IEP_CMP1_REG0, lower_32_bits(cmp));
+- if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT)
+- regmap_write(iep->map, ICSS_IEP_CMP1_REG1, upper_32_bits(cmp));
+- /* Configure SYNC, based on req on width */
+- regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG,
+- div_u64(ns_width, iep->def_inc));
+- regmap_write(iep->map, ICSS_IEP_SYNC0_PERIOD_REG, 0);
+- regmap_write(iep->map, ICSS_IEP_SYNC_START_REG,
+- div_u64(ns_start, iep->def_inc));
+- regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG, 0); /* one-shot mode */
+- /* Enable CMP 1 */
+- regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
+- IEP_CMP_CFG_CMP_EN(1), IEP_CMP_CFG_CMP_EN(1));
+- } else {
+- /* Disable CMP 1 */
+- regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
+- IEP_CMP_CFG_CMP_EN(1), 0);
+-
+- /* clear regs */
+- regmap_write(iep->map, ICSS_IEP_CMP1_REG0, 0);
+- if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT)
+- regmap_write(iep->map, ICSS_IEP_CMP1_REG1, 0);
+- }
++ /* Configure CMP */
++ regmap_write(iep->map, ICSS_IEP_CMP1_REG0, lower_32_bits(cmp));
++ if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT)
++ regmap_write(iep->map, ICSS_IEP_CMP1_REG1, upper_32_bits(cmp));
++ /* Configure SYNC, based on req on width */
++ regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG,
++ div_u64(ns_width, iep->def_inc));
++ regmap_write(iep->map, ICSS_IEP_SYNC0_PERIOD_REG, 0);
++ regmap_write(iep->map, ICSS_IEP_SYNC_START_REG,
++ div_u64(ns_start, iep->def_inc));
++ regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG, 0); /* one-shot mode */
++ /* Enable CMP 1 */
++ regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
++ IEP_CMP_CFG_CMP_EN(1), IEP_CMP_CFG_CMP_EN(1));
+ } else {
+- if (on) {
+- u64 start_ns;
+-
+- iep->period = ((u64)req->period.sec * NSEC_PER_SEC) +
+- req->period.nsec;
+- start_ns = ((u64)req->period.sec * NSEC_PER_SEC)
+- + req->period.nsec;
+- icss_iep_update_to_next_boundary(iep, start_ns);
+-
+- regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG,
+- div_u64(ns_width, iep->def_inc));
+- regmap_write(iep->map, ICSS_IEP_SYNC_START_REG,
+- div_u64(ns_start, iep->def_inc));
+- /* Enable Sync in single shot mode */
+- regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG,
+- IEP_SYNC_CTRL_SYNC_N_EN(0) | IEP_SYNC_CTRL_SYNC_EN);
+- /* Enable CMP 1 */
+- regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
+- IEP_CMP_CFG_CMP_EN(1), IEP_CMP_CFG_CMP_EN(1));
+- } else {
+- /* Disable CMP 1 */
+- regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
+- IEP_CMP_CFG_CMP_EN(1), 0);
+-
+- /* clear CMP regs */
+- regmap_write(iep->map, ICSS_IEP_CMP1_REG0, 0);
+- if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT)
+- regmap_write(iep->map, ICSS_IEP_CMP1_REG1, 0);
+-
+- /* Disable sync */
+- regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG, 0);
+- }
++ u64 start_ns;
++
++ iep->period = ((u64)req->period.sec * NSEC_PER_SEC) +
++ req->period.nsec;
++ start_ns = ((u64)req->period.sec * NSEC_PER_SEC)
++ + req->period.nsec;
++ icss_iep_update_to_next_boundary(iep, start_ns);
++
++ regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG,
++ div_u64(ns_width, iep->def_inc));
++ regmap_write(iep->map, ICSS_IEP_SYNC_START_REG,
++ div_u64(ns_start, iep->def_inc));
++ /* Enable Sync in single shot mode */
++ regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG,
++ IEP_SYNC_CTRL_SYNC_N_EN(0) | IEP_SYNC_CTRL_SYNC_EN);
++ /* Enable CMP 1 */
++ regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
++ IEP_CMP_CFG_CMP_EN(1), IEP_CMP_CFG_CMP_EN(1));
+ }
+
+ return 0;
+@@ -568,11 +559,21 @@ static int icss_iep_perout_enable(struct icss_iep *iep,
+ {
+ int ret = 0;
+
++ if (!on)
++ goto disable;
++
+ /* Reject requests with unsupported flags */
+ if (req->flags & ~(PTP_PEROUT_DUTY_CYCLE |
+ PTP_PEROUT_PHASE))
+ return -EOPNOTSUPP;
+
++ /* Set default "on" time (1ms) for the signal if not passed by the app */
++ if (!(req->flags & PTP_PEROUT_DUTY_CYCLE)) {
++ req->on.sec = 0;
++ req->on.nsec = NSEC_PER_MSEC;
++ }
++
++disable:
+ mutex_lock(&iep->ptp_clk_mutex);
+
+ if (iep->pps_enabled) {
+@@ -583,12 +584,6 @@ static int icss_iep_perout_enable(struct icss_iep *iep,
+ if (iep->perout_enabled == !!on)
+ goto exit;
+
+- /* Set default "on" time (1ms) for the signal if not passed by the app */
+- if (!(req->flags & PTP_PEROUT_DUTY_CYCLE)) {
+- req->on.sec = 0;
+- req->on.nsec = NSEC_PER_MSEC;
+- }
+-
+ ret = icss_iep_perout_enable_hw(iep, req, on);
+ if (!ret)
+ iep->perout_enabled = !!on;
+--
+2.39.5
+
--- /dev/null
+From 4f9ed0558f332df1fc8e7a19fb462f14f8b77fb8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 14:18:48 -0700
+Subject: netlink: specs: rt-link: add an attr layer around alt-ifname
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit acf4da17deada7f8b120e051aa6c9cac40dbd83b ]
+
+alt-ifname attr is directly placed in requests (as an alternative
+to ifname) but in responses its wrapped up in IFLA_PROP_LIST
+and only there is may be multi-attr. See rtnl_fill_prop_list().
+
+Fixes: b2f63d904e72 ("doc/netlink: Add spec for rt link messages")
+Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20250414211851.602096-6-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/netlink/specs/rt_link.yaml | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/Documentation/netlink/specs/rt_link.yaml b/Documentation/netlink/specs/rt_link.yaml
+index d86a68f8475ca..34f74c451dcdb 100644
+--- a/Documentation/netlink/specs/rt_link.yaml
++++ b/Documentation/netlink/specs/rt_link.yaml
+@@ -892,11 +892,10 @@ attribute-sets:
+ -
+ name: prop-list
+ type: nest
+- nested-attributes: link-attrs
++ nested-attributes: prop-list-link-attrs
+ -
+ name: alt-ifname
+ type: string
+- multi-attr: true
+ -
+ name: perm-address
+ type: binary
+@@ -931,6 +930,13 @@ attribute-sets:
+ -
+ name: gro-ipv4-max-size
+ type: u32
++ -
++ name: prop-list-link-attrs
++ subset-of: link-attrs
++ attributes:
++ -
++ name: alt-ifname
++ multi-attr: true
+ -
+ name: af-spec-attrs
+ attributes:
+@@ -1362,7 +1368,6 @@ operations:
+ - min-mtu
+ - max-mtu
+ - prop-list
+- - alt-ifname
+ - perm-address
+ - proto-down-reason
+ - parent-dev-name
+--
+2.39.5
+
--- /dev/null
+From f2b4d057e5586297b3ef98c8509f0928848705d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 14:18:50 -0700
+Subject: netlink: specs: rt-link: adjust mctp attribute naming
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit beb3c5ad8829b52057f48a776a9d9558b98c157f ]
+
+MCTP attribute naming is inconsistent. In C we have:
+ IFLA_MCTP_NET,
+ IFLA_MCTP_PHYS_BINDING,
+ ^^^^
+
+but in YAML:
+ - mctp-net
+ - phys-binding
+ ^
+ no "mctp"
+
+It's unclear whether the "mctp" part of the name is supposed
+to be a prefix or part of attribute name. Make it a prefix,
+seems cleaner, even tho technically phys-binding was added later.
+
+Fixes: b2f63d904e72 ("doc/netlink: Add spec for rt link messages")
+Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20250414211851.602096-8-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/netlink/specs/rt_link.yaml | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/Documentation/netlink/specs/rt_link.yaml b/Documentation/netlink/specs/rt_link.yaml
+index 34f74c451dcdb..a8a1466adf179 100644
+--- a/Documentation/netlink/specs/rt_link.yaml
++++ b/Documentation/netlink/specs/rt_link.yaml
+@@ -1199,9 +1199,10 @@ attribute-sets:
+ type: u32
+ -
+ name: mctp-attrs
++ name-prefix: ifla-mctp-
+ attributes:
+ -
+- name: mctp-net
++ name: net
+ type: u32
+ -
+ name: stats-attrs
+--
+2.39.5
+
--- /dev/null
+From 5f4545c9c9526ddb84d446cd34c8925aa1cc0159 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Feb 2025 13:07:55 +0100
+Subject: ovl: remove unused forward declaration
+
+From: Giuseppe Scrivano <gscrivan@redhat.com>
+
+[ Upstream commit a6eb9a4a69cc360b930dad9dc8513f8fd9b3577f ]
+
+The ovl_get_verity_xattr() function was never added, only its declaration.
+
+Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
+Fixes: 184996e92e86 ("ovl: Validate verity xattr when resolving lowerdata")
+Reviewed-by: Amir Goldstein <amir73il@gmail.com>
+Reviewed-by: Alexander Larsson <alexl@redhat.com>
+Reviewed-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/overlayfs/overlayfs.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
+index 981967e507b3e..23b5c5f9c7823 100644
+--- a/fs/overlayfs/overlayfs.h
++++ b/fs/overlayfs/overlayfs.h
+@@ -506,8 +506,6 @@ int ovl_set_metacopy_xattr(struct ovl_fs *ofs, struct dentry *d,
+ bool ovl_is_metacopy_dentry(struct dentry *dentry);
+ char *ovl_get_redirect_xattr(struct ovl_fs *ofs, const struct path *path, int padding);
+ int ovl_ensure_verity_loaded(struct path *path);
+-int ovl_get_verity_xattr(struct ovl_fs *ofs, const struct path *path,
+- u8 *digest_buf, int *buf_length);
+ int ovl_validate_verity(struct ovl_fs *ofs,
+ struct path *metapath,
+ struct path *datapath);
+--
+2.39.5
+
--- /dev/null
+From 1a7bb38feec2aba4a76292477952e4816bbf1b1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 11:14:48 +0530
+Subject: pds_core: fix memory leak in pdsc_debugfs_add_qcq()
+
+From: Abdun Nihaal <abdun.nihaal@gmail.com>
+
+[ Upstream commit 8b82f656826c741d032490b089a5638c33f2c91d ]
+
+The memory allocated for intr_ctrl_regset, which is passed to
+debugfs_create_regset32() may not be cleaned up when the driver is
+removed. Fix that by using device managed allocation for it.
+
+Fixes: 45d76f492938 ("pds_core: set up device and adminq")
+Signed-off-by: Abdun Nihaal <abdun.nihaal@gmail.com>
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Reviewed-by: Shannon Nelson <shannon.nelson@amd.com>
+Link: https://patch.msgid.link/20250409054450.48606-1-abdun.nihaal@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/amd/pds_core/debugfs.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/amd/pds_core/debugfs.c b/drivers/net/ethernet/amd/pds_core/debugfs.c
+index 4e8579ca1c8c7..51f3f73a839a9 100644
+--- a/drivers/net/ethernet/amd/pds_core/debugfs.c
++++ b/drivers/net/ethernet/amd/pds_core/debugfs.c
+@@ -154,8 +154,9 @@ void pdsc_debugfs_add_qcq(struct pdsc *pdsc, struct pdsc_qcq *qcq)
+ debugfs_create_u32("index", 0400, intr_dentry, &intr->index);
+ debugfs_create_u32("vector", 0400, intr_dentry, &intr->vector);
+
+- intr_ctrl_regset = kzalloc(sizeof(*intr_ctrl_regset),
+- GFP_KERNEL);
++ intr_ctrl_regset = devm_kzalloc(pdsc->dev,
++ sizeof(*intr_ctrl_regset),
++ GFP_KERNEL);
+ if (!intr_ctrl_regset)
+ return;
+ intr_ctrl_regset->regs = intr_ctrl_regs;
+--
+2.39.5
+
--- /dev/null
+From f8b532fde839a20d3de126459a620d0d6c3458f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 08:31:31 +0300
+Subject: ptp: ocp: fix start time alignment in ptp_ocp_signal_set
+
+From: Sagi Maimon <maimon.sagi@gmail.com>
+
+[ Upstream commit 2a5970d5aaff8f3e33ce3bfaa403ae88c40de40d ]
+
+In ptp_ocp_signal_set, the start time for periodic signals is not
+aligned to the next period boundary. The current code rounds up the
+start time and divides by the period but fails to multiply back by
+the period, causing misaligned signal starts. Fix this by multiplying
+the rounded-up value by the period to ensure the start time is the
+closest next period.
+
+Fixes: 4bd46bb037f8e ("ptp: ocp: Use DIV64_U64_ROUND_UP for rounding.")
+Signed-off-by: Sagi Maimon <maimon.sagi@gmail.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Link: https://patch.msgid.link/20250415053131.129413-1-maimon.sagi@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ptp/ptp_ocp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c
+index 13343c3198770..4899fdf9bdf7a 100644
+--- a/drivers/ptp/ptp_ocp.c
++++ b/drivers/ptp/ptp_ocp.c
+@@ -1842,6 +1842,7 @@ ptp_ocp_signal_set(struct ptp_ocp *bp, int gen, struct ptp_ocp_signal *s)
+ if (!s->start) {
+ /* roundup() does not work on 32-bit systems */
+ s->start = DIV64_U64_ROUND_UP(start_ns, s->period);
++ s->start *= s->period;
+ s->start = ktime_add(s->start, s->phase);
+ }
+
+--
+2.39.5
+
--- /dev/null
+From 140033c81c2a7baaeb98f988c360f82fdb98951d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Mar 2025 14:42:21 +0200
+Subject: RDMA/core: Silence oversized kvmalloc() warning
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit 9a0e6f15029e1a8a21e40f06fd05aa52b7f063de ]
+
+syzkaller triggered an oversized kvmalloc() warning.
+Silence it by adding __GFP_NOWARN.
+
+syzkaller log:
+ WARNING: CPU: 7 PID: 518 at mm/util.c:665 __kvmalloc_node_noprof+0x175/0x180
+ CPU: 7 UID: 0 PID: 518 Comm: c_repro Not tainted 6.11.0-rc6+ #6
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
+ RIP: 0010:__kvmalloc_node_noprof+0x175/0x180
+ RSP: 0018:ffffc90001e67c10 EFLAGS: 00010246
+ RAX: 0000000000000100 RBX: 0000000000000400 RCX: ffffffff8149d46b
+ RDX: 0000000000000000 RSI: ffff8881030fae80 RDI: 0000000000000002
+ RBP: 000000712c800000 R08: 0000000000000100 R09: 0000000000000000
+ R10: ffffc90001e67c10 R11: 0030ae0601000000 R12: 0000000000000000
+ R13: 0000000000000000 R14: 00000000ffffffff R15: 0000000000000000
+ FS: 00007fde79159740(0000) GS:ffff88813bdc0000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 0000000020000180 CR3: 0000000105eb4005 CR4: 00000000003706b0
+ DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+ DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+ Call Trace:
+ <TASK>
+ ib_umem_odp_get+0x1f6/0x390
+ mlx5_ib_reg_user_mr+0x1e8/0x450
+ ib_uverbs_reg_mr+0x28b/0x440
+ ib_uverbs_write+0x7d3/0xa30
+ vfs_write+0x1ac/0x6c0
+ ksys_write+0x134/0x170
+ ? __sanitizer_cov_trace_pc+0x1c/0x50
+ do_syscall_64+0x50/0x110
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Fixes: 37824952dc8f ("RDMA/odp: Use kvcalloc for the dma_list and page_list")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Link: https://patch.msgid.link/c6cb92379de668be94894f49c2cfa40e73f94d56.1742388096.git.leonro@nvidia.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/umem_odp.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c
+index e9fa22d31c233..c48ef60830205 100644
+--- a/drivers/infiniband/core/umem_odp.c
++++ b/drivers/infiniband/core/umem_odp.c
+@@ -76,12 +76,14 @@ static inline int ib_init_umem_odp(struct ib_umem_odp *umem_odp,
+
+ npfns = (end - start) >> PAGE_SHIFT;
+ umem_odp->pfn_list = kvcalloc(
+- npfns, sizeof(*umem_odp->pfn_list), GFP_KERNEL);
++ npfns, sizeof(*umem_odp->pfn_list),
++ GFP_KERNEL | __GFP_NOWARN);
+ if (!umem_odp->pfn_list)
+ return -ENOMEM;
+
+ umem_odp->dma_list = kvcalloc(
+- ndmas, sizeof(*umem_odp->dma_list), GFP_KERNEL);
++ ndmas, sizeof(*umem_odp->dma_list),
++ GFP_KERNEL | __GFP_NOWARN);
+ if (!umem_odp->dma_list) {
+ ret = -ENOMEM;
+ goto out_pfn_list;
+--
+2.39.5
+
--- /dev/null
+From d526d740875dcd7a5bb5a9f8cd1904d8cf29eae3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Mar 2025 19:47:24 +0800
+Subject: RDMA/hns: Fix wrong maximum DMA segment size
+
+From: Chengchang Tang <tangchengchang@huawei.com>
+
+[ Upstream commit 9beb2c91fb86e0be70a5833c6730441fa3c9efa8 ]
+
+Set maximum DMA segment size to 2G instead of UINT_MAX due to HW limit.
+
+Fixes: e0477b34d9d1 ("RDMA: Explicitly pass in the dma_device to ib_register_device")
+Link: https://patch.msgid.link/r/20250327114724.3454268-3-huangjunxian6@hisilicon.com
+Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
+Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c
+index dcd763dbb636d..a7e4c951f8fe4 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_main.c
++++ b/drivers/infiniband/hw/hns/hns_roce_main.c
+@@ -731,7 +731,7 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev)
+ if (ret)
+ return ret;
+ }
+- dma_set_max_seg_size(dev, UINT_MAX);
++ dma_set_max_seg_size(dev, SZ_2G);
+ ret = ib_register_device(ib_dev, "hns_%d", dev);
+ if (ret) {
+ dev_err(dev, "ib_register_device failed!\n");
+--
+2.39.5
+
--- /dev/null
+From a0e02b5acf63fc67398b4c54a6f8f0e75680673b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 20:31:32 +0800
+Subject: RDMA/usnic: Fix passing zero to PTR_ERR in usnic_ib_pci_probe()
+
+From: Yue Haibing <yuehaibing@huawei.com>
+
+[ Upstream commit 95ba3850fed03e01b422ab5d7943aeba130c9723 ]
+
+drivers/infiniband/hw/usnic/usnic_ib_main.c:590
+ usnic_ib_pci_probe() warn: passing zero to 'PTR_ERR'
+
+Make usnic_ib_device_add() return NULL on fail path, also remove
+useless NULL check for usnic_ib_discover_pf()
+
+Fixes: e3cf00d0a87f ("IB/usnic: Add Cisco VIC low-level hardware driver")
+Link: https://patch.msgid.link/r/20250324123132.2392077-1-yuehaibing@huawei.com
+Signed-off-by: Yue Haibing <yuehaibing@huawei.com>
+Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev>
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/usnic/usnic_ib_main.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/infiniband/hw/usnic/usnic_ib_main.c b/drivers/infiniband/hw/usnic/usnic_ib_main.c
+index 13b654ddd3cc8..bcf7d8607d56e 100644
+--- a/drivers/infiniband/hw/usnic/usnic_ib_main.c
++++ b/drivers/infiniband/hw/usnic/usnic_ib_main.c
+@@ -380,7 +380,7 @@ static void *usnic_ib_device_add(struct pci_dev *dev)
+ if (!us_ibdev) {
+ usnic_err("Device %s context alloc failed\n",
+ netdev_name(pci_get_drvdata(dev)));
+- return ERR_PTR(-EFAULT);
++ return NULL;
+ }
+
+ us_ibdev->ufdev = usnic_fwd_dev_alloc(dev);
+@@ -500,8 +500,8 @@ static struct usnic_ib_dev *usnic_ib_discover_pf(struct usnic_vnic *vnic)
+ }
+
+ us_ibdev = usnic_ib_device_add(parent_pci);
+- if (IS_ERR_OR_NULL(us_ibdev)) {
+- us_ibdev = us_ibdev ? us_ibdev : ERR_PTR(-EFAULT);
++ if (!us_ibdev) {
++ us_ibdev = ERR_PTR(-EFAULT);
+ goto out;
+ }
+
+@@ -569,10 +569,10 @@ static int usnic_ib_pci_probe(struct pci_dev *pdev,
+ }
+
+ pf = usnic_ib_discover_pf(vf->vnic);
+- if (IS_ERR_OR_NULL(pf)) {
+- usnic_err("Failed to discover pf of vnic %s with err%ld\n",
+- pci_name(pdev), PTR_ERR(pf));
+- err = pf ? PTR_ERR(pf) : -EFAULT;
++ if (IS_ERR(pf)) {
++ err = PTR_ERR(pf);
++ usnic_err("Failed to discover pf of vnic %s with err%d\n",
++ pci_name(pdev), err);
+ goto out_clean_vnic;
+ }
+
+--
+2.39.5
+
--- /dev/null
+From efe8ebd31fc7030027340adfe3dd14044efcb7f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 16:13:34 +0200
+Subject: Revert "wifi: mac80211: Update skb's control block key in
+ ieee80211_tx_dequeue()"
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 0937cb5f345c79d702b4d0d744e2a2529b551cb2 ]
+
+This reverts commit a104042e2bf6528199adb6ca901efe7b60c2c27f.
+
+Since the original bug seems to have been around for years,
+but a new issue was report with the fix, revert the fix for
+now. We have a couple of weeks to figure it out for this
+release, if needed.
+
+Reported-by: Bert Karwatzki <spasswolf@web.de>
+Closes: https://lore.kernel.org/linux-wireless/20250410215527.3001-1-spasswolf@web.de
+Fixes: a104042e2bf6 ("wifi: mac80211: Update skb's control block key in ieee80211_tx_dequeue()")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/tx.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index 8c46498152d76..45a093d3f1fa7 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -3877,7 +3877,6 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
+ * The key can be removed while the packet was queued, so need to call
+ * this here to get the current key.
+ */
+- info->control.hw_key = NULL;
+ r = ieee80211_tx_h_select_key(&tx);
+ if (r != TX_CONTINUE) {
+ ieee80211_free_txskb(&local->hw, skb);
+--
+2.39.5
+
--- /dev/null
+From 32db1fd7de901d8b7412aab5e2f8cffb7bcd8af7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 15:32:21 +0800
+Subject: riscv: KGDB: Do not inline arch_kgdb_breakpoint()
+
+From: WangYuli <wangyuli@uniontech.com>
+
+[ Upstream commit 3af4bec9c1db3f003be4d5ae09b6a737e4be1612 ]
+
+The arch_kgdb_breakpoint() function defines the kgdb_compiled_break
+symbol using inline assembly.
+
+There's a potential issue where the compiler might inline
+arch_kgdb_breakpoint(), which would then define the kgdb_compiled_break
+symbol multiple times, leading to fail to link vmlinux.o.
+
+This isn't merely a potential compilation problem. The intent here
+is to determine the global symbol address of kgdb_compiled_break,
+and if this function is inlined multiple times, it would logically
+be a grave error.
+
+Link: https://lore.kernel.org/all/4b4187c1-77e5-44b7-885f-d6826723dd9a@sifive.com/
+Link: https://lore.kernel.org/all/5b0adf9b-2b22-43fe-ab74-68df94115b9a@ghiti.fr/
+Link: https://lore.kernel.org/all/23693e7f-4fff-40f3-a437-e06d827278a5@ghiti.fr/
+Fixes: fe89bd2be866 ("riscv: Add KGDB support")
+Co-developed-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: WangYuli <wangyuli@uniontech.com>
+Link: https://lore.kernel.org/r/F22359AFB6FF9FD8+20250411073222.56820-1-wangyuli@uniontech.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/include/asm/kgdb.h | 9 +--------
+ arch/riscv/kernel/kgdb.c | 8 ++++++++
+ 2 files changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/arch/riscv/include/asm/kgdb.h b/arch/riscv/include/asm/kgdb.h
+index 46677daf708bd..cc11c4544cffd 100644
+--- a/arch/riscv/include/asm/kgdb.h
++++ b/arch/riscv/include/asm/kgdb.h
+@@ -19,16 +19,9 @@
+
+ #ifndef __ASSEMBLY__
+
++void arch_kgdb_breakpoint(void);
+ extern unsigned long kgdb_compiled_break;
+
+-static inline void arch_kgdb_breakpoint(void)
+-{
+- asm(".global kgdb_compiled_break\n"
+- ".option norvc\n"
+- "kgdb_compiled_break: ebreak\n"
+- ".option rvc\n");
+-}
+-
+ #endif /* !__ASSEMBLY__ */
+
+ #define DBG_REG_ZERO "zero"
+diff --git a/arch/riscv/kernel/kgdb.c b/arch/riscv/kernel/kgdb.c
+index 2e0266ae6bd72..5d1ce8dacaf58 100644
+--- a/arch/riscv/kernel/kgdb.c
++++ b/arch/riscv/kernel/kgdb.c
+@@ -254,6 +254,14 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
+ regs->epc = pc;
+ }
+
++noinline void arch_kgdb_breakpoint(void)
++{
++ asm(".global kgdb_compiled_break\n"
++ ".option norvc\n"
++ "kgdb_compiled_break: ebreak\n"
++ ".option rvc\n");
++}
++
+ void kgdb_arch_handle_qxfer_pkt(char *remcom_in_buffer,
+ char *remcom_out_buffer)
+ {
+--
+2.39.5
+
--- /dev/null
+From d111649e68aab6cc65704252e7c0754e97085a5e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 15:32:22 +0800
+Subject: riscv: KGDB: Remove ".option norvc/.option rvc" for
+ kgdb_compiled_break
+
+From: WangYuli <wangyuli@uniontech.com>
+
+[ Upstream commit 550c2aa787d1b06efcb11de1877354502a1237f2 ]
+
+[ Quoting Samuel Holland: ]
+
+ This is a separate issue, but using ".option rvc" here is a bug.
+ It will unconditionally enable the C extension for the rest of
+ the file, even if the kernel is being built with CONFIG_RISCV_ISA_C=n.
+
+[ Quoting Palmer Dabbelt: ]
+
+ We're just looking at the address of kgdb_compiled_break, so it's
+ fine if it ends up as a c.ebreak.
+
+[ Quoting Alexandre Ghiti: ]
+
+ .option norvc is used to prevent the assembler from using compressed
+ instructions, but it's generally used when we need to ensure the
+ size of the instructions that are used, which is not the case here
+ as noted by Palmer since we only care about the address. So yes
+ it will work fine with C enabled :)
+
+So let's just remove them all.
+
+Link: https://lore.kernel.org/all/4b4187c1-77e5-44b7-885f-d6826723dd9a@sifive.com/
+Link: https://lore.kernel.org/all/mhng-69513841-5068-441d-be8f-2aeebdc56a08@palmer-ri-x1c9a/
+Link: https://lore.kernel.org/all/23693e7f-4fff-40f3-a437-e06d827278a5@ghiti.fr/
+Fixes: fe89bd2be866 ("riscv: Add KGDB support")
+Cc: Samuel Holland <samuel.holland@sifive.com>
+Cc: Palmer Dabbelt <palmer@dabbelt.com>
+Cc: Alexandre Ghiti <alex@ghiti.fr>
+Signed-off-by: WangYuli <wangyuli@uniontech.com>
+Link: https://lore.kernel.org/r/8B431C6A4626225C+20250411073222.56820-2-wangyuli@uniontech.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/kgdb.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/arch/riscv/kernel/kgdb.c b/arch/riscv/kernel/kgdb.c
+index 5d1ce8dacaf58..9f3db3503dabd 100644
+--- a/arch/riscv/kernel/kgdb.c
++++ b/arch/riscv/kernel/kgdb.c
+@@ -257,9 +257,7 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
+ noinline void arch_kgdb_breakpoint(void)
+ {
+ asm(".global kgdb_compiled_break\n"
+- ".option norvc\n"
+- "kgdb_compiled_break: ebreak\n"
+- ".option rvc\n");
++ "kgdb_compiled_break: ebreak\n");
+ }
+
+ void kgdb_arch_handle_qxfer_pkt(char *remcom_in_buffer,
+--
+2.39.5
+
--- /dev/null
+From c767cd919da46674a7c25aeb8b24b2cc711c0952 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 20:21:27 +0200
+Subject: riscv: Properly export reserved regions in /proc/iomem
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Björn Töpel <bjorn@rivosinc.com>
+
+[ Upstream commit e94eb7ea6f206e229791761a5fdf9389f8dbd183 ]
+
+The /proc/iomem represents the kernel's memory map. Regions marked
+with "Reserved" tells the user that the range should not be tampered
+with. Kexec-tools, when using the older kexec_load syscall relies on
+the "Reserved" regions to build the memory segments, that will be the
+target of the new kexec'd kernel.
+
+The RISC-V port tries to expose all reserved regions to userland, but
+some regions were not properly exposed: Regions that resided in both
+the "regular" and reserved memory block, e.g. the EFI Memory Map. A
+missing entry could result in reserved memory being overwritten.
+
+It turns out, that arm64, and loongarch had a similar issue a while
+back:
+
+ commit d91680e687f4 ("arm64: Fix /proc/iomem for reserved but not memory regions")
+ commit 50d7ba36b916 ("arm64: export memblock_reserve()d regions via /proc/iomem")
+
+Similar to the other ports, resolve the issue by splitting the regions
+in an arch initcall, since we need a working allocator.
+
+Fixes: ffe0e5261268 ("RISC-V: Improve init_resources()")
+Signed-off-by: Björn Töpel <bjorn@rivosinc.com>
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Link: https://lore.kernel.org/r/20250409182129.634415-1-bjorn@kernel.org
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/setup.c | 36 +++++++++++++++++++++++++++++++++++-
+ 1 file changed, 35 insertions(+), 1 deletion(-)
+
+diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
+index 175184b059264..f598e0eb3b0a0 100644
+--- a/arch/riscv/kernel/setup.c
++++ b/arch/riscv/kernel/setup.c
+@@ -73,6 +73,9 @@ static struct resource bss_res = { .name = "Kernel bss", };
+ static struct resource elfcorehdr_res = { .name = "ELF Core hdr", };
+ #endif
+
++static int num_standard_resources;
++static struct resource *standard_resources;
++
+ static int __init add_resource(struct resource *parent,
+ struct resource *res)
+ {
+@@ -146,7 +149,7 @@ static void __init init_resources(void)
+ struct resource *res = NULL;
+ struct resource *mem_res = NULL;
+ size_t mem_res_sz = 0;
+- int num_resources = 0, res_idx = 0;
++ int num_resources = 0, res_idx = 0, non_resv_res = 0;
+ int ret = 0;
+
+ /* + 1 as memblock_alloc() might increase memblock.reserved.cnt */
+@@ -215,6 +218,7 @@ static void __init init_resources(void)
+ /* Add /memory regions to the resource tree */
+ for_each_mem_region(region) {
+ res = &mem_res[res_idx--];
++ non_resv_res++;
+
+ if (unlikely(memblock_is_nomap(region))) {
+ res->name = "Reserved";
+@@ -232,6 +236,9 @@ static void __init init_resources(void)
+ goto error;
+ }
+
++ num_standard_resources = non_resv_res;
++ standard_resources = &mem_res[res_idx + 1];
++
+ /* Clean-up any unused pre-allocated resources */
+ if (res_idx >= 0)
+ memblock_free(mem_res, (res_idx + 1) * sizeof(*mem_res));
+@@ -243,6 +250,33 @@ static void __init init_resources(void)
+ memblock_free(mem_res, mem_res_sz);
+ }
+
++static int __init reserve_memblock_reserved_regions(void)
++{
++ u64 i, j;
++
++ for (i = 0; i < num_standard_resources; i++) {
++ struct resource *mem = &standard_resources[i];
++ phys_addr_t r_start, r_end, mem_size = resource_size(mem);
++
++ if (!memblock_is_region_reserved(mem->start, mem_size))
++ continue;
++
++ for_each_reserved_mem_range(j, &r_start, &r_end) {
++ resource_size_t start, end;
++
++ start = max(PFN_PHYS(PFN_DOWN(r_start)), mem->start);
++ end = min(PFN_PHYS(PFN_UP(r_end)) - 1, mem->end);
++
++ if (start > mem->end || end < mem->start)
++ continue;
++
++ reserve_region_with_split(mem, start, end, "Reserved");
++ }
++ }
++
++ return 0;
++}
++arch_initcall(reserve_memblock_reserved_regions);
+
+ static void __init parse_dtb(void)
+ {
+--
+2.39.5
+
--- /dev/null
+From bc7591efb732fbfa12a3071da8d5439619d7fb8a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 17:51:34 +0800
+Subject: scsi: hisi_sas: Enable force phy when SATA disk directly connected
+
+From: Xingui Yang <yangxingui@huawei.com>
+
+[ Upstream commit 8aa580cd92843b60d4d6331f3b0a9e8409bb70eb ]
+
+when a SATA disk is directly connected the SAS controller determines the
+disk to which I/Os are delivered based on the port ID in the DQ entry.
+
+When many phys are disconnected and reconnect, the port ID of phys were
+changed and used by other link, resulting in I/O being sent to incorrect
+disk. Data inconsistency on the SATA disk may occur during I/O retries
+using the old port ID. So enable force phy, then force the command to be
+executed in a certain phy, and if the actual phy ID of the port does not
+match the phy configured in the command, the chip will stop delivering the
+I/O to disk.
+
+Fixes: ce60689e12dd ("scsi: hisi_sas: add v3 code to send ATA frame")
+Signed-off-by: Xingui Yang <yangxingui@huawei.com>
+Link: https://lore.kernel.org/r/20250312095135.3048379-2-yangxingui@huawei.com
+Reviewed-by: Yihang Li <liyihang9@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 9 +++++++--
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 14 ++++++++++++--
+ 2 files changed, 19 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index 73b378837da7b..e6bcc3171391c 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -2501,6 +2501,7 @@ static void prep_ata_v2_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_port *port = to_hisi_sas_port(sas_port);
+ struct sas_ata_task *ata_task = &task->ata_task;
+ struct sas_tmf_task *tmf = slot->tmf;
++ int phy_id;
+ u8 *buf_cmd;
+ int has_data = 0, hdr_tag = 0;
+ u32 dw0, dw1 = 0, dw2 = 0;
+@@ -2508,10 +2509,14 @@ static void prep_ata_v2_hw(struct hisi_hba *hisi_hba,
+ /* create header */
+ /* dw0 */
+ dw0 = port->id << CMD_HDR_PORT_OFF;
+- if (parent_dev && dev_is_expander(parent_dev->dev_type))
++ if (parent_dev && dev_is_expander(parent_dev->dev_type)) {
+ dw0 |= 3 << CMD_HDR_CMD_OFF;
+- else
++ } else {
++ phy_id = device->phy->identify.phy_identifier;
++ dw0 |= (1U << phy_id) << CMD_HDR_PHY_ID_OFF;
++ dw0 |= CMD_HDR_FORCE_PHY_MSK;
+ dw0 |= 4 << CMD_HDR_CMD_OFF;
++ }
+
+ if (tmf && ata_task->force_phy) {
+ dw0 |= CMD_HDR_FORCE_PHY_MSK;
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index ff5f86867dbf0..596b5426d9953 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -358,6 +358,10 @@
+ #define CMD_HDR_RESP_REPORT_MSK (0x1 << CMD_HDR_RESP_REPORT_OFF)
+ #define CMD_HDR_TLR_CTRL_OFF 6
+ #define CMD_HDR_TLR_CTRL_MSK (0x3 << CMD_HDR_TLR_CTRL_OFF)
++#define CMD_HDR_PHY_ID_OFF 8
++#define CMD_HDR_PHY_ID_MSK (0x1ff << CMD_HDR_PHY_ID_OFF)
++#define CMD_HDR_FORCE_PHY_OFF 17
++#define CMD_HDR_FORCE_PHY_MSK (0x1U << CMD_HDR_FORCE_PHY_OFF)
+ #define CMD_HDR_PORT_OFF 18
+ #define CMD_HDR_PORT_MSK (0xf << CMD_HDR_PORT_OFF)
+ #define CMD_HDR_PRIORITY_OFF 27
+@@ -1425,15 +1429,21 @@ static void prep_ata_v3_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr;
+ struct asd_sas_port *sas_port = device->port;
+ struct hisi_sas_port *port = to_hisi_sas_port(sas_port);
++ int phy_id;
+ u8 *buf_cmd;
+ int has_data = 0, hdr_tag = 0;
+ u32 dw1 = 0, dw2 = 0;
+
+ hdr->dw0 = cpu_to_le32(port->id << CMD_HDR_PORT_OFF);
+- if (parent_dev && dev_is_expander(parent_dev->dev_type))
++ if (parent_dev && dev_is_expander(parent_dev->dev_type)) {
+ hdr->dw0 |= cpu_to_le32(3 << CMD_HDR_CMD_OFF);
+- else
++ } else {
++ phy_id = device->phy->identify.phy_identifier;
++ hdr->dw0 |= cpu_to_le32((1U << phy_id)
++ << CMD_HDR_PHY_ID_OFF);
++ hdr->dw0 |= CMD_HDR_FORCE_PHY_MSK;
+ hdr->dw0 |= cpu_to_le32(4U << CMD_HDR_CMD_OFF);
++ }
+
+ switch (task->data_dir) {
+ case DMA_TO_DEVICE:
+--
+2.39.5
+
--- /dev/null
+From 2bb73321329f392f12cd0823175320ff27ac8bf3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 17:43:43 +0800
+Subject: scsi: iscsi: Fix missing scsi_host_put() in error path
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 72eea84a1092b50a10eeecfeba4b28ac9f1312ab ]
+
+Add goto to ensure scsi_host_put() is called in all error paths of
+iscsi_set_host_param() function. This fixes a potential memory leak when
+strlen() check fails.
+
+Fixes: ce51c8170084 ("scsi: iscsi: Add strlen() check in iscsi_if_set{_host}_param()")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20250318094344.91776-1-linmq006@gmail.com
+Reviewed-by: Mike Christie <michael.christie@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_transport_iscsi.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index deeb657981a69..0c30fec555475 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -3208,11 +3208,14 @@ iscsi_set_host_param(struct iscsi_transport *transport,
+ }
+
+ /* see similar check in iscsi_if_set_param() */
+- if (strlen(data) > ev->u.set_host_param.len)
+- return -EINVAL;
++ if (strlen(data) > ev->u.set_host_param.len) {
++ err = -EINVAL;
++ goto out;
++ }
+
+ err = transport->set_host_param(shost, ev->u.set_host_param.param,
+ data, ev->u.set_host_param.len);
++out:
+ scsi_host_put(shost);
+ return err;
+ }
+--
+2.39.5
+
media-mediatek-vcodec-mark-vdec_vp9_slice_map_counts_eob_coef-noinline.patch
bluetooth-hci_uart-fix-another-race-during-initialization.patch
hsi-ssi_protocol-fix-use-after-free-vulnerability-in-ssi_protocol-driver-due-to-race-condition.patch
+scsi-hisi_sas-enable-force-phy-when-sata-disk-direct.patch
+wifi-at76c50x-fix-use-after-free-access-in-at76_disc.patch
+wifi-mac80211-update-skb-s-control-block-key-in-ieee.patch
+wifi-mac80211-purge-vif-txq-in-ieee80211_do_stop.patch
+wifi-wl1251-fix-memory-leak-in-wl1251_tx_work.patch
+scsi-iscsi-fix-missing-scsi_host_put-in-error-path.patch
+md-raid10-fix-missing-discard-io-accounting.patch
+md-md-bitmap-fix-stats-collection-for-external-bitma.patch
+asoc-dwc-always-enable-disable-i2s-irqs.patch
+asoc-intel-avs-fix-null-ptr-deref-in-avs_component_p.patch
+ovl-remove-unused-forward-declaration.patch
+rdma-usnic-fix-passing-zero-to-ptr_err-in-usnic_ib_p.patch
+rdma-hns-fix-wrong-maximum-dma-segment-size.patch
+asoc-cs42l43-reset-clamp-override-on-jack-removal.patch
+rdma-core-silence-oversized-kvmalloc-warning.patch
+bluetooth-hci_event-fix-sending-mgmt_ev_device_found.patch
+bluetooth-btrtl-prevent-potential-null-dereference.patch
+bluetooth-l2cap-check-encryption-key-size-on-incomin.patch
+revert-wifi-mac80211-update-skb-s-control-block-key-.patch
+igc-fix-ptm-cycle-trigger-logic.patch
+igc-increase-wait-time-before-retrying-ptm.patch
+igc-move-ktime-snapshot-into-ptm-retry-loop.patch
+igc-handle-the-igc_ptp_enabled-flag-correctly.patch
+igc-cleanup-ptp-module-if-probe-fails.patch
+igc-add-lock-preventing-multiple-simultaneous-ptm-tr.patch
+test-suite-use-zu-to-print-size_t.patch
+pds_core-fix-memory-leak-in-pdsc_debugfs_add_qcq.patch
+net-mctp-set-sock_rcu_free.patch
+block-fix-resource-leak-in-blk_register_queue-error-.patch
+net-openvswitch-fix-nested-key-length-validation-in-.patch
+net-ngbe-fix-memory-leak-in-ngbe_probe-error-path.patch
+net-ethernet-ti-am65-cpsw-nuss-rename-phy_node-port_.patch
+net-ethernet-ti-am65-cpsw-fix-port_np-reference-coun.patch
+ata-libata-sata-save-all-fields-from-sense-data-desc.patch
+cxgb4-fix-memory-leak-in-cxgb4_init_ethtool_filters-.patch
+tools-ynl-gen-track-attribute-use.patch
+tools-ynl-gen-record-information-about-recursive-nes.patch
+tools-ynl-gen-re-sort-ignoring-recursive-nests.patch
+tools-ynl-gen-store-recursive-nests-by-a-pointer.patch
+tools-ynl-gen-individually-free-previous-values-on-d.patch
+netlink-specs-rt-link-add-an-attr-layer-around-alt-i.patch
+netlink-specs-rt-link-adjust-mctp-attribute-naming.patch
+net-b53-enable-bpdu-reception-for-management-port.patch
+net-bridge-switchdev-do-not-notify-new-brentries-as-.patch
+net-dsa-mv88e6xxx-avoid-unregistering-devlink-region.patch
+net-dsa-mv88e6xxx-fix-enoent-when-deleting-vlans-and.patch
+net-dsa-clean-up-fdb-mdb-vlan-entries-on-unbind.patch
+net-dsa-free-routing-table-on-probe-failure.patch
+net-dsa-avoid-refcount-warnings-when-ds-ops-tag_8021.patch
+ptp-ocp-fix-start-time-alignment-in-ptp_ocp_signal_s.patch
+net-ti-icss-iep-add-pwidth-configuration-for-perout-.patch
+net-ti-icss-iep-add-phase-offset-configuration-for-p.patch
+net-ti-icss-iep-fix-possible-null-pointer-dereferenc.patch
+net-ethernet-mtk_eth_soc-correct-the-max-weight-of-t.patch
+net-ethernet-mtk_eth_soc-revise-qdma-packet-schedule.patch
+riscv-properly-export-reserved-regions-in-proc-iomem.patch
+kunit-qemu_configs-sh-respect-kunit-cmdline.patch
+riscv-kgdb-do-not-inline-arch_kgdb_breakpoint.patch
+riscv-kgdb-remove-.option-norvc-.option-rvc-for-kgdb.patch
+cpufreq-sched-fix-the-usage-of-cpufreq_need_update_l.patch
--- /dev/null
+From ab05f6d4aa3dd1317cbd5a2b2ecdf3f0f104521e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 20:33:11 -0400
+Subject: test suite: use %zu to print size_t
+
+From: Matthew Wilcox (Oracle) <willy@infradead.org>
+
+[ Upstream commit a30951d09c33c899f0e4aca80eb87fad5f10ecfa ]
+
+On 32-bit, we can't use %lu to print a size_t variable and gcc warns us
+about it. Shame it doesn't warn about it on 64-bit.
+
+Link: https://lkml.kernel.org/r/20250403003311.359917-1-Liam.Howlett@oracle.com
+Fixes: cc86e0c2f306 ("radix tree test suite: add support for slab bulk APIs")
+Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/radix-tree/linux.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/radix-tree/linux.c b/tools/testing/radix-tree/linux.c
+index d587a558997f8..11149bd12a1f7 100644
+--- a/tools/testing/radix-tree/linux.c
++++ b/tools/testing/radix-tree/linux.c
+@@ -121,7 +121,7 @@ void kmem_cache_free(struct kmem_cache *cachep, void *objp)
+ void kmem_cache_free_bulk(struct kmem_cache *cachep, size_t size, void **list)
+ {
+ if (kmalloc_verbose)
+- pr_debug("Bulk free %p[0-%lu]\n", list, size - 1);
++ pr_debug("Bulk free %p[0-%zu]\n", list, size - 1);
+
+ pthread_mutex_lock(&cachep->lock);
+ for (int i = 0; i < size; i++)
+@@ -139,7 +139,7 @@ int kmem_cache_alloc_bulk(struct kmem_cache *cachep, gfp_t gfp, size_t size,
+ size_t i;
+
+ if (kmalloc_verbose)
+- pr_debug("Bulk alloc %lu\n", size);
++ pr_debug("Bulk alloc %zu\n", size);
+
+ if (!(gfp & __GFP_DIRECT_RECLAIM)) {
+ if (cachep->non_kernel < size)
+--
+2.39.5
+
--- /dev/null
+From 5604949695e5b874289ce8143d8a4c1e1fe97374 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 14:18:46 -0700
+Subject: tools: ynl-gen: individually free previous values on double set
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit ce6cb8113c842b94e77364b247c4f85c7b34e0c2 ]
+
+When user calls request_attrA_set() multiple times (for the same
+attribute), and attrA is of type which allocates memory -
+we try to free the previously associated values. For array
+types (including multi-attr) we have only freed the array,
+but the array may have contained pointers.
+
+Refactor the code generation for free attr and reuse the generated
+lines in setters to flush out the previous state. Since setters
+are static inlines in the header we need to add forward declarations
+for the free helpers of pure nested structs. Track which types get
+used by arrays and include the right forwad declarations.
+
+At least ethtool string set and bit set would not be freed without
+this. Tho, admittedly, overriding already set attribute twice is likely
+a very very rare thing to do.
+
+Fixes: be5bea1cc0bf ("net: add basic C code generators for Netlink")
+Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20250414211851.602096-4-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/net/ynl/ynl-gen-c.py | 62 +++++++++++++++++++++++++++-----------
+ 1 file changed, 45 insertions(+), 17 deletions(-)
+
+diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py
+index 9e37d14d76bf9..53c86d3897e13 100755
+--- a/tools/net/ynl/ynl-gen-c.py
++++ b/tools/net/ynl/ynl-gen-c.py
+@@ -107,9 +107,15 @@ class Type(SpecAttr):
+ def free_needs_iter(self):
+ return False
+
+- def free(self, ri, var, ref):
++ def _free_lines(self, ri, var, ref):
+ if self.is_multi_val() or self.presence_type() == 'len':
+- ri.cw.p(f'free({var}->{ref}{self.c_name});')
++ return [f'free({var}->{ref}{self.c_name});']
++ return []
++
++ def free(self, ri, var, ref):
++ lines = self._free_lines(ri, var, ref)
++ for line in lines:
++ ri.cw.p(line)
+
+ def arg_member(self, ri):
+ member = self._complex_member_type(ri)
+@@ -205,6 +211,10 @@ class Type(SpecAttr):
+ var = "req"
+ member = f"{var}->{'.'.join(ref)}"
+
++ local_vars = []
++ if self.free_needs_iter():
++ local_vars += ['unsigned int i;']
++
+ code = []
+ presence = ''
+ for i in range(0, len(ref)):
+@@ -214,6 +224,10 @@ class Type(SpecAttr):
+ if i == len(ref) - 1 and self.presence_type() != 'bit':
+ continue
+ code.append(presence + ' = 1;')
++ ref_path = '.'.join(ref[:-1])
++ if ref_path:
++ ref_path += '.'
++ code += self._free_lines(ri, var, ref_path)
+ code += self._setter_lines(ri, member, presence)
+
+ func_name = f"{op_prefix(ri, direction, deref=deref)}_set_{'_'.join(ref)}"
+@@ -221,7 +235,8 @@ class Type(SpecAttr):
+ alloc = bool([x for x in code if 'alloc(' in x])
+ if free and not alloc:
+ func_name = '__' + func_name
+- ri.cw.write_func('static inline void', func_name, body=code,
++ ri.cw.write_func('static inline void', func_name, local_vars=local_vars,
++ body=code,
+ args=[f'{type_name(ri, direction, deref=deref)} *{var}'] + self.arg_member(ri))
+
+
+@@ -397,8 +412,7 @@ class TypeString(Type):
+ ['unsigned int len;']
+
+ def _setter_lines(self, ri, member, presence):
+- return [f"free({member});",
+- f"{presence}_len = strlen({self.c_name});",
++ return [f"{presence}_len = strlen({self.c_name});",
+ f"{member} = malloc({presence}_len + 1);",
+ f'memcpy({member}, {self.c_name}, {presence}_len);',
+ f'{member}[{presence}_len] = 0;']
+@@ -441,8 +455,7 @@ class TypeBinary(Type):
+ ['unsigned int len;']
+
+ def _setter_lines(self, ri, member, presence):
+- return [f"free({member});",
+- f"{presence}_len = len;",
++ return [f"{presence}_len = len;",
+ f"{member} = malloc({presence}_len);",
+ f'memcpy({member}, {self.c_name}, {presence}_len);']
+
+@@ -454,12 +467,14 @@ class TypeNest(Type):
+ def _complex_member_type(self, ri):
+ return self.nested_struct_type
+
+- def free(self, ri, var, ref):
++ def _free_lines(self, ri, var, ref):
++ lines = []
+ at = '&'
+ if self.is_recursive_for_op(ri):
+ at = ''
+- ri.cw.p(f'if ({var}->{ref}{self.c_name})')
+- ri.cw.p(f'{self.nested_render_name}_free({at}{var}->{ref}{self.c_name});')
++ lines += [f'if ({var}->{ref}{self.c_name})']
++ lines += [f'{self.nested_render_name}_free({at}{var}->{ref}{self.c_name});']
++ return lines
+
+ def _attr_typol(self):
+ return f'.type = YNL_PT_NEST, .nest = &{self.nested_render_name}_nest, '
+@@ -519,15 +534,19 @@ class TypeMultiAttr(Type):
+ def free_needs_iter(self):
+ return 'type' not in self.attr or self.attr['type'] == 'nest'
+
+- def free(self, ri, var, ref):
++ def _free_lines(self, ri, var, ref):
++ lines = []
+ if self.attr['type'] in scalars:
+- ri.cw.p(f"free({var}->{ref}{self.c_name});")
++ lines += [f"free({var}->{ref}{self.c_name});"]
+ elif 'type' not in self.attr or self.attr['type'] == 'nest':
+- ri.cw.p(f"for (i = 0; i < {var}->{ref}n_{self.c_name}; i++)")
+- ri.cw.p(f'{self.nested_render_name}_free(&{var}->{ref}{self.c_name}[i]);')
+- ri.cw.p(f"free({var}->{ref}{self.c_name});")
++ lines += [
++ f"for (i = 0; i < {var}->{ref}n_{self.c_name}; i++)",
++ f'{self.nested_render_name}_free(&{var}->{ref}{self.c_name}[i]);',
++ f"free({var}->{ref}{self.c_name});",
++ ]
+ else:
+ raise Exception(f"Free of MultiAttr sub-type {self.attr['type']} not supported yet")
++ return lines
+
+ def _attr_policy(self, policy):
+ return self.base_type._attr_policy(policy)
+@@ -553,8 +572,7 @@ class TypeMultiAttr(Type):
+ def _setter_lines(self, ri, member, presence):
+ # For multi-attr we have a count, not presence, hack up the presence
+ presence = presence[:-(len('_present.') + len(self.c_name))] + "n_" + self.c_name
+- return [f"free({member});",
+- f"{member} = {self.c_name};",
++ return [f"{member} = {self.c_name};",
+ f"{presence} = n_{self.c_name};"]
+
+
+@@ -639,6 +657,7 @@ class Struct:
+ self.request = False
+ self.reply = False
+ self.recursive = False
++ self.in_multi_val = False # used by a MultiAttr or and legacy arrays
+
+ self.attr_list = []
+ self.attrs = dict()
+@@ -987,6 +1006,10 @@ class Family(SpecFamily):
+ if attr in rs_members['reply']:
+ self.pure_nested_structs[nested].reply = True
+
++ if spec.is_multi_val():
++ child = self.pure_nested_structs.get(nested)
++ child.in_multi_val = True
++
+ self._sort_pure_types()
+
+ # Propagate the request / reply / recursive
+@@ -1001,6 +1024,8 @@ class Family(SpecFamily):
+ struct.child_nests.update(child.child_nests)
+ child.request |= struct.request
+ child.reply |= struct.reply
++ if spec.is_multi_val():
++ child.in_multi_val = True
+ if attr_set in struct.child_nests:
+ struct.recursive = True
+
+@@ -2552,6 +2577,9 @@ def main():
+ for attr_set, struct in parsed.pure_nested_structs.items():
+ ri = RenderInfo(cw, parsed, args.mode, "", "", attr_set)
+ print_type_full(ri, struct)
++ if struct.request and struct.in_multi_val:
++ free_rsp_nested_prototype(ri)
++ cw.nl()
+
+ for op_name, op in parsed.ops.items():
+ cw.p(f"/* ============== {op.enum_name} ============== */")
+--
+2.39.5
+
--- /dev/null
+From 81bea2ea7c3b5153dd4f58b111ee44f9bca2cb46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Dec 2023 15:14:30 -0800
+Subject: tools: ynl-gen: re-sort ignoring recursive nests
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit aa75783b95a1e7fc09129f5364476e6effe47392 ]
+
+We try to keep the structures and helpers "topologically sorted",
+to avoid forward declarations. When recursive nests are at play
+we need to sort twice, because structs which end up being marked
+as recursive will get a full set of forward declarations, so we
+should ignore them for the purpose of sorting.
+
+Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
+Link: https://lore.kernel.org/r/20231213231432.2944749-7-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: ce6cb8113c84 ("tools: ynl-gen: individually free previous values on double set")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/net/ynl/ynl-gen-c.py | 52 +++++++++++++++++++++++---------------
+ 1 file changed, 31 insertions(+), 21 deletions(-)
+
+diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py
+index e5a3e0bb5a39d..502d03b8a758a 100755
+--- a/tools/net/ynl/ynl-gen-c.py
++++ b/tools/net/ynl/ynl-gen-c.py
+@@ -909,6 +909,33 @@ class Family(SpecFamily):
+ self.root_sets[op['attribute-set']]['request'].update(req_attrs)
+ self.root_sets[op['attribute-set']]['reply'].update(rsp_attrs)
+
++ def _sort_pure_types(self):
++ # Try to reorder according to dependencies
++ pns_key_list = list(self.pure_nested_structs.keys())
++ pns_key_seen = set()
++ rounds = len(pns_key_list) ** 2 # it's basically bubble sort
++ for _ in range(rounds):
++ if len(pns_key_list) == 0:
++ break
++ name = pns_key_list.pop(0)
++ finished = True
++ for _, spec in self.attr_sets[name].items():
++ if 'nested-attributes' in spec:
++ nested = spec['nested-attributes']
++ # If the unknown nest we hit is recursive it's fine, it'll be a pointer
++ if self.pure_nested_structs[nested].recursive:
++ continue
++ if nested not in pns_key_seen:
++ # Dicts are sorted, this will make struct last
++ struct = self.pure_nested_structs.pop(name)
++ self.pure_nested_structs[name] = struct
++ finished = False
++ break
++ if finished:
++ pns_key_seen.add(name)
++ else:
++ pns_key_list.append(name)
++
+ def _load_nested_sets(self):
+ attr_set_queue = list(self.root_sets.keys())
+ attr_set_seen = set(self.root_sets.keys())
+@@ -948,27 +975,8 @@ class Family(SpecFamily):
+ if attr in rs_members['reply']:
+ self.pure_nested_structs[nested].reply = True
+
+- # Try to reorder according to dependencies
+- pns_key_list = list(self.pure_nested_structs.keys())
+- pns_key_seen = set()
+- rounds = len(pns_key_list)**2 # it's basically bubble sort
+- for _ in range(rounds):
+- if len(pns_key_list) == 0:
+- break
+- name = pns_key_list.pop(0)
+- finished = True
+- for _, spec in self.attr_sets[name].items():
+- if 'nested-attributes' in spec:
+- if spec['nested-attributes'] not in pns_key_seen:
+- # Dicts are sorted, this will make struct last
+- struct = self.pure_nested_structs.pop(name)
+- self.pure_nested_structs[name] = struct
+- finished = False
+- break
+- if finished:
+- pns_key_seen.add(name)
+- else:
+- pns_key_list.append(name)
++ self._sort_pure_types()
++
+ # Propagate the request / reply / recursive
+ for attr_set, struct in reversed(self.pure_nested_structs.items()):
+ for _, spec in self.attr_sets[attr_set].items():
+@@ -984,6 +992,8 @@ class Family(SpecFamily):
+ if attr_set in struct.child_nests:
+ struct.recursive = True
+
++ self._sort_pure_types()
++
+ def _load_attr_use(self):
+ for _, struct in self.pure_nested_structs.items():
+ if struct.request:
+--
+2.39.5
+
--- /dev/null
+From e81c87860379f30670ad0505ebad1fcc30330348 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Dec 2023 15:14:29 -0800
+Subject: tools: ynl-gen: record information about recursive nests
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 38329fcfb757b8215c07a77b6657721cc7e9530e ]
+
+Track which nests are recursive. Non-recursive nesting gets
+rendered in C as directly nested structs. For recursive
+ones we need to put a pointer in, rather than full struct.
+
+Track this information, no change to generated code, yet.
+
+Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
+Link: https://lore.kernel.org/r/20231213231432.2944749-6-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: ce6cb8113c84 ("tools: ynl-gen: individually free previous values on double set")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/net/ynl/ynl-gen-c.py | 19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py
+index 4c86fe0cd1179..e5a3e0bb5a39d 100755
+--- a/tools/net/ynl/ynl-gen-c.py
++++ b/tools/net/ynl/ynl-gen-c.py
+@@ -80,6 +80,9 @@ class Type(SpecAttr):
+ def is_scalar(self):
+ return self.type in {'u8', 'u16', 'u32', 'u64', 's32', 's64'}
+
++ def is_recursive(self):
++ return False
++
+ def presence_type(self):
+ return 'bit'
+
+@@ -440,6 +443,9 @@ class TypeBinary(Type):
+
+
+ class TypeNest(Type):
++ def is_recursive(self):
++ return self.family.pure_nested_structs[self.nested_attrs].recursive
++
+ def _complex_member_type(self, ri):
+ return self.nested_struct_type
+
+@@ -615,9 +621,12 @@ class Struct:
+ if self.nested and space_name in family.consts:
+ self.struct_name += '_'
+ self.ptr_name = self.struct_name + ' *'
++ # All attr sets this one contains, directly or multiple levels down
++ self.child_nests = set()
+
+ self.request = False
+ self.reply = False
++ self.recursive = False
+
+ self.attr_list = []
+ self.attrs = dict()
+@@ -960,14 +969,20 @@ class Family(SpecFamily):
+ pns_key_seen.add(name)
+ else:
+ pns_key_list.append(name)
+- # Propagate the request / reply
++ # Propagate the request / reply / recursive
+ for attr_set, struct in reversed(self.pure_nested_structs.items()):
+ for _, spec in self.attr_sets[attr_set].items():
+ if 'nested-attributes' in spec:
+- child = self.pure_nested_structs.get(spec['nested-attributes'])
++ child_name = spec['nested-attributes']
++ struct.child_nests.add(child_name)
++ child = self.pure_nested_structs.get(child_name)
+ if child:
++ if not child.recursive:
++ struct.child_nests.update(child.child_nests)
+ child.request |= struct.request
+ child.reply |= struct.reply
++ if attr_set in struct.child_nests:
++ struct.recursive = True
+
+ def _load_attr_use(self):
+ for _, struct in self.pure_nested_structs.items():
+--
+2.39.5
+
--- /dev/null
+From 0558ef104f9aecdb8be03b564438e99cad3b597e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Dec 2023 15:14:31 -0800
+Subject: tools: ynl-gen: store recursive nests by a pointer
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 461f25a2e4334767d3e306b08dbda054da1aaa30 ]
+
+To avoid infinite nesting store recursive structs by pointer.
+If recursive struct is placed in the op directly - the first
+instance can be stored by value. That makes the code much
+less of a pain for majority of practical uses.
+
+Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
+Link: https://lore.kernel.org/r/20231213231432.2944749-8-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: ce6cb8113c84 ("tools: ynl-gen: individually free previous values on double set")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/net/ynl/ynl-gen-c.py | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py
+index 502d03b8a758a..9e37d14d76bf9 100755
+--- a/tools/net/ynl/ynl-gen-c.py
++++ b/tools/net/ynl/ynl-gen-c.py
+@@ -83,6 +83,9 @@ class Type(SpecAttr):
+ def is_recursive(self):
+ return False
+
++ def is_recursive_for_op(self, ri):
++ return self.is_recursive() and not ri.op
++
+ def presence_type(self):
+ return 'bit'
+
+@@ -123,6 +126,8 @@ class Type(SpecAttr):
+ member = self._complex_member_type(ri)
+ if member:
+ ptr = '*' if self.is_multi_val() else ''
++ if self.is_recursive_for_op(ri):
++ ptr = '*'
+ ri.cw.p(f"{member} {ptr}{self.c_name};")
+ return
+ members = self.arg_member(ri)
+@@ -450,7 +455,11 @@ class TypeNest(Type):
+ return self.nested_struct_type
+
+ def free(self, ri, var, ref):
+- ri.cw.p(f'{self.nested_render_name}_free(&{var}->{ref}{self.c_name});')
++ at = '&'
++ if self.is_recursive_for_op(ri):
++ at = ''
++ ri.cw.p(f'if ({var}->{ref}{self.c_name})')
++ ri.cw.p(f'{self.nested_render_name}_free({at}{var}->{ref}{self.c_name});')
+
+ def _attr_typol(self):
+ return f'.type = YNL_PT_NEST, .nest = &{self.nested_render_name}_nest, '
+@@ -459,8 +468,9 @@ class TypeNest(Type):
+ return 'NLA_POLICY_NESTED(' + self.nested_render_name + '_nl_policy)'
+
+ def attr_put(self, ri, var):
++ at = '' if self.is_recursive_for_op(ri) else '&'
+ self._attr_put_line(ri, var, f"{self.nested_render_name}_put(nlh, " +
+- f"{self.enum_name}, &{var}->{self.c_name})")
++ f"{self.enum_name}, {at}{var}->{self.c_name})")
+
+ def _attr_get(self, ri, var):
+ get_lines = [f"if ({self.nested_render_name}_parse(&parg, attr))",
+@@ -473,6 +483,8 @@ class TypeNest(Type):
+ ref = (ref if ref else []) + [self.c_name]
+
+ for _, attr in ri.family.pure_nested_structs[self.nested_attrs].member_list():
++ if attr.is_recursive():
++ continue
+ attr.setter(ri, self.nested_attrs, direction, deref=deref, ref=ref)
+
+
+--
+2.39.5
+
--- /dev/null
+From 178fdfff69b384c6f6ee2119bdfc4f3b945c162c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Oct 2023 09:39:15 -0700
+Subject: tools: ynl-gen: track attribute use
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit ee0a4cfcbdcc6a7b2b35dba475e68187ebdafbf1 ]
+
+For range validation we'll need to know if any individual
+attribute is used on input (i.e. whether we will generate
+a policy for it). Track this information.
+
+Link: https://lore.kernel.org/r/20231018163917.2514503-2-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: ce6cb8113c84 ("tools: ynl-gen: individually free previous values on double set")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/net/ynl/ynl-gen-c.py | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py
+index 575b7e248e521..4c86fe0cd1179 100755
+--- a/tools/net/ynl/ynl-gen-c.py
++++ b/tools/net/ynl/ynl-gen-c.py
+@@ -42,6 +42,9 @@ class Type(SpecAttr):
+ self.type = attr['type']
+ self.checks = attr.get('checks', {})
+
++ self.request = False
++ self.reply = False
++
+ if 'len' in attr:
+ self.len = attr['len']
+ if 'nested-attributes' in attr:
+@@ -845,6 +848,7 @@ class Family(SpecFamily):
+
+ self._load_root_sets()
+ self._load_nested_sets()
++ self._load_attr_use()
+ self._load_hooks()
+
+ self.kernel_policy = self.yaml.get('kernel-policy', 'split')
+@@ -965,6 +969,22 @@ class Family(SpecFamily):
+ child.request |= struct.request
+ child.reply |= struct.reply
+
++ def _load_attr_use(self):
++ for _, struct in self.pure_nested_structs.items():
++ if struct.request:
++ for _, arg in struct.member_list():
++ arg.request = True
++ if struct.reply:
++ for _, arg in struct.member_list():
++ arg.reply = True
++
++ for root_set, rs_members in self.root_sets.items():
++ for attr, spec in self.attr_sets[root_set].items():
++ if attr in rs_members['request']:
++ spec.request = True
++ if attr in rs_members['reply']:
++ spec.reply = True
++
+ def _load_global_policy(self):
+ global_set = set()
+ attr_set_name = None
+--
+2.39.5
+
--- /dev/null
+From 34b0858ea2b25d6b4539a3e039be514dc71d68e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Mar 2025 16:01:10 +0530
+Subject: wifi: at76c50x: fix use after free access in at76_disconnect
+
+From: Abdun Nihaal <abdun.nihaal@gmail.com>
+
+[ Upstream commit 27c7e63b3cb1a20bb78ed4a36c561ea4579fd7da ]
+
+The memory pointed to by priv is freed at the end of at76_delete_device
+function (using ieee80211_free_hw). But the code then accesses the udev
+field of the freed object to put the USB device. This may also lead to a
+memory leak of the usb device. Fix this by using udev from interface.
+
+Fixes: 29e20aa6c6af ("at76c50x-usb: fix use after free on failure path in at76_probe()")
+Signed-off-by: Abdun Nihaal <abdun.nihaal@gmail.com>
+Link: https://patch.msgid.link/20250330103110.44080-1-abdun.nihaal@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/atmel/at76c50x-usb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/atmel/at76c50x-usb.c b/drivers/net/wireless/atmel/at76c50x-usb.c
+index 447b51cff8f96..c1a92c7f0f8e8 100644
+--- a/drivers/net/wireless/atmel/at76c50x-usb.c
++++ b/drivers/net/wireless/atmel/at76c50x-usb.c
+@@ -2554,7 +2554,7 @@ static void at76_disconnect(struct usb_interface *interface)
+
+ wiphy_info(priv->hw->wiphy, "disconnecting\n");
+ at76_delete_device(priv);
+- usb_put_dev(priv->udev);
++ usb_put_dev(interface_to_usbdev(interface));
+ dev_info(&interface->dev, "disconnected\n");
+ }
+
+--
+2.39.5
+
--- /dev/null
+From 873f1d1789f6bb31f7c7970d6c0eca4cc792cd5e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 17:28:21 +0100
+Subject: wifi: mac80211: Purge vif txq in ieee80211_do_stop()
+
+From: Remi Pommarel <repk@triplefau.lt>
+
+[ Upstream commit 378677eb8f44621ecc9ce659f7af61e5baa94d81 ]
+
+After ieee80211_do_stop() SKB from vif's txq could still be processed.
+Indeed another concurrent vif schedule_and_wake_txq call could cause
+those packets to be dequeued (see ieee80211_handle_wake_tx_queue())
+without checking the sdata current state.
+
+Because vif.drv_priv is now cleared in this function, this could lead to
+driver crash.
+
+For example in ath12k, ahvif is store in vif.drv_priv. Thus if
+ath12k_mac_op_tx() is called after ieee80211_do_stop(), ahvif->ah can be
+NULL, leading the ath12k_warn(ahvif->ah,...) call in this function to
+trigger the NULL deref below.
+
+ Unable to handle kernel paging request at virtual address dfffffc000000001
+ KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
+ batman_adv: bat0: Interface deactivated: brbh1337
+ Mem abort info:
+ ESR = 0x0000000096000004
+ EC = 0x25: DABT (current EL), IL = 32 bits
+ SET = 0, FnV = 0
+ EA = 0, S1PTW = 0
+ FSC = 0x04: level 0 translation fault
+ Data abort info:
+ ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
+ CM = 0, WnR = 0, TnD = 0, TagAccess = 0
+ GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+ [dfffffc000000001] address between user and kernel address ranges
+ Internal error: Oops: 0000000096000004 [#1] SMP
+ CPU: 1 UID: 0 PID: 978 Comm: lbd Not tainted 6.13.0-g633f875b8f1e #114
+ Hardware name: HW (DT)
+ pstate: 10000005 (nzcV daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+ pc : ath12k_mac_op_tx+0x6cc/0x29b8 [ath12k]
+ lr : ath12k_mac_op_tx+0x174/0x29b8 [ath12k]
+ sp : ffffffc086ace450
+ x29: ffffffc086ace450 x28: 0000000000000000 x27: 1ffffff810d59ca4
+ x26: ffffff801d05f7c0 x25: 0000000000000000 x24: 000000004000001e
+ x23: ffffff8009ce4926 x22: ffffff801f9c0800 x21: ffffff801d05f7f0
+ x20: ffffff8034a19f40 x19: 0000000000000000 x18: ffffff801f9c0958
+ x17: ffffff800bc0a504 x16: dfffffc000000000 x15: ffffffc086ace4f8
+ x14: ffffff801d05f83c x13: 0000000000000000 x12: ffffffb003a0bf03
+ x11: 0000000000000000 x10: ffffffb003a0bf02 x9 : ffffff8034a19f40
+ x8 : ffffff801d05f818 x7 : 1ffffff0069433dc x6 : ffffff8034a19ee0
+ x5 : ffffff801d05f7f0 x4 : 0000000000000000 x3 : 0000000000000001
+ x2 : 0000000000000000 x1 : dfffffc000000000 x0 : 0000000000000008
+ Call trace:
+ ath12k_mac_op_tx+0x6cc/0x29b8 [ath12k] (P)
+ ieee80211_handle_wake_tx_queue+0x16c/0x260
+ ieee80211_queue_skb+0xeec/0x1d20
+ ieee80211_tx+0x200/0x2c8
+ ieee80211_xmit+0x22c/0x338
+ __ieee80211_subif_start_xmit+0x7e8/0xc60
+ ieee80211_subif_start_xmit+0xc4/0xee0
+ __ieee80211_subif_start_xmit_8023.isra.0+0x854/0x17a0
+ ieee80211_subif_start_xmit_8023+0x124/0x488
+ dev_hard_start_xmit+0x160/0x5a8
+ __dev_queue_xmit+0x6f8/0x3120
+ br_dev_queue_push_xmit+0x120/0x4a8
+ __br_forward+0xe4/0x2b0
+ deliver_clone+0x5c/0xd0
+ br_flood+0x398/0x580
+ br_dev_xmit+0x454/0x9f8
+ dev_hard_start_xmit+0x160/0x5a8
+ __dev_queue_xmit+0x6f8/0x3120
+ ip6_finish_output2+0xc28/0x1b60
+ __ip6_finish_output+0x38c/0x638
+ ip6_output+0x1b4/0x338
+ ip6_local_out+0x7c/0xa8
+ ip6_send_skb+0x7c/0x1b0
+ ip6_push_pending_frames+0x94/0xd0
+ rawv6_sendmsg+0x1a98/0x2898
+ inet_sendmsg+0x94/0xe0
+ __sys_sendto+0x1e4/0x308
+ __arm64_sys_sendto+0xc4/0x140
+ do_el0_svc+0x110/0x280
+ el0_svc+0x20/0x60
+ el0t_64_sync_handler+0x104/0x138
+ el0t_64_sync+0x154/0x158
+
+To avoid that, empty vif's txq at ieee80211_do_stop() so no packet could
+be dequeued after ieee80211_do_stop() (new packets cannot be queued
+because SDATA_STATE_RUNNING is cleared at this point).
+
+Fixes: ba8c3d6f16a1 ("mac80211: add an intermediate software queue implementation")
+Signed-off-by: Remi Pommarel <repk@triplefau.lt>
+Link: https://patch.msgid.link/ff7849e268562456274213c0476e09481a48f489.1742833382.git.repk@triplefau.lt
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/iface.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index fae701248f058..eaa4e5c6a5c3a 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -682,6 +682,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+ ieee80211_txq_remove_vlan(local, sdata);
+
++ if (sdata->vif.txq)
++ ieee80211_txq_purge(sdata->local, to_txq_info(sdata->vif.txq));
++
+ sdata->bss = NULL;
+
+ if (local->open_count == 0)
+--
+2.39.5
+
--- /dev/null
+From 64aa303c9a88dac400c072cde6a9ccd8045ba287 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 17:28:20 +0100
+Subject: wifi: mac80211: Update skb's control block key in
+ ieee80211_tx_dequeue()
+
+From: Remi Pommarel <repk@triplefau.lt>
+
+[ Upstream commit a104042e2bf6528199adb6ca901efe7b60c2c27f ]
+
+The ieee80211 skb control block key (set when skb was queued) could have
+been removed before ieee80211_tx_dequeue() call. ieee80211_tx_dequeue()
+already called ieee80211_tx_h_select_key() to get the current key, but
+the latter do not update the key in skb control block in case it is
+NULL. Because some drivers actually use this key in their TX callbacks
+(e.g. ath1{1,2}k_mac_op_tx()) this could lead to the use after free
+below:
+
+ BUG: KASAN: slab-use-after-free in ath11k_mac_op_tx+0x590/0x61c
+ Read of size 4 at addr ffffff803083c248 by task kworker/u16:4/1440
+
+ CPU: 3 UID: 0 PID: 1440 Comm: kworker/u16:4 Not tainted 6.13.0-ge128f627f404 #2
+ Hardware name: HW (DT)
+ Workqueue: bat_events batadv_send_outstanding_bcast_packet
+ Call trace:
+ show_stack+0x14/0x1c (C)
+ dump_stack_lvl+0x58/0x74
+ print_report+0x164/0x4c0
+ kasan_report+0xac/0xe8
+ __asan_report_load4_noabort+0x1c/0x24
+ ath11k_mac_op_tx+0x590/0x61c
+ ieee80211_handle_wake_tx_queue+0x12c/0x1c8
+ ieee80211_queue_skb+0xdcc/0x1b4c
+ ieee80211_tx+0x1ec/0x2bc
+ ieee80211_xmit+0x224/0x324
+ __ieee80211_subif_start_xmit+0x85c/0xcf8
+ ieee80211_subif_start_xmit+0xc0/0xec4
+ dev_hard_start_xmit+0xf4/0x28c
+ __dev_queue_xmit+0x6ac/0x318c
+ batadv_send_skb_packet+0x38c/0x4b0
+ batadv_send_outstanding_bcast_packet+0x110/0x328
+ process_one_work+0x578/0xc10
+ worker_thread+0x4bc/0xc7c
+ kthread+0x2f8/0x380
+ ret_from_fork+0x10/0x20
+
+ Allocated by task 1906:
+ kasan_save_stack+0x28/0x4c
+ kasan_save_track+0x1c/0x40
+ kasan_save_alloc_info+0x3c/0x4c
+ __kasan_kmalloc+0xac/0xb0
+ __kmalloc_noprof+0x1b4/0x380
+ ieee80211_key_alloc+0x3c/0xb64
+ ieee80211_add_key+0x1b4/0x71c
+ nl80211_new_key+0x2b4/0x5d8
+ genl_family_rcv_msg_doit+0x198/0x240
+ <...>
+
+ Freed by task 1494:
+ kasan_save_stack+0x28/0x4c
+ kasan_save_track+0x1c/0x40
+ kasan_save_free_info+0x48/0x94
+ __kasan_slab_free+0x48/0x60
+ kfree+0xc8/0x31c
+ kfree_sensitive+0x70/0x80
+ ieee80211_key_free_common+0x10c/0x174
+ ieee80211_free_keys+0x188/0x46c
+ ieee80211_stop_mesh+0x70/0x2cc
+ ieee80211_leave_mesh+0x1c/0x60
+ cfg80211_leave_mesh+0xe0/0x280
+ cfg80211_leave+0x1e0/0x244
+ <...>
+
+Reset SKB control block key before calling ieee80211_tx_h_select_key()
+to avoid that.
+
+Fixes: bb42f2d13ffc ("mac80211: Move reorder-sensitive TX handlers to after TXQ dequeue")
+Signed-off-by: Remi Pommarel <repk@triplefau.lt>
+Link: https://patch.msgid.link/06aa507b853ca385ceded81c18b0a6dd0f081bc8.1742833382.git.repk@triplefau.lt
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/tx.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index 45a093d3f1fa7..8c46498152d76 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -3877,6 +3877,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
+ * The key can be removed while the packet was queued, so need to call
+ * this here to get the current key.
+ */
++ info->control.hw_key = NULL;
+ r = ieee80211_tx_h_select_key(&tx);
+ if (r != TX_CONTINUE) {
+ ieee80211_free_txskb(&local->hw, skb);
+--
+2.39.5
+
--- /dev/null
+From 475b727921b088da1aaa3e59e5bb3ad54942d0a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Mar 2025 16:15:32 +0530
+Subject: wifi: wl1251: fix memory leak in wl1251_tx_work
+
+From: Abdun Nihaal <abdun.nihaal@gmail.com>
+
+[ Upstream commit a0f0dc96de03ffeefc2a177b7f8acde565cb77f4 ]
+
+The skb dequeued from tx_queue is lost when wl1251_ps_elp_wakeup fails
+with a -ETIMEDOUT error. Fix that by queueing the skb back to tx_queue.
+
+Fixes: c5483b719363 ("wl12xx: check if elp wakeup failed")
+Signed-off-by: Abdun Nihaal <abdun.nihaal@gmail.com>
+Reviewed-by: Michael Nemanov <michael.nemanov@ti.com>
+Link: https://patch.msgid.link/20250330104532.44935-1-abdun.nihaal@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ti/wl1251/tx.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ti/wl1251/tx.c b/drivers/net/wireless/ti/wl1251/tx.c
+index e9dc3c72bb110..06dc74cc6cb52 100644
+--- a/drivers/net/wireless/ti/wl1251/tx.c
++++ b/drivers/net/wireless/ti/wl1251/tx.c
+@@ -342,8 +342,10 @@ void wl1251_tx_work(struct work_struct *work)
+ while ((skb = skb_dequeue(&wl->tx_queue))) {
+ if (!woken_up) {
+ ret = wl1251_ps_elp_wakeup(wl);
+- if (ret < 0)
++ if (ret < 0) {
++ skb_queue_head(&wl->tx_queue, skb);
+ goto out;
++ }
+ woken_up = true;
+ }
+
+--
+2.39.5
+