--- /dev/null
+From 9e000f1b7f31684cc5927e034360b87ac7919593 Mon Sep 17 00:00:00 2001
+From: Wentao Liang <vulab@iscas.ac.cn>
+Date: Wed, 14 May 2025 17:24:44 +0800
+Subject: ALSA: es1968: Add error handling for snd_pcm_hw_constraint_pow2()
+
+From: Wentao Liang <vulab@iscas.ac.cn>
+
+commit 9e000f1b7f31684cc5927e034360b87ac7919593 upstream.
+
+The function snd_es1968_capture_open() calls the function
+snd_pcm_hw_constraint_pow2(), but does not check its return
+value. A proper implementation can be found in snd_cx25821_pcm_open().
+
+Add error handling for snd_pcm_hw_constraint_pow2() and propagate its
+error code.
+
+Fixes: b942cf815b57 ("[ALSA] es1968 - Fix stuttering capture")
+Cc: stable@vger.kernel.org # v2.6.22
+Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
+Link: https://patch.msgid.link/20250514092444.331-1-vulab@iscas.ac.cn
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/es1968.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/sound/pci/es1968.c
++++ b/sound/pci/es1968.c
+@@ -1561,7 +1561,7 @@ static int snd_es1968_capture_open(struc
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct es1968 *chip = snd_pcm_substream_chip(substream);
+ struct esschan *es;
+- int apu1, apu2;
++ int err, apu1, apu2;
+
+ apu1 = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_CAPTURE);
+ if (apu1 < 0)
+@@ -1605,7 +1605,9 @@ static int snd_es1968_capture_open(struc
+ runtime->hw = snd_es1968_capture;
+ runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max =
+ calc_available_memory_size(chip) - 1024; /* keep MIXBUF size */
+- snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
++ err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
++ if (err < 0)
++ return err;
+
+ spin_lock_irq(&chip->substream_lock);
+ list_add(&es->list, &chip->substream_list);
--- /dev/null
+From 2b24eb060c2bb9ef79e1d3bcf633ba1bc95215d6 Mon Sep 17 00:00:00 2001
+From: Christian Heusel <christian@heusel.eu>
+Date: Mon, 12 May 2025 22:23:37 +0200
+Subject: ALSA: usb-audio: Add sample rate quirk for Audioengine D1
+
+From: Christian Heusel <christian@heusel.eu>
+
+commit 2b24eb060c2bb9ef79e1d3bcf633ba1bc95215d6 upstream.
+
+A user reported on the Arch Linux Forums that their device is emitting
+the following message in the kernel journal, which is fixed by adding
+the quirk as submitted in this patch:
+
+ > kernel: usb 1-2: current rate 8436480 is different from the runtime rate 48000
+
+There also is an entry for this product line added long time ago.
+Their specific device has the following ID:
+
+ $ lsusb | grep Audio
+ Bus 001 Device 002: ID 1101:0003 EasyPass Industrial Co., Ltd Audioengine D1
+
+Link: https://bbs.archlinux.org/viewtopic.php?id=305494
+Fixes: 93f9d1a4ac593 ("ALSA: usb-audio: Apply sample rate quirk for Audioengine D1")
+Cc: stable@vger.kernel.org
+Signed-off-by: Christian Heusel <christian@heusel.eu>
+Link: https://patch.msgid.link/20250512-audioengine-quirk-addition-v1-1-4c370af6eff7@heusel.eu
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/usb/quirks.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -2248,6 +2248,8 @@ static const struct usb_audio_quirk_flag
+ QUIRK_FLAG_FIXED_RATE),
+ DEVICE_FLG(0x0fd9, 0x0008, /* Hauppauge HVR-950Q */
+ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
++ DEVICE_FLG(0x1101, 0x0003, /* Audioengine D1 */
++ QUIRK_FLAG_GET_SAMPLE_RATE),
+ DEVICE_FLG(0x1224, 0x2a25, /* Jieli Technology USB PHY 2.0 */
+ QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_MIC_RES_16),
+ DEVICE_FLG(0x1395, 0x740a, /* Sennheiser DECT */
--- /dev/null
+From 7b9938a14460e8ec7649ca2e80ac0aae9815bf02 Mon Sep 17 00:00:00 2001
+From: Nicolas Chauvet <kwizart@gmail.com>
+Date: Thu, 15 May 2025 12:21:32 +0200
+Subject: ALSA: usb-audio: Add sample rate quirk for Microdia JP001 USB Camera
+
+From: Nicolas Chauvet <kwizart@gmail.com>
+
+commit 7b9938a14460e8ec7649ca2e80ac0aae9815bf02 upstream.
+
+Microdia JP001 does not support reading the sample rate which leads to
+many lines of "cannot get freq at ep 0x84".
+This patch adds the USB ID to quirks.c and avoids those error messages.
+
+usb 7-4: New USB device found, idVendor=0c45, idProduct=636b, bcdDevice= 1.00
+usb 7-4: New USB device strings: Mfr=2, Product=1, SerialNumber=3
+usb 7-4: Product: JP001
+usb 7-4: Manufacturer: JP001
+usb 7-4: SerialNumber: JP001
+usb 7-4: 3:1: cannot get freq at ep 0x84
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Nicolas Chauvet <kwizart@gmail.com>
+Link: https://patch.msgid.link/20250515102132.73062-1-kwizart@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/usb/quirks.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -2240,6 +2240,8 @@ static const struct usb_audio_quirk_flag
+ QUIRK_FLAG_CTL_MSG_DELAY_1M),
+ DEVICE_FLG(0x0c45, 0x6340, /* Sonix HD USB Camera */
+ QUIRK_FLAG_GET_SAMPLE_RATE),
++ DEVICE_FLG(0x0c45, 0x636b, /* Microdia JP001 USB Camera */
++ QUIRK_FLAG_GET_SAMPLE_RATE),
+ DEVICE_FLG(0x0d8c, 0x0014, /* USB Audio Device */
+ QUIRK_FLAG_CTL_MSG_DELAY_1M),
+ DEVICE_FLG(0x0ecb, 0x205c, /* JBL Quantum610 Wireless */
--- /dev/null
+From 0f67578587bb9e5a8eecfcdf6b8a501b5bd90526 Mon Sep 17 00:00:00 2001
+From: Christian Hewitt <christianshewitt@gmail.com>
+Date: Sat, 3 May 2025 08:44:43 +0000
+Subject: arm64: dts: amlogic: dreambox: fix missing clkc_audio node
+
+From: Christian Hewitt <christianshewitt@gmail.com>
+
+commit 0f67578587bb9e5a8eecfcdf6b8a501b5bd90526 upstream.
+
+Add the clkc_audio node to fix audio support on Dreambox One/Two.
+
+Fixes: 83a6f4c62cb1 ("arm64: dts: meson: add initial support for Dreambox One/Two")
+CC: stable@vger.kernel.org
+Suggested-by: Emanuel Strobel <emanuel.strobel@yahoo.com>
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Link: https://lore.kernel.org/r/20250503084443.3704866-1-christianshewitt@gmail.com
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/boot/dts/amlogic/meson-g12b-dreambox.dtsi | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/arm64/boot/dts/amlogic/meson-g12b-dreambox.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-g12b-dreambox.dtsi
+@@ -116,6 +116,10 @@
+ status = "okay";
+ };
+
++&clkc_audio {
++ status = "okay";
++};
++
+ &frddr_a {
+ status = "okay";
+ };
--- /dev/null
+From e0bd7ecf6b2dc71215af699dffbf14bf0bc3d978 Mon Sep 17 00:00:00 2001
+From: Dragan Simic <dsimic@manjaro.org>
+Date: Mon, 24 Mar 2025 12:00:43 +0100
+Subject: arm64: dts: rockchip: Remove overdrive-mode OPPs from RK3588J SoC dtsi
+
+From: Dragan Simic <dsimic@manjaro.org>
+
+commit e0bd7ecf6b2dc71215af699dffbf14bf0bc3d978 upstream.
+
+The differences in the vendor-approved CPU and GPU OPPs for the standard
+Rockchip RK3588 variant [1] and the industrial Rockchip RK3588J variant [2]
+come from the latter, presumably, supporting an extended temperature range
+that's usually associated with industrial applications, despite the two SoC
+variant datasheets specifying the same upper limit for the allowed ambient
+temperature for both variants. However, the lower temperature limit is
+specified much lower for the RK3588J variant. [1][2]
+
+To be on the safe side and to ensure maximum longevity of the RK3588J SoCs,
+only the CPU and GPU OPPs that are declared by the vendor to be always safe
+for this SoC variant may be provided. As explained by the vendor [3] and
+according to the RK3588J datasheet, [2] higher-frequency/higher-voltage
+CPU and GPU OPPs can be used as well, but at the risk of reducing the SoC
+lifetime expectancy. Presumably, using the higher OPPs may be safe only
+when not enjoying the assumed extended temperature range that the RK3588J,
+as an SoC variant targeted specifically at higher-temperature, industrial
+applications, is made (or binned) for.
+
+Anyone able to keep their RK3588J-based board outside the above-presumed
+extended temperature range at all times, and willing to take the associated
+risk of possibly reducing the SoC lifetime expectancy, is free to apply
+a DT overlay that adds the higher CPU and GPU OPPs.
+
+With all this and the downstream RK3588(J) DT definitions [4][5] in mind,
+let's delete the RK3588J CPU and GPU OPPs that are not considered belonging
+to the normal operation mode for this SoC variant. To quote the RK3588J
+datasheet [2], "normal mode means the chipset works under safety voltage
+and frequency; for the industrial environment, highly recommend to keep in
+normal mode, the lifetime is reasonably guaranteed", while "overdrive mode
+brings higher frequency, and the voltage will increase accordingly; under
+the overdrive mode for a long time, the chipset may shorten the lifetime,
+especially in high-temperature condition".
+
+To sum the RK3588J datasheet [2] and the vendor-provided DTs up, [4][5]
+the maximum allowed CPU core, GPU and NPU frequencies are as follows:
+
+ IP core | Normal mode | Overdrive mode
+ ------------+-------------+----------------
+ Cortex-A55 | 1,296 MHz | 1,704 MHz
+ Cortex-A76 | 1,608 MHz | 2,016 MHz
+ GPU | 700 MHz | 850 MHz
+ NPU | 800 MHz | 950 MHz
+
+Unfortunately, when it comes to the actual voltages for the RK3588J CPU and
+GPU OPPs, there's a discrepancy between the RK3588J datasheet [2] and the
+downstream kernel code. [4][5] The RK3588J datasheet states that "the max.
+working voltage of CPU/GPU/NPU is 0.75 V under the normal mode", while the
+downstream kernel code actually allows voltage ranges that go up to 0.95 V,
+which is still within the voltage range allowed by the datasheet. However,
+the RK3588J datasheet also tells us to "strictly refer to the software
+configuration of SDK and the hardware reference design", so let's embrace
+the voltage ranges provided by the downstream kernel code, which also
+prevents the undesirable theoretical outcome of ending up with no usable
+OPPs on a particular board, as a result of the board's voltage regulator(s)
+being unable to deliver the exact voltages, for whatever reason.
+
+The above-described voltage ranges for the RK3588J CPU OPPs remain taken
+from the downstream kernel code [4][5] by picking the highest, worst-bin
+values, which ensure that all RK3588J bins will work reliably. Yes, with
+some power inevitably wasted as unnecessarily generated heat, but the
+reliability is paramount, together with the longevity. This deficiency
+may be revisited separately at some point in the future.
+
+The provided RK3588J CPU OPPs follow the slightly debatable "provide only
+the highest-frequency OPP from the same-voltage group" approach that's been
+established earlier, [6] as a result of the "same-voltage, lower-frequency"
+OPPs being considered inefficient from the IPA governor's standpoint, which
+may also be revisited separately at some point in the future.
+
+[1] https://wiki.friendlyelec.com/wiki/images/e/ee/Rockchip_RK3588_Datasheet_V1.6-20231016.pdf
+[2] https://wmsc.lcsc.com/wmsc/upload/file/pdf/v2/lcsc/2403201054_Rockchip-RK3588J_C22364189.pdf
+[3] https://lore.kernel.org/linux-rockchip/e55125ed-64fb-455e-b1e4-cebe2cf006e4@cherry.de/T/#u
+[4] https://raw.githubusercontent.com/rockchip-linux/kernel/604cec4004abe5a96c734f2fab7b74809d2d742f/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+[5] https://raw.githubusercontent.com/rockchip-linux/kernel/604cec4004abe5a96c734f2fab7b74809d2d742f/arch/arm64/boot/dts/rockchip/rk3588j.dtsi
+[6] https://lore.kernel.org/all/20240229-rk-dts-additions-v3-5-6afe8473a631@gmail.com/
+
+Fixes: 667885a68658 ("arm64: dts: rockchip: Add OPP data for CPU cores on RK3588j")
+Fixes: a7b2070505a2 ("arm64: dts: rockchip: Split GPU OPPs of RK3588 and RK3588j")
+Cc: stable@vger.kernel.org
+Cc: Heiko Stuebner <heiko@sntech.de>
+Cc: Alexey Charkov <alchark@gmail.com>
+Helped-by: Quentin Schulz <quentin.schulz@cherry.de>
+Reviewed-by: Quentin Schulz <quentin.schulz@cherry.de>
+Signed-off-by: Dragan Simic <dsimic@manjaro.org>
+Link: https://lore.kernel.org/r/eeec0d30d79b019d111b3f0aa2456e69896b2caa.1742813866.git.dsimic@manjaro.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3588j.dtsi | 53 +++++++++---------------------
+ 1 file changed, 17 insertions(+), 36 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588j.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588j.dtsi
+@@ -11,20 +11,15 @@
+ compatible = "operating-points-v2";
+ opp-shared;
+
+- opp-1416000000 {
+- opp-hz = /bits/ 64 <1416000000>;
++ opp-1200000000 {
++ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <750000 750000 950000>;
+ clock-latency-ns = <40000>;
+ opp-suspend;
+ };
+- opp-1608000000 {
+- opp-hz = /bits/ 64 <1608000000>;
+- opp-microvolt = <887500 887500 950000>;
+- clock-latency-ns = <40000>;
+- };
+- opp-1704000000 {
+- opp-hz = /bits/ 64 <1704000000>;
+- opp-microvolt = <937500 937500 950000>;
++ opp-1296000000 {
++ opp-hz = /bits/ 64 <1296000000>;
++ opp-microvolt = <775000 775000 950000>;
+ clock-latency-ns = <40000>;
+ };
+ };
+@@ -33,9 +28,14 @@
+ compatible = "operating-points-v2";
+ opp-shared;
+
++ opp-1200000000{
++ opp-hz = /bits/ 64 <1200000000>;
++ opp-microvolt = <750000 750000 950000>;
++ clock-latency-ns = <40000>;
++ };
+ opp-1416000000 {
+ opp-hz = /bits/ 64 <1416000000>;
+- opp-microvolt = <750000 750000 950000>;
++ opp-microvolt = <762500 762500 950000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-1608000000 {
+@@ -43,25 +43,20 @@
+ opp-microvolt = <787500 787500 950000>;
+ clock-latency-ns = <40000>;
+ };
+- opp-1800000000 {
+- opp-hz = /bits/ 64 <1800000000>;
+- opp-microvolt = <875000 875000 950000>;
+- clock-latency-ns = <40000>;
+- };
+- opp-2016000000 {
+- opp-hz = /bits/ 64 <2016000000>;
+- opp-microvolt = <950000 950000 950000>;
+- clock-latency-ns = <40000>;
+- };
+ };
+
+ cluster2_opp_table: opp-table-cluster2 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
++ opp-1200000000{
++ opp-hz = /bits/ 64 <1200000000>;
++ opp-microvolt = <750000 750000 950000>;
++ clock-latency-ns = <40000>;
++ };
+ opp-1416000000 {
+ opp-hz = /bits/ 64 <1416000000>;
+- opp-microvolt = <750000 750000 950000>;
++ opp-microvolt = <762500 762500 950000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-1608000000 {
+@@ -69,16 +64,6 @@
+ opp-microvolt = <787500 787500 950000>;
+ clock-latency-ns = <40000>;
+ };
+- opp-1800000000 {
+- opp-hz = /bits/ 64 <1800000000>;
+- opp-microvolt = <875000 875000 950000>;
+- clock-latency-ns = <40000>;
+- };
+- opp-2016000000 {
+- opp-hz = /bits/ 64 <2016000000>;
+- opp-microvolt = <950000 950000 950000>;
+- clock-latency-ns = <40000>;
+- };
+ };
+
+ gpu_opp_table: opp-table {
+@@ -104,10 +89,6 @@
+ opp-hz = /bits/ 64 <700000000>;
+ opp-microvolt = <750000 750000 850000>;
+ };
+- opp-850000000 {
+- opp-hz = /bits/ 64 <800000000>;
+- opp-microvolt = <787500 787500 850000>;
+- };
+ };
+ };
+
--- /dev/null
+From 72c7d62583ebce7baeb61acce6057c361f73be4a Mon Sep 17 00:00:00 2001
+From: Hyejeong Choi <hjeong.choi@samsung.com>
+Date: Mon, 12 May 2025 21:06:38 -0500
+Subject: dma-buf: insert memory barrier before updating num_fences
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Hyejeong Choi <hjeong.choi@samsung.com>
+
+commit 72c7d62583ebce7baeb61acce6057c361f73be4a upstream.
+
+smp_store_mb() inserts memory barrier after storing operation.
+It is different with what the comment is originally aiming so Null
+pointer dereference can be happened if memory update is reordered.
+
+Signed-off-by: Hyejeong Choi <hjeong.choi@samsung.com>
+Fixes: a590d0fdbaa5 ("dma-buf: Update reservation shared_count after adding the new fence")
+CC: stable@vger.kernel.org
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Link: https://lore.kernel.org/r/20250513020638.GA2329653@au1-maretx-p37.eng.sarc.samsung.com
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma-buf/dma-resv.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/dma-buf/dma-resv.c
++++ b/drivers/dma-buf/dma-resv.c
+@@ -320,8 +320,9 @@ void dma_resv_add_fence(struct dma_resv
+ count++;
+
+ dma_resv_list_set(fobj, i, fence, usage);
+- /* pointer update must be visible before we extend the num_fences */
+- smp_store_mb(fobj->num_fences, count);
++ /* fence update must be visible before we extend the num_fences */
++ smp_wmb();
++ fobj->num_fences = count;
+ }
+ EXPORT_SYMBOL(dma_resv_add_fence);
+
--- /dev/null
+From 61259fb96e023f7299c442c48b13e72c441fc0f2 Mon Sep 17 00:00:00 2001
+From: Shuai Xue <xueshuai@linux.alibaba.com>
+Date: Fri, 4 Apr 2025 20:02:12 +0800
+Subject: dmaengine: idxd: Add missing cleanup for early error out in idxd_setup_internals
+
+From: Shuai Xue <xueshuai@linux.alibaba.com>
+
+commit 61259fb96e023f7299c442c48b13e72c441fc0f2 upstream.
+
+The idxd_setup_internals() is missing some cleanup when things fail in
+the middle.
+
+Add the appropriate cleanup routines:
+
+- cleanup groups
+- cleanup enginces
+- cleanup wqs
+
+to make sure it exits gracefully.
+
+Fixes: defe49f96012 ("dmaengine: idxd: fix group conf_dev lifetime")
+Cc: stable@vger.kernel.org
+Suggested-by: Fenghua Yu <fenghuay@nvidia.com>
+Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
+Reviewed-by: Fenghua Yu <fenghuay@nvidia.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/20250404120217.48772-5-xueshuai@linux.alibaba.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/idxd/init.c | 58 ++++++++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 51 insertions(+), 7 deletions(-)
+
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -153,6 +153,25 @@ static void idxd_cleanup_interrupts(stru
+ pci_free_irq_vectors(pdev);
+ }
+
++static void idxd_clean_wqs(struct idxd_device *idxd)
++{
++ struct idxd_wq *wq;
++ struct device *conf_dev;
++ int i;
++
++ for (i = 0; i < idxd->max_wqs; i++) {
++ wq = idxd->wqs[i];
++ if (idxd->hw.wq_cap.op_config)
++ bitmap_free(wq->opcap_bmap);
++ kfree(wq->wqcfg);
++ conf_dev = wq_confdev(wq);
++ put_device(conf_dev);
++ kfree(wq);
++ }
++ bitmap_free(idxd->wq_enable_map);
++ kfree(idxd->wqs);
++}
++
+ static int idxd_setup_wqs(struct idxd_device *idxd)
+ {
+ struct device *dev = &idxd->pdev->dev;
+@@ -243,6 +262,21 @@ err_bitmap:
+ return rc;
+ }
+
++static void idxd_clean_engines(struct idxd_device *idxd)
++{
++ struct idxd_engine *engine;
++ struct device *conf_dev;
++ int i;
++
++ for (i = 0; i < idxd->max_engines; i++) {
++ engine = idxd->engines[i];
++ conf_dev = engine_confdev(engine);
++ put_device(conf_dev);
++ kfree(engine);
++ }
++ kfree(idxd->engines);
++}
++
+ static int idxd_setup_engines(struct idxd_device *idxd)
+ {
+ struct idxd_engine *engine;
+@@ -294,6 +328,19 @@ static int idxd_setup_engines(struct idx
+ return rc;
+ }
+
++static void idxd_clean_groups(struct idxd_device *idxd)
++{
++ struct idxd_group *group;
++ int i;
++
++ for (i = 0; i < idxd->max_groups; i++) {
++ group = idxd->groups[i];
++ put_device(group_confdev(group));
++ kfree(group);
++ }
++ kfree(idxd->groups);
++}
++
+ static int idxd_setup_groups(struct idxd_device *idxd)
+ {
+ struct device *dev = &idxd->pdev->dev;
+@@ -408,7 +455,7 @@ static int idxd_init_evl(struct idxd_dev
+ static int idxd_setup_internals(struct idxd_device *idxd)
+ {
+ struct device *dev = &idxd->pdev->dev;
+- int rc, i;
++ int rc;
+
+ init_waitqueue_head(&idxd->cmd_waitq);
+
+@@ -439,14 +486,11 @@ static int idxd_setup_internals(struct i
+ err_evl:
+ destroy_workqueue(idxd->wq);
+ err_wkq_create:
+- for (i = 0; i < idxd->max_groups; i++)
+- put_device(group_confdev(idxd->groups[i]));
++ idxd_clean_groups(idxd);
+ err_group:
+- for (i = 0; i < idxd->max_engines; i++)
+- put_device(engine_confdev(idxd->engines[i]));
++ idxd_clean_engines(idxd);
+ err_engine:
+- for (i = 0; i < idxd->max_wqs; i++)
+- put_device(wq_confdev(idxd->wqs[i]));
++ idxd_clean_wqs(idxd);
+ err_wqs:
+ return rc;
+ }
--- /dev/null
+From 61d651572b6c4fe50c7b39a390760f3a910c7ccf Mon Sep 17 00:00:00 2001
+From: Shuai Xue <xueshuai@linux.alibaba.com>
+Date: Fri, 4 Apr 2025 20:02:13 +0800
+Subject: dmaengine: idxd: Add missing cleanups in cleanup internals
+
+From: Shuai Xue <xueshuai@linux.alibaba.com>
+
+commit 61d651572b6c4fe50c7b39a390760f3a910c7ccf upstream.
+
+The idxd_cleanup_internals() function only decreases the reference count
+of groups, engines, and wqs but is missing the step to release memory
+resources.
+
+To fix this, use the cleanup helper to properly release the memory
+resources.
+
+Fixes: ddf742d4f3f1 ("dmaengine: idxd: Add missing cleanup for early error out in probe call")
+Cc: stable@vger.kernel.org
+Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
+Reviewed-by: Fenghua Yu <fenghuay@nvidia.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/20250404120217.48772-6-xueshuai@linux.alibaba.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/idxd/init.c | 11 +++--------
+ 1 file changed, 3 insertions(+), 8 deletions(-)
+
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -405,14 +405,9 @@ static int idxd_setup_groups(struct idxd
+
+ static void idxd_cleanup_internals(struct idxd_device *idxd)
+ {
+- int i;
+-
+- for (i = 0; i < idxd->max_groups; i++)
+- put_device(group_confdev(idxd->groups[i]));
+- for (i = 0; i < idxd->max_engines; i++)
+- put_device(engine_confdev(idxd->engines[i]));
+- for (i = 0; i < idxd->max_wqs; i++)
+- put_device(wq_confdev(idxd->wqs[i]));
++ idxd_clean_groups(idxd);
++ idxd_clean_engines(idxd);
++ idxd_clean_wqs(idxd);
+ destroy_workqueue(idxd->wq);
+ }
+
--- /dev/null
+From d5449ff1b04dfe9ed8e455769aa01e4c2ccf6805 Mon Sep 17 00:00:00 2001
+From: Shuai Xue <xueshuai@linux.alibaba.com>
+Date: Fri, 4 Apr 2025 20:02:16 +0800
+Subject: dmaengine: idxd: Add missing idxd cleanup to fix memory leak in remove call
+
+From: Shuai Xue <xueshuai@linux.alibaba.com>
+
+commit d5449ff1b04dfe9ed8e455769aa01e4c2ccf6805 upstream.
+
+The remove call stack is missing idxd cleanup to free bitmap, ida and
+the idxd_device. Call idxd_free() helper routines to make sure we exit
+gracefully.
+
+Fixes: bfe1d56091c1 ("dmaengine: idxd: Init and probe for Intel data accelerators")
+Cc: stable@vger.kernel.org
+Suggested-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
+Reviewed-by: Fenghua Yu <fenghuay@nvidia.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/20250404120217.48772-9-xueshuai@linux.alibaba.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/idxd/init.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -915,6 +915,7 @@ static void idxd_remove(struct pci_dev *
+ destroy_workqueue(idxd->wq);
+ perfmon_pmu_remove(idxd);
+ put_device(idxd_confdev(idxd));
++ idxd_free(idxd);
+ }
+
+ static struct pci_driver idxd_pci_driver = {
--- /dev/null
+From 46a5cca76c76c86063000a12936f8e7875295838 Mon Sep 17 00:00:00 2001
+From: Shuai Xue <xueshuai@linux.alibaba.com>
+Date: Fri, 4 Apr 2025 20:02:14 +0800
+Subject: dmaengine: idxd: fix memory leak in error handling path of idxd_alloc
+
+From: Shuai Xue <xueshuai@linux.alibaba.com>
+
+commit 46a5cca76c76c86063000a12936f8e7875295838 upstream.
+
+Memory allocated for idxd is not freed if an error occurs during
+idxd_alloc(). To fix it, free the allocated memory in the reverse order
+of allocation before exiting the function in case of an error.
+
+Fixes: a8563a33a5e2 ("dmanegine: idxd: reformat opcap output to match bitmap_parse() input")
+Cc: stable@vger.kernel.org
+Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Reviewed-by: Fenghua Yu <fenghuay@nvidia.com>
+Link: https://lore.kernel.org/r/20250404120217.48772-7-xueshuai@linux.alibaba.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/idxd/init.c | 24 +++++++++++++++---------
+ 1 file changed, 15 insertions(+), 9 deletions(-)
+
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -602,28 +602,34 @@ static struct idxd_device *idxd_alloc(st
+ idxd_dev_set_type(&idxd->idxd_dev, idxd->data->type);
+ idxd->id = ida_alloc(&idxd_ida, GFP_KERNEL);
+ if (idxd->id < 0)
+- return NULL;
++ goto err_ida;
+
+ idxd->opcap_bmap = bitmap_zalloc_node(IDXD_MAX_OPCAP_BITS, GFP_KERNEL, dev_to_node(dev));
+- if (!idxd->opcap_bmap) {
+- ida_free(&idxd_ida, idxd->id);
+- return NULL;
+- }
++ if (!idxd->opcap_bmap)
++ goto err_opcap;
+
+ device_initialize(conf_dev);
+ conf_dev->parent = dev;
+ conf_dev->bus = &dsa_bus_type;
+ conf_dev->type = idxd->data->dev_type;
+ rc = dev_set_name(conf_dev, "%s%d", idxd->data->name_prefix, idxd->id);
+- if (rc < 0) {
+- put_device(conf_dev);
+- return NULL;
+- }
++ if (rc < 0)
++ goto err_name;
+
+ spin_lock_init(&idxd->dev_lock);
+ spin_lock_init(&idxd->cmd_lock);
+
+ return idxd;
++
++err_name:
++ put_device(conf_dev);
++ bitmap_free(idxd->opcap_bmap);
++err_opcap:
++ ida_free(&idxd_ida, idxd->id);
++err_ida:
++ kfree(idxd);
++
++ return NULL;
+ }
+
+ static int idxd_enable_system_pasid(struct idxd_device *idxd)
--- /dev/null
+From 90022b3a6981ec234902be5dbf0f983a12c759fc Mon Sep 17 00:00:00 2001
+From: Shuai Xue <xueshuai@linux.alibaba.com>
+Date: Fri, 4 Apr 2025 20:02:15 +0800
+Subject: dmaengine: idxd: fix memory leak in error handling path of idxd_pci_probe
+
+From: Shuai Xue <xueshuai@linux.alibaba.com>
+
+commit 90022b3a6981ec234902be5dbf0f983a12c759fc upstream.
+
+Memory allocated for idxd is not freed if an error occurs during
+idxd_pci_probe(). To fix it, free the allocated memory in the reverse
+order of allocation before exiting the function in case of an error.
+
+Fixes: bfe1d56091c1 ("dmaengine: idxd: Init and probe for Intel data accelerators")
+Cc: stable@vger.kernel.org
+Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Reviewed-by: Fenghua Yu <fenghuay@nvidia.com>
+Link: https://lore.kernel.org/r/20250404120217.48772-8-xueshuai@linux.alibaba.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/idxd/init.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -585,6 +585,17 @@ static void idxd_read_caps(struct idxd_d
+ idxd->hw.iaa_cap.bits = ioread64(idxd->reg_base + IDXD_IAACAP_OFFSET);
+ }
+
++static void idxd_free(struct idxd_device *idxd)
++{
++ if (!idxd)
++ return;
++
++ put_device(idxd_confdev(idxd));
++ bitmap_free(idxd->opcap_bmap);
++ ida_free(&idxd_ida, idxd->id);
++ kfree(idxd);
++}
++
+ static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_data *data)
+ {
+ struct device *dev = &pdev->dev;
+@@ -857,7 +868,7 @@ static int idxd_pci_probe(struct pci_dev
+ err:
+ pci_iounmap(pdev, idxd->reg_base);
+ err_iomap:
+- put_device(idxd_confdev(idxd));
++ idxd_free(idxd);
+ err_idxd_alloc:
+ pci_disable_device(pdev);
+ return rc;
--- /dev/null
+From 817bced19d1dbdd0b473580d026dc0983e30e17b Mon Sep 17 00:00:00 2001
+From: Shuai Xue <xueshuai@linux.alibaba.com>
+Date: Fri, 4 Apr 2025 20:02:10 +0800
+Subject: dmaengine: idxd: fix memory leak in error handling path of idxd_setup_engines
+
+From: Shuai Xue <xueshuai@linux.alibaba.com>
+
+commit 817bced19d1dbdd0b473580d026dc0983e30e17b upstream.
+
+Memory allocated for engines is not freed if an error occurs during
+idxd_setup_engines(). To fix it, free the allocated memory in the
+reverse order of allocation before exiting the function in case of an
+error.
+
+Fixes: 75b911309060 ("dmaengine: idxd: fix engine conf_dev lifetime")
+Cc: stable@vger.kernel.org
+Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Reviewed-by: Fenghua Yu <fenghuay@nvidia.com>
+Link: https://lore.kernel.org/r/20250404120217.48772-3-xueshuai@linux.alibaba.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/idxd/init.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -273,6 +273,7 @@ static int idxd_setup_engines(struct idx
+ rc = dev_set_name(conf_dev, "engine%d.%d", idxd->id, engine->id);
+ if (rc < 0) {
+ put_device(conf_dev);
++ kfree(engine);
+ goto err;
+ }
+
+@@ -286,7 +287,10 @@ static int idxd_setup_engines(struct idx
+ engine = idxd->engines[i];
+ conf_dev = engine_confdev(engine);
+ put_device(conf_dev);
++ kfree(engine);
+ }
++ kfree(idxd->engines);
++
+ return rc;
+ }
+
--- /dev/null
+From aa6f4f945b10eac57aed46154ae7d6fada7fccc7 Mon Sep 17 00:00:00 2001
+From: Shuai Xue <xueshuai@linux.alibaba.com>
+Date: Fri, 4 Apr 2025 20:02:11 +0800
+Subject: dmaengine: idxd: fix memory leak in error handling path of idxd_setup_groups
+
+From: Shuai Xue <xueshuai@linux.alibaba.com>
+
+commit aa6f4f945b10eac57aed46154ae7d6fada7fccc7 upstream.
+
+Memory allocated for groups is not freed if an error occurs during
+idxd_setup_groups(). To fix it, free the allocated memory in the reverse
+order of allocation before exiting the function in case of an error.
+
+Fixes: defe49f96012 ("dmaengine: idxd: fix group conf_dev lifetime")
+Cc: stable@vger.kernel.org
+Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Reviewed-by: Fenghua Yu <fenghuay@nvidia.com>
+Link: https://lore.kernel.org/r/20250404120217.48772-4-xueshuai@linux.alibaba.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/idxd/init.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -324,6 +324,7 @@ static int idxd_setup_groups(struct idxd
+ rc = dev_set_name(conf_dev, "group%d.%d", idxd->id, group->id);
+ if (rc < 0) {
+ put_device(conf_dev);
++ kfree(group);
+ goto err;
+ }
+
+@@ -348,7 +349,10 @@ static int idxd_setup_groups(struct idxd
+ while (--i >= 0) {
+ group = idxd->groups[i];
+ put_device(group_confdev(group));
++ kfree(group);
+ }
++ kfree(idxd->groups);
++
+ return rc;
+ }
+
--- /dev/null
+From 3fd2f4bc010cdfbc07dd21018dc65bd9370eb7a4 Mon Sep 17 00:00:00 2001
+From: Shuai Xue <xueshuai@linux.alibaba.com>
+Date: Fri, 4 Apr 2025 20:02:09 +0800
+Subject: dmaengine: idxd: fix memory leak in error handling path of idxd_setup_wqs
+
+From: Shuai Xue <xueshuai@linux.alibaba.com>
+
+commit 3fd2f4bc010cdfbc07dd21018dc65bd9370eb7a4 upstream.
+
+Memory allocated for wqs is not freed if an error occurs during
+idxd_setup_wqs(). To fix it, free the allocated memory in the reverse
+order of allocation before exiting the function in case of an error.
+
+Fixes: 7c5dd23e57c1 ("dmaengine: idxd: fix wq conf_dev 'struct device' lifetime")
+Fixes: 700af3a0a26c ("dmaengine: idxd: add 'struct idxd_dev' as wrapper for conf_dev")
+Fixes: de5819b99489 ("dmaengine: idxd: track enabled workqueues in bitmap")
+Fixes: b0325aefd398 ("dmaengine: idxd: add WQ operation cap restriction support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Reviewed-by: Fenghua Yu <fenghuay@nvidia.com>
+Link: https://lore.kernel.org/r/20250404120217.48772-2-xueshuai@linux.alibaba.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/idxd/init.c | 30 +++++++++++++++++++++---------
+ 1 file changed, 21 insertions(+), 9 deletions(-)
+
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -167,8 +167,8 @@ static int idxd_setup_wqs(struct idxd_de
+
+ idxd->wq_enable_map = bitmap_zalloc_node(idxd->max_wqs, GFP_KERNEL, dev_to_node(dev));
+ if (!idxd->wq_enable_map) {
+- kfree(idxd->wqs);
+- return -ENOMEM;
++ rc = -ENOMEM;
++ goto err_bitmap;
+ }
+
+ for (i = 0; i < idxd->max_wqs; i++) {
+@@ -187,10 +187,8 @@ static int idxd_setup_wqs(struct idxd_de
+ conf_dev->bus = &dsa_bus_type;
+ conf_dev->type = &idxd_wq_device_type;
+ rc = dev_set_name(conf_dev, "wq%d.%d", idxd->id, wq->id);
+- if (rc < 0) {
+- put_device(conf_dev);
++ if (rc < 0)
+ goto err;
+- }
+
+ mutex_init(&wq->wq_lock);
+ init_waitqueue_head(&wq->err_queue);
+@@ -201,7 +199,6 @@ static int idxd_setup_wqs(struct idxd_de
+ wq->enqcmds_retries = IDXD_ENQCMDS_RETRIES;
+ wq->wqcfg = kzalloc_node(idxd->wqcfg_size, GFP_KERNEL, dev_to_node(dev));
+ if (!wq->wqcfg) {
+- put_device(conf_dev);
+ rc = -ENOMEM;
+ goto err;
+ }
+@@ -209,9 +206,8 @@ static int idxd_setup_wqs(struct idxd_de
+ if (idxd->hw.wq_cap.op_config) {
+ wq->opcap_bmap = bitmap_zalloc(IDXD_MAX_OPCAP_BITS, GFP_KERNEL);
+ if (!wq->opcap_bmap) {
+- put_device(conf_dev);
+ rc = -ENOMEM;
+- goto err;
++ goto err_opcap_bmap;
+ }
+ bitmap_copy(wq->opcap_bmap, idxd->opcap_bmap, IDXD_MAX_OPCAP_BITS);
+ }
+@@ -222,12 +218,28 @@ static int idxd_setup_wqs(struct idxd_de
+
+ return 0;
+
+- err:
++err_opcap_bmap:
++ kfree(wq->wqcfg);
++
++err:
++ put_device(conf_dev);
++ kfree(wq);
++
+ while (--i >= 0) {
+ wq = idxd->wqs[i];
++ if (idxd->hw.wq_cap.op_config)
++ bitmap_free(wq->opcap_bmap);
++ kfree(wq->wqcfg);
+ conf_dev = wq_confdev(wq);
+ put_device(conf_dev);
++ kfree(wq);
++
+ }
++ bitmap_free(idxd->wq_enable_map);
++
++err_bitmap:
++ kfree(idxd->wqs);
++
+ return rc;
+ }
+
--- /dev/null
+From a409e919ca321cc0e28f8abf96fde299f0072a81 Mon Sep 17 00:00:00 2001
+From: Shuai Xue <xueshuai@linux.alibaba.com>
+Date: Fri, 4 Apr 2025 20:02:17 +0800
+Subject: dmaengine: idxd: Refactor remove call with idxd_cleanup() helper
+
+From: Shuai Xue <xueshuai@linux.alibaba.com>
+
+commit a409e919ca321cc0e28f8abf96fde299f0072a81 upstream.
+
+The idxd_cleanup() helper cleans up perfmon, interrupts, internals and
+so on. Refactor remove call with the idxd_cleanup() helper to avoid code
+duplication. Note, this also fixes the missing put_device() for idxd
+groups, enginces and wqs.
+
+Fixes: bfe1d56091c1 ("dmaengine: idxd: Init and probe for Intel data accelerators")
+Cc: stable@vger.kernel.org
+Suggested-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
+Reviewed-by: Fenghua Yu <fenghuay@nvidia.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/20250404120217.48772-10-xueshuai@linux.alibaba.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/idxd/init.c | 14 ++------------
+ 1 file changed, 2 insertions(+), 12 deletions(-)
+
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -905,7 +905,6 @@ static void idxd_shutdown(struct pci_dev
+ static void idxd_remove(struct pci_dev *pdev)
+ {
+ struct idxd_device *idxd = pci_get_drvdata(pdev);
+- struct idxd_irq_entry *irq_entry;
+
+ idxd_unregister_devices(idxd);
+ /*
+@@ -918,21 +917,12 @@ static void idxd_remove(struct pci_dev *
+ get_device(idxd_confdev(idxd));
+ device_unregister(idxd_confdev(idxd));
+ idxd_shutdown(pdev);
+- if (device_pasid_enabled(idxd))
+- idxd_disable_system_pasid(idxd);
+ idxd_device_remove_debugfs(idxd);
+-
+- irq_entry = idxd_get_ie(idxd, 0);
+- free_irq(irq_entry->vector, irq_entry);
+- pci_free_irq_vectors(pdev);
++ idxd_cleanup(idxd);
+ pci_iounmap(pdev, idxd->reg_base);
+- if (device_user_pasid_enabled(idxd))
+- idxd_disable_sva(pdev);
+- pci_disable_device(pdev);
+- destroy_workqueue(idxd->wq);
+- perfmon_pmu_remove(idxd);
+ put_device(idxd_confdev(idxd));
+ idxd_free(idxd);
++ pci_disable_device(pdev);
+ }
+
+ static struct pci_driver idxd_pci_driver = {
--- /dev/null
+From fca280992af8c2fbd511bc43f65abb4a17363f2f Mon Sep 17 00:00:00 2001
+From: Ronald Wahl <ronald.wahl@legrand.com>
+Date: Mon, 14 Apr 2025 19:31:13 +0200
+Subject: dmaengine: ti: k3-udma: Add missing locking
+
+From: Ronald Wahl <ronald.wahl@legrand.com>
+
+commit fca280992af8c2fbd511bc43f65abb4a17363f2f upstream.
+
+Recent kernels complain about a missing lock in k3-udma.c when the lock
+validator is enabled:
+
+[ 4.128073] WARNING: CPU: 0 PID: 746 at drivers/dma/ti/../virt-dma.h:169 udma_start.isra.0+0x34/0x238
+[ 4.137352] CPU: 0 UID: 0 PID: 746 Comm: kworker/0:3 Not tainted 6.12.9-arm64 #28
+[ 4.144867] Hardware name: pp-v12 (DT)
+[ 4.148648] Workqueue: events udma_check_tx_completion
+[ 4.153841] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+[ 4.160834] pc : udma_start.isra.0+0x34/0x238
+[ 4.165227] lr : udma_start.isra.0+0x30/0x238
+[ 4.169618] sp : ffffffc083cabcf0
+[ 4.172963] x29: ffffffc083cabcf0 x28: 0000000000000000 x27: ffffff800001b005
+[ 4.180167] x26: ffffffc0812f0000 x25: 0000000000000000 x24: 0000000000000000
+[ 4.187370] x23: 0000000000000001 x22: 00000000e21eabe9 x21: ffffff8000fa0670
+[ 4.194571] x20: ffffff8001b6bf00 x19: ffffff8000fa0430 x18: ffffffc083b95030
+[ 4.201773] x17: 0000000000000000 x16: 00000000f0000000 x15: 0000000000000048
+[ 4.208976] x14: 0000000000000048 x13: 0000000000000000 x12: 0000000000000001
+[ 4.216179] x11: ffffffc08151a240 x10: 0000000000003ea1 x9 : ffffffc08046ab68
+[ 4.223381] x8 : ffffffc083cabac0 x7 : ffffffc081df3718 x6 : 0000000000029fc8
+[ 4.230583] x5 : ffffffc0817ee6d8 x4 : 0000000000000bc0 x3 : 0000000000000000
+[ 4.237784] x2 : 0000000000000000 x1 : 00000000001fffff x0 : 0000000000000000
+[ 4.244986] Call trace:
+[ 4.247463] udma_start.isra.0+0x34/0x238
+[ 4.251509] udma_check_tx_completion+0xd0/0xdc
+[ 4.256076] process_one_work+0x244/0x3fc
+[ 4.260129] process_scheduled_works+0x6c/0x74
+[ 4.264610] worker_thread+0x150/0x1dc
+[ 4.268398] kthread+0xd8/0xe8
+[ 4.271492] ret_from_fork+0x10/0x20
+[ 4.275107] irq event stamp: 220
+[ 4.278363] hardirqs last enabled at (219): [<ffffffc080a27c7c>] _raw_spin_unlock_irq+0x38/0x50
+[ 4.287183] hardirqs last disabled at (220): [<ffffffc080a1c154>] el1_dbg+0x24/0x50
+[ 4.294879] softirqs last enabled at (182): [<ffffffc080037e68>] handle_softirqs+0x1c0/0x3cc
+[ 4.303437] softirqs last disabled at (177): [<ffffffc080010170>] __do_softirq+0x1c/0x28
+[ 4.311559] ---[ end trace 0000000000000000 ]---
+
+This commit adds the missing locking.
+
+Fixes: 25dcb5dd7b7c ("dmaengine: ti: New driver for K3 UDMA")
+Cc: Peter Ujfalusi <peter.ujfalusi@gmail.com>
+Cc: Vignesh Raghavendra <vigneshr@ti.com>
+Cc: Vinod Koul <vkoul@kernel.org>
+Cc: dmaengine@vger.kernel.org
+Cc: stable@vger.kernel.org
+Signed-off-by: Ronald Wahl <ronald.wahl@legrand.com>
+Acked-by: Peter Ujfalusi <peter.ujfalusi@gmail.com>
+Link: https://lore.kernel.org/r/20250414173113.80677-1-rwahl@gmx.de
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/ti/k3-udma.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/dma/ti/k3-udma.c
++++ b/drivers/dma/ti/k3-udma.c
+@@ -1091,8 +1091,11 @@ static void udma_check_tx_completion(str
+ u32 residue_diff;
+ ktime_t time_diff;
+ unsigned long delay;
++ unsigned long flags;
+
+ while (1) {
++ spin_lock_irqsave(&uc->vc.lock, flags);
++
+ if (uc->desc) {
+ /* Get previous residue and time stamp */
+ residue_diff = uc->tx_drain.residue;
+@@ -1127,6 +1130,8 @@ static void udma_check_tx_completion(str
+ break;
+ }
+
++ spin_unlock_irqrestore(&uc->vc.lock, flags);
++
+ usleep_range(ktime_to_us(delay),
+ ktime_to_us(delay) + 10);
+ continue;
+@@ -1143,6 +1148,8 @@ static void udma_check_tx_completion(str
+
+ break;
+ }
++
++ spin_unlock_irqrestore(&uc->vc.lock, flags);
+ }
+
+ static irqreturn_t udma_ring_irq_handler(int irq, void *data)
--- /dev/null
+From 8ca9590c39b69b55a8de63d2b21b0d44f523b43a Mon Sep 17 00:00:00 2001
+From: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
+Date: Thu, 17 Apr 2025 13:25:21 +0530
+Subject: dmaengine: ti: k3-udma: Use cap_mask directly from dma_device structure instead of a local copy
+
+From: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
+
+commit 8ca9590c39b69b55a8de63d2b21b0d44f523b43a upstream.
+
+Currently, a local dma_cap_mask_t variable is used to store device
+cap_mask within udma_of_xlate(). However, the DMA_PRIVATE flag in
+the device cap_mask can get cleared when the last channel is released.
+This can happen right after storing the cap_mask locally in
+udma_of_xlate(), and subsequent dma_request_channel() can fail due to
+mismatch in the cap_mask. Fix this by removing the local dma_cap_mask_t
+variable and directly using the one from the dma_device structure.
+
+Fixes: 25dcb5dd7b7c ("dmaengine: ti: New driver for K3 UDMA")
+Cc: stable@vger.kernel.org
+Signed-off-by: Vaishnav Achath <vaishnav.a@ti.com>
+Acked-by: Peter Ujfalusi <peter.ujfalusi@gmail.com>
+Reviewed-by: Udit Kumar <u-kumar1@ti.com>
+Signed-off-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
+Link: https://lore.kernel.org/r/20250417075521.623651-1-y-abhilashchandra@ti.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/ti/k3-udma.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/dma/ti/k3-udma.c
++++ b/drivers/dma/ti/k3-udma.c
+@@ -4253,7 +4253,6 @@ static struct dma_chan *udma_of_xlate(st
+ struct of_dma *ofdma)
+ {
+ struct udma_dev *ud = ofdma->of_dma_data;
+- dma_cap_mask_t mask = ud->ddev.cap_mask;
+ struct udma_filter_param filter_param;
+ struct dma_chan *chan;
+
+@@ -4285,7 +4284,7 @@ static struct dma_chan *udma_of_xlate(st
+ }
+ }
+
+- chan = __dma_request_channel(&mask, udma_dma_filter_fn, &filter_param,
++ chan = __dma_request_channel(&ud->ddev.cap_mask, udma_dma_filter_fn, &filter_param,
+ ofdma->of_node);
+ if (!chan) {
+ dev_err(ud->dev, "get channel fail in %s.\n", __func__);
--- /dev/null
+From 380b75d3078626aadd0817de61f3143f5db6e393 Mon Sep 17 00:00:00 2001
+From: Michael Kelley <mhklinux@outlook.com>
+Date: Mon, 12 May 2025 17:06:00 -0700
+Subject: Drivers: hv: Allow vmbus_sendpacket_mpb_desc() to create multiple ranges
+
+From: Michael Kelley <mhklinux@outlook.com>
+
+commit 380b75d3078626aadd0817de61f3143f5db6e393 upstream.
+
+vmbus_sendpacket_mpb_desc() is currently used only by the storvsc driver
+and is hardcoded to create a single GPA range. To allow it to also be
+used by the netvsc driver to create multiple GPA ranges, no longer
+hardcode as having a single GPA range. Allow the calling driver to
+specify the rangecount in the supplied descriptor.
+
+Update the storvsc driver to reflect this new approach.
+
+Cc: <stable@vger.kernel.org> # 6.1.x
+Signed-off-by: Michael Kelley <mhklinux@outlook.com>
+Link: https://patch.msgid.link/20250513000604.1396-2-mhklinux@outlook.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hv/channel.c | 6 +++---
+ drivers/scsi/storvsc_drv.c | 1 +
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -1136,9 +1136,10 @@ int vmbus_sendpacket_pagebuffer(struct v
+ EXPORT_SYMBOL_GPL(vmbus_sendpacket_pagebuffer);
+
+ /*
+- * vmbus_sendpacket_multipagebuffer - Send a multi-page buffer packet
++ * vmbus_sendpacket_mpb_desc - Send one or more multi-page buffer packets
+ * using a GPADL Direct packet type.
+- * The buffer includes the vmbus descriptor.
++ * The desc argument must include space for the VMBus descriptor. The
++ * rangecount field must already be set.
+ */
+ int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel,
+ struct vmbus_packet_mpb_array *desc,
+@@ -1160,7 +1161,6 @@ int vmbus_sendpacket_mpb_desc(struct vmb
+ desc->length8 = (u16)(packetlen_aligned >> 3);
+ desc->transactionid = VMBUS_RQST_ERROR; /* will be updated in hv_ringbuffer_write() */
+ desc->reserved = 0;
+- desc->rangecount = 1;
+
+ bufferlist[0].iov_base = desc;
+ bufferlist[0].iov_len = desc_size;
+--- a/drivers/scsi/storvsc_drv.c
++++ b/drivers/scsi/storvsc_drv.c
+@@ -1819,6 +1819,7 @@ static int storvsc_queuecommand(struct S
+ return SCSI_MLQUEUE_DEVICE_BUSY;
+ }
+
++ payload->rangecount = 1;
+ payload->range.len = length;
+ payload->range.offset = offset_in_hvpg;
+
--- /dev/null
+From 45a442fe369e6c4e0b4aa9f63b31c3f2f9e2090e Mon Sep 17 00:00:00 2001
+From: Michael Kelley <mhklinux@outlook.com>
+Date: Mon, 12 May 2025 17:06:04 -0700
+Subject: Drivers: hv: vmbus: Remove vmbus_sendpacket_pagebuffer()
+
+From: Michael Kelley <mhklinux@outlook.com>
+
+commit 45a442fe369e6c4e0b4aa9f63b31c3f2f9e2090e upstream.
+
+With the netvsc driver changed to use vmbus_sendpacket_mpb_desc()
+instead of vmbus_sendpacket_pagebuffer(), the latter has no remaining
+callers. Remove it.
+
+Cc: <stable@vger.kernel.org> # 6.1.x
+Signed-off-by: Michael Kelley <mhklinux@outlook.com>
+Link: https://patch.msgid.link/20250513000604.1396-6-mhklinux@outlook.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hv/channel.c | 59 -------------------------------------------------
+ include/linux/hyperv.h | 7 -----
+ 2 files changed, 66 deletions(-)
+
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -1077,65 +1077,6 @@ int vmbus_sendpacket(struct vmbus_channe
+ EXPORT_SYMBOL(vmbus_sendpacket);
+
+ /*
+- * vmbus_sendpacket_pagebuffer - Send a range of single-page buffer
+- * packets using a GPADL Direct packet type. This interface allows you
+- * to control notifying the host. This will be useful for sending
+- * batched data. Also the sender can control the send flags
+- * explicitly.
+- */
+-int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
+- struct hv_page_buffer pagebuffers[],
+- u32 pagecount, void *buffer, u32 bufferlen,
+- u64 requestid)
+-{
+- int i;
+- struct vmbus_channel_packet_page_buffer desc;
+- u32 descsize;
+- u32 packetlen;
+- u32 packetlen_aligned;
+- struct kvec bufferlist[3];
+- u64 aligned_data = 0;
+-
+- if (pagecount > MAX_PAGE_BUFFER_COUNT)
+- return -EINVAL;
+-
+- /*
+- * Adjust the size down since vmbus_channel_packet_page_buffer is the
+- * largest size we support
+- */
+- descsize = sizeof(struct vmbus_channel_packet_page_buffer) -
+- ((MAX_PAGE_BUFFER_COUNT - pagecount) *
+- sizeof(struct hv_page_buffer));
+- packetlen = descsize + bufferlen;
+- packetlen_aligned = ALIGN(packetlen, sizeof(u64));
+-
+- /* Setup the descriptor */
+- desc.type = VM_PKT_DATA_USING_GPA_DIRECT;
+- desc.flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
+- desc.dataoffset8 = descsize >> 3; /* in 8-bytes granularity */
+- desc.length8 = (u16)(packetlen_aligned >> 3);
+- desc.transactionid = VMBUS_RQST_ERROR; /* will be updated in hv_ringbuffer_write() */
+- desc.reserved = 0;
+- desc.rangecount = pagecount;
+-
+- for (i = 0; i < pagecount; i++) {
+- desc.range[i].len = pagebuffers[i].len;
+- desc.range[i].offset = pagebuffers[i].offset;
+- desc.range[i].pfn = pagebuffers[i].pfn;
+- }
+-
+- bufferlist[0].iov_base = &desc;
+- bufferlist[0].iov_len = descsize;
+- bufferlist[1].iov_base = buffer;
+- bufferlist[1].iov_len = bufferlen;
+- bufferlist[2].iov_base = &aligned_data;
+- bufferlist[2].iov_len = (packetlen_aligned - packetlen);
+-
+- return hv_ringbuffer_write(channel, bufferlist, 3, requestid, NULL);
+-}
+-EXPORT_SYMBOL_GPL(vmbus_sendpacket_pagebuffer);
+-
+-/*
+ * vmbus_sendpacket_mpb_desc - Send one or more multi-page buffer packets
+ * using a GPADL Direct packet type.
+ * The desc argument must include space for the VMBus descriptor. The
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -1232,13 +1232,6 @@ extern int vmbus_sendpacket(struct vmbus
+ enum vmbus_packet_type type,
+ u32 flags);
+
+-extern int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
+- struct hv_page_buffer pagebuffers[],
+- u32 pagecount,
+- void *buffer,
+- u32 bufferlen,
+- u64 requestid);
+-
+ extern int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel,
+ struct vmbus_packet_mpb_array *mpb,
+ u32 desc_size,
--- /dev/null
+From 11aff32439df6ca5b3b891b43032faf88f4a6a29 Mon Sep 17 00:00:00 2001
+From: pengdonglin <pengdonglin@xiaomi.com>
+Date: Mon, 12 May 2025 17:42:46 +0800
+Subject: ftrace: Fix preemption accounting for stacktrace filter command
+
+From: pengdonglin <pengdonglin@xiaomi.com>
+
+commit 11aff32439df6ca5b3b891b43032faf88f4a6a29 upstream.
+
+The preemption count of the stacktrace filter command to trace ksys_read
+is consistently incorrect:
+
+$ echo ksys_read:stacktrace > set_ftrace_filter
+
+ <...>-453 [004] ...1. 38.308956: <stack trace>
+=> ksys_read
+=> do_syscall_64
+=> entry_SYSCALL_64_after_hwframe
+
+The root cause is that the trace framework disables preemption when
+invoking the filter command callback in function_trace_probe_call:
+
+ preempt_disable_notrace();
+ probe_ops->func(ip, parent_ip, probe_opsbe->tr, probe_ops, probe->data);
+ preempt_enable_notrace();
+
+Use tracing_gen_ctx_dec() to account for the preempt_disable_notrace(),
+which will output the correct preemption count:
+
+$ echo ksys_read:stacktrace > set_ftrace_filter
+
+ <...>-410 [006] ..... 31.420396: <stack trace>
+=> ksys_read
+=> do_syscall_64
+=> entry_SYSCALL_64_after_hwframe
+
+Cc: stable@vger.kernel.org
+Fixes: 36590c50b2d07 ("tracing: Merge irqflags + preempt counter.")
+Link: https://lore.kernel.org/20250512094246.1167956-2-dolinux.peng@gmail.com
+Signed-off-by: pengdonglin <dolinux.peng@gmail.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/trace_functions.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+--- a/kernel/trace/trace_functions.c
++++ b/kernel/trace/trace_functions.c
+@@ -574,11 +574,7 @@ ftrace_traceoff(unsigned long ip, unsign
+
+ static __always_inline void trace_stack(struct trace_array *tr)
+ {
+- unsigned int trace_ctx;
+-
+- trace_ctx = tracing_gen_ctx();
+-
+- __trace_stack(tr, trace_ctx, FTRACE_STACK_SKIP);
++ __trace_stack(tr, tracing_gen_ctx_dec(), FTRACE_STACK_SKIP);
+ }
+
+ static void
--- /dev/null
+From e333332657f615ac2b55aa35565c4a882018bbe9 Mon Sep 17 00:00:00 2001
+From: pengdonglin <pengdonglin@xiaomi.com>
+Date: Mon, 12 May 2025 17:42:45 +0800
+Subject: ftrace: Fix preemption accounting for stacktrace trigger command
+
+From: pengdonglin <pengdonglin@xiaomi.com>
+
+commit e333332657f615ac2b55aa35565c4a882018bbe9 upstream.
+
+When using the stacktrace trigger command to trace syscalls, the
+preemption count was consistently reported as 1 when the system call
+event itself had 0 (".").
+
+For example:
+
+root@ubuntu22-vm:/sys/kernel/tracing/events/syscalls/sys_enter_read
+$ echo stacktrace > trigger
+$ echo 1 > enable
+
+ sshd-416 [002] ..... 232.864910: sys_read(fd: a, buf: 556b1f3221d0, count: 8000)
+ sshd-416 [002] ...1. 232.864913: <stack trace>
+ => ftrace_syscall_enter
+ => syscall_trace_enter
+ => do_syscall_64
+ => entry_SYSCALL_64_after_hwframe
+
+The root cause is that the trace framework disables preemption in __DO_TRACE before
+invoking the trigger callback.
+
+Use the tracing_gen_ctx_dec() that will accommodate for the increase of
+the preemption count in __DO_TRACE when calling the callback. The result
+is the accurate reporting of:
+
+ sshd-410 [004] ..... 210.117660: sys_read(fd: 4, buf: 559b725ba130, count: 40000)
+ sshd-410 [004] ..... 210.117662: <stack trace>
+ => ftrace_syscall_enter
+ => syscall_trace_enter
+ => do_syscall_64
+ => entry_SYSCALL_64_after_hwframe
+
+Cc: stable@vger.kernel.org
+Fixes: ce33c845b030c ("tracing: Dump stacktrace trigger to the corresponding instance")
+Link: https://lore.kernel.org/20250512094246.1167956-1-dolinux.peng@gmail.com
+Signed-off-by: pengdonglin <dolinux.peng@gmail.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/trace_events_trigger.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/trace/trace_events_trigger.c
++++ b/kernel/trace/trace_events_trigger.c
+@@ -1581,7 +1581,7 @@ stacktrace_trigger(struct event_trigger_
+ struct trace_event_file *file = data->private_data;
+
+ if (file)
+- __trace_stack(file->tr, tracing_gen_ctx(), STACK_SKIP);
++ __trace_stack(file->tr, tracing_gen_ctx_dec(), STACK_SKIP);
+ else
+ trace_dump_stack(STACK_SKIP);
+ }
--- /dev/null
+From 41a6328b2c55276f89ea3812069fd7521e348bbf Mon Sep 17 00:00:00 2001
+From: Michael Kelley <mhklinux@outlook.com>
+Date: Mon, 12 May 2025 17:06:02 -0700
+Subject: hv_netvsc: Preserve contiguous PFN grouping in the page buffer array
+
+From: Michael Kelley <mhklinux@outlook.com>
+
+commit 41a6328b2c55276f89ea3812069fd7521e348bbf upstream.
+
+Starting with commit dca5161f9bd0 ("hv_netvsc: Check status in
+SEND_RNDIS_PKT completion message") in the 6.3 kernel, the Linux
+driver for Hyper-V synthetic networking (netvsc) occasionally reports
+"nvsp_rndis_pkt_complete error status: 2".[1] This error indicates
+that Hyper-V has rejected a network packet transmit request from the
+guest, and the outgoing network packet is dropped. Higher level
+network protocols presumably recover and resend the packet so there is
+no functional error, but performance is slightly impacted. Commit
+dca5161f9bd0 is not the cause of the error -- it only added reporting
+of an error that was already happening without any notice. The error
+has presumably been present since the netvsc driver was originally
+introduced into Linux.
+
+The root cause of the problem is that the netvsc driver in Linux may
+send an incorrectly formatted VMBus message to Hyper-V when
+transmitting the network packet. The incorrect formatting occurs when
+the rndis header of the VMBus message crosses a page boundary due to
+how the Linux skb head memory is aligned. In such a case, two PFNs are
+required to describe the location of the rndis header, even though
+they are contiguous in guest physical address (GPA) space. Hyper-V
+requires that two rndis header PFNs be in a single "GPA range" data
+struture, but current netvsc code puts each PFN in its own GPA range,
+which Hyper-V rejects as an error.
+
+The incorrect formatting occurs only for larger packets that netvsc
+must transmit via a VMBus "GPA Direct" message. There's no problem
+when netvsc transmits a smaller packet by copying it into a pre-
+allocated send buffer slot because the pre-allocated slots don't have
+page crossing issues.
+
+After commit 14ad6ed30a10 ("net: allow small head cache usage with
+large MAX_SKB_FRAGS values") in the 6.14-rc4 kernel, the error occurs
+much more frequently in VMs with 16 or more vCPUs. It may occur every
+few seconds, or even more frequently, in an ssh session that outputs a
+lot of text. Commit 14ad6ed30a10 subtly changes how skb head memory is
+allocated, making it much more likely that the rndis header will cross
+a page boundary when the vCPU count is 16 or more. The changes in
+commit 14ad6ed30a10 are perfectly valid -- they just had the side
+effect of making the netvsc bug more prominent.
+
+Current code in init_page_array() creates a separate page buffer array
+entry for each PFN required to identify the data to be transmitted.
+Contiguous PFNs get separate entries in the page buffer array, and any
+information about contiguity is lost.
+
+Fix the core issue by having init_page_array() construct the page
+buffer array to represent contiguous ranges rather than individual
+pages. When these ranges are subsequently passed to
+netvsc_build_mpb_array(), it can build GPA ranges that contain
+multiple PFNs, as required to avoid the error "nvsp_rndis_pkt_complete
+error status: 2". If instead the network packet is sent by copying
+into a pre-allocated send buffer slot, the copy proceeds using the
+contiguous ranges rather than individual pages, but the result of the
+copying is the same. Also fix rndis_filter_send_request() to construct
+a contiguous range, since it has its own page buffer array.
+
+This change has a side benefit in CoCo VMs in that netvsc_dma_map()
+calls dma_map_single() on each contiguous range instead of on each
+page. This results in fewer calls to dma_map_single() but on larger
+chunks of memory, which should reduce contention on the swiotlb.
+
+Since the page buffer array now contains one entry for each contiguous
+range instead of for each individual page, the number of entries in
+the array can be reduced, saving 208 bytes of stack space in
+netvsc_xmit() when MAX_SKG_FRAGS has the default value of 17.
+
+[1] https://bugzilla.kernel.org/show_bug.cgi?id=217503
+
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217503
+Cc: <stable@vger.kernel.org> # 6.1.x
+Signed-off-by: Michael Kelley <mhklinux@outlook.com>
+Link: https://patch.msgid.link/20250513000604.1396-4-mhklinux@outlook.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/hyperv/hyperv_net.h | 12 +++++++
+ drivers/net/hyperv/netvsc_drv.c | 65 +++++++++-----------------------------
+ drivers/net/hyperv/rndis_filter.c | 24 ++------------
+ 3 files changed, 33 insertions(+), 68 deletions(-)
+
+--- a/drivers/net/hyperv/hyperv_net.h
++++ b/drivers/net/hyperv/hyperv_net.h
+@@ -893,6 +893,18 @@ struct nvsp_message {
+ sizeof(struct nvsp_message))
+ #define NETVSC_MIN_IN_MSG_SIZE sizeof(struct vmpacket_descriptor)
+
++/* Maximum # of contiguous data ranges that can make up a trasmitted packet.
++ * Typically it's the max SKB fragments plus 2 for the rndis packet and the
++ * linear portion of the SKB. But if MAX_SKB_FRAGS is large, the value may
++ * need to be limited to MAX_PAGE_BUFFER_COUNT, which is the max # of entries
++ * in a GPA direct packet sent to netvsp over VMBus.
++ */
++#if MAX_SKB_FRAGS + 2 < MAX_PAGE_BUFFER_COUNT
++#define MAX_DATA_RANGES (MAX_SKB_FRAGS + 2)
++#else
++#define MAX_DATA_RANGES MAX_PAGE_BUFFER_COUNT
++#endif
++
+ /* Estimated requestor size:
+ * out_ring_size/min_out_msg_size + in_ring_size/min_in_msg_size
+ */
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -325,43 +325,10 @@ static u16 netvsc_select_queue(struct ne
+ return txq;
+ }
+
+-static u32 fill_pg_buf(unsigned long hvpfn, u32 offset, u32 len,
+- struct hv_page_buffer *pb)
+-{
+- int j = 0;
+-
+- hvpfn += offset >> HV_HYP_PAGE_SHIFT;
+- offset = offset & ~HV_HYP_PAGE_MASK;
+-
+- while (len > 0) {
+- unsigned long bytes;
+-
+- bytes = HV_HYP_PAGE_SIZE - offset;
+- if (bytes > len)
+- bytes = len;
+- pb[j].pfn = hvpfn;
+- pb[j].offset = offset;
+- pb[j].len = bytes;
+-
+- offset += bytes;
+- len -= bytes;
+-
+- if (offset == HV_HYP_PAGE_SIZE && len) {
+- hvpfn++;
+- offset = 0;
+- j++;
+- }
+- }
+-
+- return j + 1;
+-}
+-
+ static u32 init_page_array(void *hdr, u32 len, struct sk_buff *skb,
+ struct hv_netvsc_packet *packet,
+ struct hv_page_buffer *pb)
+ {
+- u32 slots_used = 0;
+- char *data = skb->data;
+ int frags = skb_shinfo(skb)->nr_frags;
+ int i;
+
+@@ -370,28 +337,28 @@ static u32 init_page_array(void *hdr, u3
+ * 2. skb linear data
+ * 3. skb fragment data
+ */
+- slots_used += fill_pg_buf(virt_to_hvpfn(hdr),
+- offset_in_hvpage(hdr),
+- len,
+- &pb[slots_used]);
+
++ pb[0].offset = offset_in_hvpage(hdr);
++ pb[0].len = len;
++ pb[0].pfn = virt_to_hvpfn(hdr);
+ packet->rmsg_size = len;
+- packet->rmsg_pgcnt = slots_used;
++ packet->rmsg_pgcnt = 1;
+
+- slots_used += fill_pg_buf(virt_to_hvpfn(data),
+- offset_in_hvpage(data),
+- skb_headlen(skb),
+- &pb[slots_used]);
++ pb[1].offset = offset_in_hvpage(skb->data);
++ pb[1].len = skb_headlen(skb);
++ pb[1].pfn = virt_to_hvpfn(skb->data);
+
+ for (i = 0; i < frags; i++) {
+ skb_frag_t *frag = skb_shinfo(skb)->frags + i;
+-
+- slots_used += fill_pg_buf(page_to_hvpfn(skb_frag_page(frag)),
+- skb_frag_off(frag),
+- skb_frag_size(frag),
+- &pb[slots_used]);
++ struct hv_page_buffer *cur_pb = &pb[i + 2];
++ u64 pfn = page_to_hvpfn(skb_frag_page(frag));
++ u32 offset = skb_frag_off(frag);
++
++ cur_pb->offset = offset_in_hvpage(offset);
++ cur_pb->len = skb_frag_size(frag);
++ cur_pb->pfn = pfn + (offset >> HV_HYP_PAGE_SHIFT);
+ }
+- return slots_used;
++ return frags + 2;
+ }
+
+ static int count_skb_frag_slots(struct sk_buff *skb)
+@@ -482,7 +449,7 @@ static int netvsc_xmit(struct sk_buff *s
+ struct net_device *vf_netdev;
+ u32 rndis_msg_size;
+ u32 hash;
+- struct hv_page_buffer pb[MAX_PAGE_BUFFER_COUNT];
++ struct hv_page_buffer pb[MAX_DATA_RANGES];
+
+ /* If VF is present and up then redirect packets to it.
+ * Skip the VF if it is marked down or has no carrier.
+--- a/drivers/net/hyperv/rndis_filter.c
++++ b/drivers/net/hyperv/rndis_filter.c
+@@ -225,8 +225,7 @@ static int rndis_filter_send_request(str
+ struct rndis_request *req)
+ {
+ struct hv_netvsc_packet *packet;
+- struct hv_page_buffer page_buf[2];
+- struct hv_page_buffer *pb = page_buf;
++ struct hv_page_buffer pb;
+ int ret;
+
+ /* Setup the packet to send it */
+@@ -235,27 +234,14 @@ static int rndis_filter_send_request(str
+ packet->total_data_buflen = req->request_msg.msg_len;
+ packet->page_buf_cnt = 1;
+
+- pb[0].pfn = virt_to_phys(&req->request_msg) >>
+- HV_HYP_PAGE_SHIFT;
+- pb[0].len = req->request_msg.msg_len;
+- pb[0].offset = offset_in_hvpage(&req->request_msg);
+-
+- /* Add one page_buf when request_msg crossing page boundary */
+- if (pb[0].offset + pb[0].len > HV_HYP_PAGE_SIZE) {
+- packet->page_buf_cnt++;
+- pb[0].len = HV_HYP_PAGE_SIZE -
+- pb[0].offset;
+- pb[1].pfn = virt_to_phys((void *)&req->request_msg
+- + pb[0].len) >> HV_HYP_PAGE_SHIFT;
+- pb[1].offset = 0;
+- pb[1].len = req->request_msg.msg_len -
+- pb[0].len;
+- }
++ pb.pfn = virt_to_phys(&req->request_msg) >> HV_HYP_PAGE_SHIFT;
++ pb.len = req->request_msg.msg_len;
++ pb.offset = offset_in_hvpage(&req->request_msg);
+
+ trace_rndis_send(dev->ndev, 0, &req->request_msg);
+
+ rcu_read_lock_bh();
+- ret = netvsc_send(dev->ndev, packet, NULL, pb, NULL, false);
++ ret = netvsc_send(dev->ndev, packet, NULL, &pb, NULL, false);
+ rcu_read_unlock_bh();
+
+ return ret;
--- /dev/null
+From 5bbc644bbf4e97a05bc0cb052189004588ff8a09 Mon Sep 17 00:00:00 2001
+From: Michael Kelley <mhklinux@outlook.com>
+Date: Mon, 12 May 2025 17:06:03 -0700
+Subject: hv_netvsc: Remove rmsg_pgcnt
+
+From: Michael Kelley <mhklinux@outlook.com>
+
+commit 5bbc644bbf4e97a05bc0cb052189004588ff8a09 upstream.
+
+init_page_array() now always creates a single page buffer array entry
+for the rndis message, even if the rndis message crosses a page
+boundary. As such, the number of page buffer array entries used for
+the rndis message must no longer be tracked -- it is always just 1.
+Remove the rmsg_pgcnt field and use "1" where the value is needed.
+
+Cc: <stable@vger.kernel.org> # 6.1.x
+Signed-off-by: Michael Kelley <mhklinux@outlook.com>
+Link: https://patch.msgid.link/20250513000604.1396-5-mhklinux@outlook.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/hyperv/hyperv_net.h | 1 -
+ drivers/net/hyperv/netvsc.c | 7 +++----
+ drivers/net/hyperv/netvsc_drv.c | 1 -
+ 3 files changed, 3 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/hyperv/hyperv_net.h
++++ b/drivers/net/hyperv/hyperv_net.h
+@@ -158,7 +158,6 @@ struct hv_netvsc_packet {
+ u8 cp_partial; /* partial copy into send buffer */
+
+ u8 rmsg_size; /* RNDIS header and PPI size */
+- u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */
+ u8 page_buf_cnt;
+
+ u16 q_idx;
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -947,8 +947,7 @@ static void netvsc_copy_to_send_buf(stru
+ + pend_size;
+ int i;
+ u32 padding = 0;
+- u32 page_count = packet->cp_partial ? packet->rmsg_pgcnt :
+- packet->page_buf_cnt;
++ u32 page_count = packet->cp_partial ? 1 : packet->page_buf_cnt;
+ u32 remain;
+
+ /* Add padding */
+@@ -1131,7 +1130,7 @@ static inline int netvsc_send_pkt(
+ u32 desc_size;
+
+ if (packet->cp_partial)
+- pb += packet->rmsg_pgcnt;
++ pb++;
+
+ ret = netvsc_dma_map(ndev_ctx->device_ctx, packet, pb);
+ if (ret) {
+@@ -1293,7 +1292,7 @@ int netvsc_send(struct net_device *ndev,
+ packet->send_buf_index = section_index;
+
+ if (packet->cp_partial) {
+- packet->page_buf_cnt -= packet->rmsg_pgcnt;
++ packet->page_buf_cnt--;
+ packet->total_data_buflen = msd_len + packet->rmsg_size;
+ } else {
+ packet->page_buf_cnt = 0;
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -342,7 +342,6 @@ static u32 init_page_array(void *hdr, u3
+ pb[0].len = len;
+ pb[0].pfn = virt_to_hvpfn(hdr);
+ packet->rmsg_size = len;
+- packet->rmsg_pgcnt = 1;
+
+ pb[1].offset = offset_in_hvpage(skb->data);
+ pb[1].len = skb_headlen(skb);
--- /dev/null
+From 4f98616b855cb0e3b5917918bb07b44728eb96ea Mon Sep 17 00:00:00 2001
+From: Michael Kelley <mhklinux@outlook.com>
+Date: Mon, 12 May 2025 17:06:01 -0700
+Subject: hv_netvsc: Use vmbus_sendpacket_mpb_desc() to send VMBus messages
+
+From: Michael Kelley <mhklinux@outlook.com>
+
+commit 4f98616b855cb0e3b5917918bb07b44728eb96ea upstream.
+
+netvsc currently uses vmbus_sendpacket_pagebuffer() to send VMBus
+messages. This function creates a series of GPA ranges, each of which
+contains a single PFN. However, if the rndis header in the VMBus
+message crosses a page boundary, the netvsc protocol with the host
+requires that both PFNs for the rndis header must be in a single "GPA
+range" data structure, which isn't possible with
+vmbus_sendpacket_pagebuffer(). As the first step in fixing this, add a
+new function netvsc_build_mpb_array() to build a VMBus message with
+multiple GPA ranges, each of which may contain multiple PFNs. Use
+vmbus_sendpacket_mpb_desc() to send this VMBus message to the host.
+
+There's no functional change since higher levels of netvsc don't
+maintain or propagate knowledge of contiguous PFNs. Based on its
+input, netvsc_build_mpb_array() still produces a separate GPA range
+for each PFN and the behavior is the same as with
+vmbus_sendpacket_pagebuffer(). But the groundwork is laid for a
+subsequent patch to provide the necessary grouping.
+
+Cc: <stable@vger.kernel.org> # 6.1.x
+Signed-off-by: Michael Kelley <mhklinux@outlook.com>
+Link: https://patch.msgid.link/20250513000604.1396-3-mhklinux@outlook.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/hyperv/netvsc.c | 50 +++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 45 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -1049,6 +1049,42 @@ static int netvsc_dma_map(struct hv_devi
+ return 0;
+ }
+
++/* Build an "array" of mpb entries describing the data to be transferred
++ * over VMBus. After the desc header fields, each "array" entry is variable
++ * size, and each entry starts after the end of the previous entry. The
++ * "offset" and "len" fields for each entry imply the size of the entry.
++ *
++ * The pfns are in HV_HYP_PAGE_SIZE, because all communication with Hyper-V
++ * uses that granularity, even if the system page size of the guest is larger.
++ * Each entry in the input "pb" array must describe a contiguous range of
++ * guest physical memory so that the pfns are sequential if the range crosses
++ * a page boundary. The offset field must be < HV_HYP_PAGE_SIZE.
++ */
++static inline void netvsc_build_mpb_array(struct hv_page_buffer *pb,
++ u32 page_buffer_count,
++ struct vmbus_packet_mpb_array *desc,
++ u32 *desc_size)
++{
++ struct hv_mpb_array *mpb_entry = &desc->range;
++ int i, j;
++
++ for (i = 0; i < page_buffer_count; i++) {
++ u32 offset = pb[i].offset;
++ u32 len = pb[i].len;
++
++ mpb_entry->offset = offset;
++ mpb_entry->len = len;
++
++ for (j = 0; j < HVPFN_UP(offset + len); j++)
++ mpb_entry->pfn_array[j] = pb[i].pfn + j;
++
++ mpb_entry = (struct hv_mpb_array *)&mpb_entry->pfn_array[j];
++ }
++
++ desc->rangecount = page_buffer_count;
++ *desc_size = (char *)mpb_entry - (char *)desc;
++}
++
+ static inline int netvsc_send_pkt(
+ struct hv_device *device,
+ struct hv_netvsc_packet *packet,
+@@ -1091,6 +1127,9 @@ static inline int netvsc_send_pkt(
+
+ packet->dma_range = NULL;
+ if (packet->page_buf_cnt) {
++ struct vmbus_channel_packet_page_buffer desc;
++ u32 desc_size;
++
+ if (packet->cp_partial)
+ pb += packet->rmsg_pgcnt;
+
+@@ -1100,11 +1139,12 @@ static inline int netvsc_send_pkt(
+ goto exit;
+ }
+
+- ret = vmbus_sendpacket_pagebuffer(out_channel,
+- pb, packet->page_buf_cnt,
+- &nvmsg, sizeof(nvmsg),
+- req_id);
+-
++ netvsc_build_mpb_array(pb, packet->page_buf_cnt,
++ (struct vmbus_packet_mpb_array *)&desc,
++ &desc_size);
++ ret = vmbus_sendpacket_mpb_desc(out_channel,
++ (struct vmbus_packet_mpb_array *)&desc,
++ desc_size, &nvmsg, sizeof(nvmsg), req_id);
+ if (ret)
+ netvsc_dma_unmap(ndev_ctx->device_ctx, packet);
+ } else {
--- /dev/null
+From d0afcfeb9e3810ec89d1ffde1a0e36621bb75dca Mon Sep 17 00:00:00 2001
+From: Nathan Chancellor <nathan@kernel.org>
+Date: Tue, 6 May 2025 14:02:01 -0700
+Subject: kbuild: Disable -Wdefault-const-init-unsafe
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+commit d0afcfeb9e3810ec89d1ffde1a0e36621bb75dca upstream.
+
+A new on by default warning in clang [1] aims to flags instances where
+const variables without static or thread local storage or const members
+in aggregate types are not initialized because it can lead to an
+indeterminate value. This is quite noisy for the kernel due to
+instances originating from header files such as:
+
+ drivers/gpu/drm/i915/gt/intel_ring.h:62:2: error: default initialization of an object of type 'typeof (ring->size)' (aka 'const unsigned int') leaves the object uninitialized [-Werror,-Wdefault-const-init-var-unsafe]
+ 62 | typecheck(typeof(ring->size), next);
+ | ^
+ include/linux/typecheck.h:10:9: note: expanded from macro 'typecheck'
+ 10 | ({ type __dummy; \
+ | ^
+
+ include/net/ip.h:478:14: error: default initialization of an object of type 'typeof (rt->dst.expires)' (aka 'const unsigned long') leaves the object uninitialized [-Werror,-Wdefault-const-init-var-unsafe]
+ 478 | if (mtu && time_before(jiffies, rt->dst.expires))
+ | ^
+ include/linux/jiffies.h:138:26: note: expanded from macro 'time_before'
+ 138 | #define time_before(a,b) time_after(b,a)
+ | ^
+ include/linux/jiffies.h:128:3: note: expanded from macro 'time_after'
+ 128 | (typecheck(unsigned long, a) && \
+ | ^
+ include/linux/typecheck.h:11:12: note: expanded from macro 'typecheck'
+ 11 | typeof(x) __dummy2; \
+ | ^
+
+ include/linux/list.h:409:27: warning: default initialization of an object of type 'union (unnamed union at include/linux/list.h:409:27)' with const member leaves the object uninitialized [-Wdefault-const-init-field-unsafe]
+ 409 | struct list_head *next = smp_load_acquire(&head->next);
+ | ^
+ include/asm-generic/barrier.h:176:29: note: expanded from macro 'smp_load_acquire'
+ 176 | #define smp_load_acquire(p) __smp_load_acquire(p)
+ | ^
+ arch/arm64/include/asm/barrier.h:164:59: note: expanded from macro '__smp_load_acquire'
+ 164 | union { __unqual_scalar_typeof(*p) __val; char __c[1]; } __u; \
+ | ^
+ include/linux/list.h:409:27: note: member '__val' declared 'const' here
+
+ crypto/scatterwalk.c:66:22: error: default initialization of an object of type 'struct scatter_walk' with const member leaves the object uninitialized [-Werror,-Wdefault-const-init-field-unsafe]
+ 66 | struct scatter_walk walk;
+ | ^
+ include/crypto/algapi.h:112:15: note: member 'addr' declared 'const' here
+ 112 | void *const addr;
+ | ^
+
+ fs/hugetlbfs/inode.c:733:24: error: default initialization of an object of type 'struct vm_area_struct' with const member leaves the object uninitialized [-Werror,-Wdefault-const-init-field-unsafe]
+ 733 | struct vm_area_struct pseudo_vma;
+ | ^
+ include/linux/mm_types.h:803:20: note: member 'vm_flags' declared 'const' here
+ 803 | const vm_flags_t vm_flags;
+ | ^
+
+Silencing the instances from typecheck.h is difficult because '= {}' is
+not available in older but supported compilers and '= {0}' would cause
+warnings about a literal 0 being treated as NULL. While it might be
+possible to come up with a local hack to silence the warning for
+clang-21+, it may not be worth it since -Wuninitialized will still
+trigger if an uninitialized const variable is actually used.
+
+In all audited cases of the "field" variant of the warning, the members
+are either not used in the particular call path, modified through other
+means such as memset() / memcpy() because the containing object is not
+const, or are within a union with other non-const members.
+
+Since this warning does not appear to have a high signal to noise ratio,
+just disable it.
+
+Cc: stable@vger.kernel.org
+Link: https://github.com/llvm/llvm-project/commit/576161cb6069e2c7656a8ef530727a0f4aefff30 [1]
+Reported-by: Linux Kernel Functional Testing <lkft@linaro.org>
+Closes: https://lore.kernel.org/CA+G9fYuNjKcxFKS_MKPRuga32XbndkLGcY-PVuoSwzv6VWbY=w@mail.gmail.com/
+Reported-by: Marcus Seyfarth <m.seyfarth@gmail.com>
+Closes: https://github.com/ClangBuiltLinux/linux/issues/2088
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/Makefile.extrawarn | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/scripts/Makefile.extrawarn
++++ b/scripts/Makefile.extrawarn
+@@ -36,6 +36,18 @@ KBUILD_CFLAGS += -Wno-gnu
+ # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111219
+ KBUILD_CFLAGS += $(call cc-disable-warning, format-overflow-non-kprintf)
+ KBUILD_CFLAGS += $(call cc-disable-warning, format-truncation-non-kprintf)
++
++# Clang may emit a warning when a const variable, such as the dummy variables
++# in typecheck(), or const member of an aggregate type are not initialized,
++# which can result in unexpected behavior. However, in many audited cases of
++# the "field" variant of the warning, this is intentional because the field is
++# never used within a particular call path, the field is within a union with
++# other non-const members, or the containing object is not const so the field
++# can be modified via memcpy() / memset(). While the variable warning also gets
++# disabled with this same switch, there should not be too much coverage lost
++# because -Wuninitialized will still flag when an uninitialized const variable
++# is used.
++KBUILD_CFLAGS += $(call cc-disable-warning, default-const-init-unsafe)
+ else
+
+ # gcc inanely warns about local variables called 'main'
--- /dev/null
+From 75cb1cca2c880179a11c7dd9380b6f14e41a06a4 Mon Sep 17 00:00:00 2001
+From: Barry Song <v-songbaohua@oppo.com>
+Date: Fri, 9 May 2025 10:09:12 +1200
+Subject: mm: userfaultfd: correct dirty flags set for both present and swap pte
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Barry Song <v-songbaohua@oppo.com>
+
+commit 75cb1cca2c880179a11c7dd9380b6f14e41a06a4 upstream.
+
+As David pointed out, what truly matters for mremap and userfaultfd move
+operations is the soft dirty bit. The current comment and
+implementation—which always sets the dirty bit for present PTEs and
+fails to set the soft dirty bit for swap PTEs—are incorrect. This could
+break features like Checkpoint-Restore in Userspace (CRIU).
+
+This patch updates the behavior to correctly set the soft dirty bit for
+both present and swap PTEs in accordance with mremap.
+
+Link: https://lkml.kernel.org/r/20250508220912.7275-1-21cnbao@gmail.com
+Fixes: adef440691ba ("userfaultfd: UFFDIO_MOVE uABI")
+Signed-off-by: Barry Song <v-songbaohua@oppo.com>
+Reported-by: David Hildenbrand <david@redhat.com>
+Closes: https://lore.kernel.org/linux-mm/02f14ee1-923f-47e3-a994-4950afb9afcc@redhat.com/
+Acked-by: Peter Xu <peterx@redhat.com>
+Reviewed-by: Suren Baghdasaryan <surenb@google.com>
+Cc: Lokesh Gidra <lokeshgidra@google.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/userfaultfd.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/mm/userfaultfd.c
++++ b/mm/userfaultfd.c
+@@ -1059,8 +1059,13 @@ static int move_present_pte(struct mm_st
+ src_folio->index = linear_page_index(dst_vma, dst_addr);
+
+ orig_dst_pte = mk_pte(&src_folio->page, dst_vma->vm_page_prot);
+- /* Follow mremap() behavior and treat the entry dirty after the move */
+- orig_dst_pte = pte_mkwrite(pte_mkdirty(orig_dst_pte), dst_vma);
++ /* Set soft dirty bit so userspace can notice the pte was moved */
++#ifdef CONFIG_MEM_SOFT_DIRTY
++ orig_dst_pte = pte_mksoft_dirty(orig_dst_pte);
++#endif
++ if (pte_dirty(orig_src_pte))
++ orig_dst_pte = pte_mkdirty(orig_dst_pte);
++ orig_dst_pte = pte_mkwrite(orig_dst_pte, dst_vma);
+
+ set_pte_at(mm, dst_addr, dst_pte, orig_dst_pte);
+ out:
+@@ -1094,6 +1099,9 @@ static int move_swap_pte(struct mm_struc
+ }
+
+ orig_src_pte = ptep_get_and_clear(mm, src_addr, src_pte);
++#ifdef CONFIG_MEM_SOFT_DIRTY
++ orig_src_pte = pte_swp_mksoft_dirty(orig_src_pte);
++#endif
+ set_pte_at(mm, dst_addr, dst_pte, orig_src_pte);
+ double_pt_unlock(dst_ptl, src_ptl);
+
--- /dev/null
+From 6b3ab7f2cbfaeb6580709cd8ef4d72cfd01bfde4 Mon Sep 17 00:00:00 2001
+From: Nathan Chancellor <nathan@kernel.org>
+Date: Wed, 7 May 2025 21:47:45 +0100
+Subject: net: qede: Initialize qede_ll_ops with designated initializer
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+commit 6b3ab7f2cbfaeb6580709cd8ef4d72cfd01bfde4 upstream.
+
+After a recent change [1] in clang's randstruct implementation to
+randomize structures that only contain function pointers, there is an
+error because qede_ll_ops get randomized but does not use a designated
+initializer for the first member:
+
+ drivers/net/ethernet/qlogic/qede/qede_main.c:206:2: error: a randomized struct can only be initialized with a designated initializer
+ 206 | {
+ | ^
+
+Explicitly initialize the common member using a designated initializer
+to fix the build.
+
+Cc: stable@vger.kernel.org
+Fixes: 035f7f87b729 ("randstruct: Enable Clang support")
+Link: https://github.com/llvm/llvm-project/commit/04364fb888eea6db9811510607bed4b200bcb082 [1]
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Link: https://patch.msgid.link/20250507-qede-fix-clang-randstruct-v1-1-5ccc15626fba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/qlogic/qede/qede_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
++++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
+@@ -203,7 +203,7 @@ static struct pci_driver qede_pci_driver
+ };
+
+ static struct qed_eth_cb_ops qede_ll_ops = {
+- {
++ .common = {
+ #ifdef CONFIG_RFS_ACCEL
+ .arfs_filter_op = qede_arfs_filter_op,
+ #endif
--- /dev/null
+From b2ea5f49580c0762d17d80d8083cb89bc3acf74f Mon Sep 17 00:00:00 2001
+From: Ma Ke <make24@iscas.ac.cn>
+Date: Mon, 3 Mar 2025 15:27:39 +0800
+Subject: phy: Fix error handling in tegra_xusb_port_init
+
+From: Ma Ke <make24@iscas.ac.cn>
+
+commit b2ea5f49580c0762d17d80d8083cb89bc3acf74f upstream.
+
+If device_add() fails, do not use device_unregister() for error
+handling. device_unregister() consists two functions: device_del() and
+put_device(). device_unregister() should only be called after
+device_add() succeeded because device_del() undoes what device_add()
+does if successful. Change device_unregister() to put_device() call
+before returning from the function.
+
+As comment of device_add() says, 'if device_add() succeeds, you should
+call device_del() when you want to get rid of it. If device_add() has
+not succeeded, use only put_device() to drop the reference count'.
+
+Found by code review.
+
+Cc: stable@vger.kernel.org
+Fixes: 53d2a715c240 ("phy: Add Tegra XUSB pad controller support")
+Signed-off-by: Ma Ke <make24@iscas.ac.cn>
+Acked-by: Thierry Reding <treding@nvidia.com>
+Link: https://lore.kernel.org/r/20250303072739.3874987-1-make24@iscas.ac.cn
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/phy/tegra/xusb.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/phy/tegra/xusb.c
++++ b/drivers/phy/tegra/xusb.c
+@@ -548,16 +548,16 @@ static int tegra_xusb_port_init(struct t
+
+ err = dev_set_name(&port->dev, "%s-%u", name, index);
+ if (err < 0)
+- goto unregister;
++ goto put_device;
+
+ err = device_add(&port->dev);
+ if (err < 0)
+- goto unregister;
++ goto put_device;
+
+ return 0;
+
+-unregister:
+- device_unregister(&port->dev);
++put_device:
++ put_device(&port->dev);
+ return err;
+ }
+
--- /dev/null
+From 54c4c58713aaff76c2422ff5750e557ab3b100d7 Mon Sep 17 00:00:00 2001
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Date: Wed, 7 May 2025 15:50:28 +0300
+Subject: phy: renesas: rcar-gen3-usb2: Fix role detection on unbind/bind
+
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+
+commit 54c4c58713aaff76c2422ff5750e557ab3b100d7 upstream.
+
+It has been observed on the Renesas RZ/G3S SoC that unbinding and binding
+the PHY driver leads to role autodetection failures. This issue occurs when
+PHY 3 is the first initialized PHY. PHY 3 does not have an interrupt
+associated with the USB2_INT_ENABLE register (as
+rcar_gen3_int_enable[3] = 0). As a result, rcar_gen3_init_otg() is called
+to initialize OTG without enabling PHY interrupts.
+
+To resolve this, add rcar_gen3_is_any_otg_rphy_initialized() and call it in
+role_store(), role_show(), and rcar_gen3_init_otg(). At the same time,
+rcar_gen3_init_otg() is only called when initialization for a PHY with
+interrupt bits is in progress. As a result, the
+struct rcar_gen3_phy::otg_initialized is no longer needed.
+
+Fixes: 549b6b55b005 ("phy: renesas: rcar-gen3-usb2: enable/disable independent irqs")
+Cc: stable@vger.kernel.org
+Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Link: https://lore.kernel.org/r/20250507125032.565017-2-claudiu.beznea.uj@bp.renesas.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/phy/renesas/phy-rcar-gen3-usb2.c | 33 +++++++++++++------------------
+ 1 file changed, 14 insertions(+), 19 deletions(-)
+
+--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
++++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+@@ -107,7 +107,6 @@ struct rcar_gen3_phy {
+ struct rcar_gen3_chan *ch;
+ u32 int_enable_bits;
+ bool initialized;
+- bool otg_initialized;
+ bool powered;
+ };
+
+@@ -320,16 +319,15 @@ static bool rcar_gen3_is_any_rphy_initia
+ return false;
+ }
+
+-static bool rcar_gen3_needs_init_otg(struct rcar_gen3_chan *ch)
++static bool rcar_gen3_is_any_otg_rphy_initialized(struct rcar_gen3_chan *ch)
+ {
+- int i;
+-
+- for (i = 0; i < NUM_OF_PHYS; i++) {
+- if (ch->rphys[i].otg_initialized)
+- return false;
++ for (enum rcar_gen3_phy_index i = PHY_INDEX_BOTH_HC; i <= PHY_INDEX_EHCI;
++ i++) {
++ if (ch->rphys[i].initialized)
++ return true;
+ }
+
+- return true;
++ return false;
+ }
+
+ static bool rcar_gen3_are_all_rphys_power_off(struct rcar_gen3_chan *ch)
+@@ -351,7 +349,7 @@ static ssize_t role_store(struct device
+ bool is_b_device;
+ enum phy_mode cur_mode, new_mode;
+
+- if (!ch->is_otg_channel || !rcar_gen3_is_any_rphy_initialized(ch))
++ if (!ch->is_otg_channel || !rcar_gen3_is_any_otg_rphy_initialized(ch))
+ return -EIO;
+
+ if (sysfs_streq(buf, "host"))
+@@ -389,7 +387,7 @@ static ssize_t role_show(struct device *
+ {
+ struct rcar_gen3_chan *ch = dev_get_drvdata(dev);
+
+- if (!ch->is_otg_channel || !rcar_gen3_is_any_rphy_initialized(ch))
++ if (!ch->is_otg_channel || !rcar_gen3_is_any_otg_rphy_initialized(ch))
+ return -EIO;
+
+ return sprintf(buf, "%s\n", rcar_gen3_is_host(ch) ? "host" :
+@@ -402,6 +400,9 @@ static void rcar_gen3_init_otg(struct rc
+ void __iomem *usb2_base = ch->base;
+ u32 val;
+
++ if (!ch->is_otg_channel || rcar_gen3_is_any_otg_rphy_initialized(ch))
++ return;
++
+ /* Should not use functions of read-modify-write a register */
+ val = readl(usb2_base + USB2_LINECTRL1);
+ val = (val & ~USB2_LINECTRL1_DP_RPD) | USB2_LINECTRL1_DPRPD_EN |
+@@ -465,12 +466,9 @@ static int rcar_gen3_phy_usb2_init(struc
+ writel(USB2_SPD_RSM_TIMSET_INIT, usb2_base + USB2_SPD_RSM_TIMSET);
+ writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET);
+
+- /* Initialize otg part */
+- if (channel->is_otg_channel) {
+- if (rcar_gen3_needs_init_otg(channel))
+- rcar_gen3_init_otg(channel);
+- rphy->otg_initialized = true;
+- }
++ /* Initialize otg part (only if we initialize a PHY with IRQs). */
++ if (rphy->int_enable_bits)
++ rcar_gen3_init_otg(channel);
+
+ rphy->initialized = true;
+
+@@ -486,9 +484,6 @@ static int rcar_gen3_phy_usb2_exit(struc
+
+ rphy->initialized = false;
+
+- if (channel->is_otg_channel)
+- rphy->otg_initialized = false;
+-
+ val = readl(usb2_base + USB2_INT_ENABLE);
+ val &= ~rphy->int_enable_bits;
+ if (!rcar_gen3_is_any_rphy_initialized(channel))
--- /dev/null
+From 86e70849f4b2b4597ac9f7c7931f2a363774be25 Mon Sep 17 00:00:00 2001
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Date: Wed, 7 May 2025 15:50:32 +0300
+Subject: phy: renesas: rcar-gen3-usb2: Set timing registers only once
+
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+
+commit 86e70849f4b2b4597ac9f7c7931f2a363774be25 upstream.
+
+phy-rcar-gen3-usb2 driver exports 4 PHYs. The timing registers are common
+to all PHYs. There is no need to set them every time a PHY is initialized.
+Set timing register only when the 1st PHY is initialized.
+
+Fixes: f3b5a8d9b50d ("phy: rcar-gen3-usb2: Add R-Car Gen3 USB2 PHY driver")
+Cc: stable@vger.kernel.org
+Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Link: https://lore.kernel.org/r/20250507125032.565017-6-claudiu.beznea.uj@bp.renesas.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/phy/renesas/phy-rcar-gen3-usb2.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
++++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+@@ -463,8 +463,11 @@ static int rcar_gen3_phy_usb2_init(struc
+ val = readl(usb2_base + USB2_INT_ENABLE);
+ val |= USB2_INT_ENABLE_UCOM_INTEN | rphy->int_enable_bits;
+ writel(val, usb2_base + USB2_INT_ENABLE);
+- writel(USB2_SPD_RSM_TIMSET_INIT, usb2_base + USB2_SPD_RSM_TIMSET);
+- writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET);
++
++ if (!rcar_gen3_is_any_rphy_initialized(channel)) {
++ writel(USB2_SPD_RSM_TIMSET_INIT, usb2_base + USB2_SPD_RSM_TIMSET);
++ writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET);
++ }
+
+ /* Initialize otg part (only if we initialize a PHY with IRQs). */
+ if (rphy->int_enable_bits)
--- /dev/null
+From b47158fb42959c417ff2662075c0d46fb783d5d1 Mon Sep 17 00:00:00 2001
+From: Wayne Chang <waynec@nvidia.com>
+Date: Tue, 8 Apr 2025 11:09:05 +0800
+Subject: phy: tegra: xusb: Use a bitmask for UTMI pad power state tracking
+
+From: Wayne Chang <waynec@nvidia.com>
+
+commit b47158fb42959c417ff2662075c0d46fb783d5d1 upstream.
+
+The current implementation uses bias_pad_enable as a reference count to
+manage the shared bias pad for all UTMI PHYs. However, during system
+suspension with connected USB devices, multiple power-down requests for
+the UTMI pad result in a mismatch in the reference count, which in turn
+produces warnings such as:
+
+[ 237.762967] WARNING: CPU: 10 PID: 1618 at tegra186_utmi_pad_power_down+0x160/0x170
+[ 237.763103] Call trace:
+[ 237.763104] tegra186_utmi_pad_power_down+0x160/0x170
+[ 237.763107] tegra186_utmi_phy_power_off+0x10/0x30
+[ 237.763110] phy_power_off+0x48/0x100
+[ 237.763113] tegra_xusb_enter_elpg+0x204/0x500
+[ 237.763119] tegra_xusb_suspend+0x48/0x140
+[ 237.763122] platform_pm_suspend+0x2c/0xb0
+[ 237.763125] dpm_run_callback.isra.0+0x20/0xa0
+[ 237.763127] __device_suspend+0x118/0x330
+[ 237.763129] dpm_suspend+0x10c/0x1f0
+[ 237.763130] dpm_suspend_start+0x88/0xb0
+[ 237.763132] suspend_devices_and_enter+0x120/0x500
+[ 237.763135] pm_suspend+0x1ec/0x270
+
+The root cause was traced back to the dynamic power-down changes
+introduced in commit a30951d31b25 ("xhci: tegra: USB2 pad power controls"),
+where the UTMI pad was being powered down without verifying its current
+state. This unbalanced behavior led to discrepancies in the reference
+count.
+
+To rectify this issue, this patch replaces the single reference counter
+with a bitmask, renamed to utmi_pad_enabled. Each bit in the mask
+corresponds to one of the four USB2 PHYs, allowing us to track each pad's
+enablement status individually.
+
+With this change:
+ - The bias pad is powered on only when the mask is clear.
+ - Each UTMI pad is powered on or down based on its corresponding bit
+ in the mask, preventing redundant operations.
+ - The overall power state of the shared bias pad is maintained
+ correctly during suspend/resume cycles.
+
+The mutex used to prevent race conditions during UTMI pad enable/disable
+operations has been moved from the tegra186_utmi_bias_pad_power_on/off
+functions to the parent functions tegra186_utmi_pad_power_on/down. This
+change ensures that there are no race conditions when updating the bitmask.
+
+Cc: stable@vger.kernel.org
+Fixes: a30951d31b25 ("xhci: tegra: USB2 pad power controls")
+Signed-off-by: Wayne Chang <waynec@nvidia.com>
+Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
+Tested-by: Jon Hunter <jonathanh@nvidia.com>
+Link: https://lore.kernel.org/r/20250408030905.990474-1-waynec@nvidia.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/phy/tegra/xusb-tegra186.c | 44 +++++++++++++++++++++++---------------
+ 1 file changed, 27 insertions(+), 17 deletions(-)
+
+--- a/drivers/phy/tegra/xusb-tegra186.c
++++ b/drivers/phy/tegra/xusb-tegra186.c
+@@ -237,6 +237,8 @@
+ #define DATA0_VAL_PD BIT(1)
+ #define USE_XUSB_AO BIT(4)
+
++#define TEGRA_UTMI_PAD_MAX 4
++
+ #define TEGRA186_LANE(_name, _offset, _shift, _mask, _type) \
+ { \
+ .name = _name, \
+@@ -269,7 +271,7 @@ struct tegra186_xusb_padctl {
+
+ /* UTMI bias and tracking */
+ struct clk *usb2_trk_clk;
+- unsigned int bias_pad_enable;
++ DECLARE_BITMAP(utmi_pad_enabled, TEGRA_UTMI_PAD_MAX);
+
+ /* padctl context */
+ struct tegra186_xusb_padctl_context context;
+@@ -603,12 +605,8 @@ static void tegra186_utmi_bias_pad_power
+ u32 value;
+ int err;
+
+- mutex_lock(&padctl->lock);
+-
+- if (priv->bias_pad_enable++ > 0) {
+- mutex_unlock(&padctl->lock);
++ if (!bitmap_empty(priv->utmi_pad_enabled, TEGRA_UTMI_PAD_MAX))
+ return;
+- }
+
+ err = clk_prepare_enable(priv->usb2_trk_clk);
+ if (err < 0)
+@@ -667,17 +665,8 @@ static void tegra186_utmi_bias_pad_power
+ struct tegra186_xusb_padctl *priv = to_tegra186_xusb_padctl(padctl);
+ u32 value;
+
+- mutex_lock(&padctl->lock);
+-
+- if (WARN_ON(priv->bias_pad_enable == 0)) {
+- mutex_unlock(&padctl->lock);
+- return;
+- }
+-
+- if (--priv->bias_pad_enable > 0) {
+- mutex_unlock(&padctl->lock);
++ if (!bitmap_empty(priv->utmi_pad_enabled, TEGRA_UTMI_PAD_MAX))
+ return;
+- }
+
+ value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
+ value |= USB2_PD_TRK;
+@@ -690,13 +679,13 @@ static void tegra186_utmi_bias_pad_power
+ clk_disable_unprepare(priv->usb2_trk_clk);
+ }
+
+- mutex_unlock(&padctl->lock);
+ }
+
+ static void tegra186_utmi_pad_power_on(struct phy *phy)
+ {
+ struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
+ struct tegra_xusb_padctl *padctl = lane->pad->padctl;
++ struct tegra186_xusb_padctl *priv = to_tegra186_xusb_padctl(padctl);
+ struct tegra_xusb_usb2_port *port;
+ struct device *dev = padctl->dev;
+ unsigned int index = lane->index;
+@@ -705,9 +694,16 @@ static void tegra186_utmi_pad_power_on(s
+ if (!phy)
+ return;
+
++ mutex_lock(&padctl->lock);
++ if (test_bit(index, priv->utmi_pad_enabled)) {
++ mutex_unlock(&padctl->lock);
++ return;
++ }
++
+ port = tegra_xusb_find_usb2_port(padctl, index);
+ if (!port) {
+ dev_err(dev, "no port found for USB2 lane %u\n", index);
++ mutex_unlock(&padctl->lock);
+ return;
+ }
+
+@@ -724,18 +720,28 @@ static void tegra186_utmi_pad_power_on(s
+ value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));
+ value &= ~USB2_OTG_PD_DR;
+ padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));
++
++ set_bit(index, priv->utmi_pad_enabled);
++ mutex_unlock(&padctl->lock);
+ }
+
+ static void tegra186_utmi_pad_power_down(struct phy *phy)
+ {
+ struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
+ struct tegra_xusb_padctl *padctl = lane->pad->padctl;
++ struct tegra186_xusb_padctl *priv = to_tegra186_xusb_padctl(padctl);
+ unsigned int index = lane->index;
+ u32 value;
+
+ if (!phy)
+ return;
+
++ mutex_lock(&padctl->lock);
++ if (!test_bit(index, priv->utmi_pad_enabled)) {
++ mutex_unlock(&padctl->lock);
++ return;
++ }
++
+ dev_dbg(padctl->dev, "power down UTMI pad %u\n", index);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index));
+@@ -748,7 +754,11 @@ static void tegra186_utmi_pad_power_down
+
+ udelay(2);
+
++ clear_bit(index, priv->utmi_pad_enabled);
++
+ tegra186_utmi_bias_pad_power_off(padctl);
++
++ mutex_unlock(&padctl->lock);
+ }
+
+ static int tegra186_xusb_padctl_vbus_override(struct tegra_xusb_padctl *padctl,
--- /dev/null
+From 1d6c39c89f617c9fec6bbae166e25b16a014f7c8 Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <rostedt@goodmis.org>
+Date: Tue, 13 May 2025 11:50:32 -0400
+Subject: ring-buffer: Fix persistent buffer when commit page is the reader page
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+commit 1d6c39c89f617c9fec6bbae166e25b16a014f7c8 upstream.
+
+The ring buffer is made up of sub buffers (sometimes called pages as they
+are by default PAGE_SIZE). It has the following "pages":
+
+ "tail page" - this is the page that the next write will write to
+ "head page" - this is the page that the reader will swap the reader page with.
+ "reader page" - This belongs to the reader, where it will swap the head
+ page from the ring buffer so that the reader does not
+ race with the writer.
+
+The writer may end up on the "reader page" if the ring buffer hasn't
+written more than one page, where the "tail page" and the "head page" are
+the same.
+
+The persistent ring buffer has meta data that points to where these pages
+exist so on reboot it can re-create the pointers to the cpu_buffer
+descriptor. But when the commit page is on the reader page, the logic is
+incorrect.
+
+The check to see if the commit page is on the reader page checked if the
+head page was the reader page, which would never happen, as the head page
+is always in the ring buffer. The correct check would be to test if the
+commit page is on the reader page. If that's the case, then it can exit
+out early as the commit page is only on the reader page when there's only
+one page of data in the buffer. There's no reason to iterate the ring
+buffer pages to find the "commit page" as it is already found.
+
+To trigger this bug:
+
+ # echo 1 > /sys/kernel/tracing/instances/boot_mapped/events/syscalls/sys_enter_fchownat/enable
+ # touch /tmp/x
+ # chown sshd /tmp/x
+ # reboot
+
+On boot up, the dmesg will have:
+ Ring buffer meta [0] is from previous boot!
+ Ring buffer meta [1] is from previous boot!
+ Ring buffer meta [2] is from previous boot!
+ Ring buffer meta [3] is from previous boot!
+ Ring buffer meta [4] commit page not found
+ Ring buffer meta [5] is from previous boot!
+ Ring buffer meta [6] is from previous boot!
+ Ring buffer meta [7] is from previous boot!
+
+Where the buffer on CPU 4 had a "commit page not found" error and that
+buffer is cleared and reset causing the output to be empty and the data lost.
+
+When it works correctly, it has:
+
+ # cat /sys/kernel/tracing/instances/boot_mapped/trace_pipe
+ <...>-1137 [004] ..... 998.205323: sys_enter_fchownat: __syscall_nr=0x104 (260) dfd=0xffffff9c (4294967196) filename=(0xffffc90000a0002c) user=0x3e8 (1000) group=0xffffffff (4294967295) flag=0x0 (0
+
+Cc: stable@vger.kernel.org
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Link: https://lore.kernel.org/20250513115032.3e0b97f7@gandalf.local.home
+Fixes: 5f3b6e839f3ce ("ring-buffer: Validate boot range memory events")
+Reported-by: Tasos Sahanidis <tasos@tasossah.com>
+Tested-by: Tasos Sahanidis <tasos@tasossah.com>
+Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/ring_buffer.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -1832,10 +1832,12 @@ static void rb_meta_validate_events(stru
+
+ head_page = cpu_buffer->head_page;
+
+- /* If both the head and commit are on the reader_page then we are done. */
+- if (head_page == cpu_buffer->reader_page &&
+- head_page == cpu_buffer->commit_page)
++ /* If the commit_buffer is the reader page, update the commit page */
++ if (meta->commit_buffer == (unsigned long)cpu_buffer->reader_page->page) {
++ cpu_buffer->commit_page = cpu_buffer->reader_page;
++ /* Nothing more to do, the only page is the reader page */
+ goto done;
++ }
+
+ /* Iterate until finding the commit page */
+ for (i = 0; i < meta->nr_subbufs + 1; i++, rb_inc_page(&head_page)) {
--- /dev/null
+From e8007fad5457ea547ca63bb011fdb03213571c7e Mon Sep 17 00:00:00 2001
+From: Steve Siwinski <ssiwinski@atto.com>
+Date: Thu, 8 May 2025 16:01:22 -0400
+Subject: scsi: sd_zbc: block: Respect bio vector limits for REPORT ZONES buffer
+
+From: Steve Siwinski <ssiwinski@atto.com>
+
+commit e8007fad5457ea547ca63bb011fdb03213571c7e upstream.
+
+The REPORT ZONES buffer size is currently limited by the HBA's maximum
+segment count to ensure the buffer can be mapped. However, the block
+layer further limits the number of iovec entries to 1024 when allocating
+a bio.
+
+To avoid allocation of buffers too large to be mapped, further restrict
+the maximum buffer size to BIO_MAX_INLINE_VECS.
+
+Replace the UIO_MAXIOV symbolic name with the more contextually
+appropriate BIO_MAX_INLINE_VECS.
+
+Fixes: b091ac616846 ("sd_zbc: Fix report zones buffer allocation")
+Cc: stable@vger.kernel.org
+Signed-off-by: Steve Siwinski <ssiwinski@atto.com>
+Link: https://lore.kernel.org/r/20250508200122.243129-1-ssiwinski@atto.com
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ block/bio.c | 2 +-
+ drivers/scsi/sd_zbc.c | 6 +++++-
+ include/linux/bio.h | 1 +
+ 3 files changed, 7 insertions(+), 2 deletions(-)
+
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -611,7 +611,7 @@ struct bio *bio_kmalloc(unsigned short n
+ {
+ struct bio *bio;
+
+- if (nr_vecs > UIO_MAXIOV)
++ if (nr_vecs > BIO_MAX_INLINE_VECS)
+ return NULL;
+ return kmalloc(struct_size(bio, bi_inline_vecs, nr_vecs), gfp_mask);
+ }
+--- a/drivers/scsi/sd_zbc.c
++++ b/drivers/scsi/sd_zbc.c
+@@ -169,6 +169,7 @@ static void *sd_zbc_alloc_report_buffer(
+ unsigned int nr_zones, size_t *buflen)
+ {
+ struct request_queue *q = sdkp->disk->queue;
++ unsigned int max_segments;
+ size_t bufsize;
+ void *buf;
+
+@@ -180,12 +181,15 @@ static void *sd_zbc_alloc_report_buffer(
+ * Furthermore, since the report zone command cannot be split, make
+ * sure that the allocated buffer can always be mapped by limiting the
+ * number of pages allocated to the HBA max segments limit.
++ * Since max segments can be larger than the max inline bio vectors,
++ * further limit the allocated buffer to BIO_MAX_INLINE_VECS.
+ */
+ nr_zones = min(nr_zones, sdkp->zone_info.nr_zones);
+ bufsize = roundup((nr_zones + 1) * 64, SECTOR_SIZE);
+ bufsize = min_t(size_t, bufsize,
+ queue_max_hw_sectors(q) << SECTOR_SHIFT);
+- bufsize = min_t(size_t, bufsize, queue_max_segments(q) << PAGE_SHIFT);
++ max_segments = min(BIO_MAX_INLINE_VECS, queue_max_segments(q));
++ bufsize = min_t(size_t, bufsize, max_segments << PAGE_SHIFT);
+
+ while (bufsize >= SECTOR_SIZE) {
+ buf = kvzalloc(bufsize, GFP_KERNEL | __GFP_NORETRY);
+--- a/include/linux/bio.h
++++ b/include/linux/bio.h
+@@ -11,6 +11,7 @@
+ #include <linux/uio.h>
+
+ #define BIO_MAX_VECS 256U
++#define BIO_MAX_INLINE_VECS UIO_MAXIOV
+
+ struct queue_limits;
+
maintainers-update-alexey-makhalov-s-email-address.patch
gpio-pca953x-fix-irq-storm-on-system-wake-up.patch
acpi-pptt-fix-processor-subtable-walk.patch
+alsa-es1968-add-error-handling-for-snd_pcm_hw_constraint_pow2.patch
+alsa-usb-audio-add-sample-rate-quirk-for-audioengine-d1.patch
+alsa-usb-audio-add-sample-rate-quirk-for-microdia-jp001-usb-camera.patch
+dma-buf-insert-memory-barrier-before-updating-num_fences.patch
+hv_netvsc-use-vmbus_sendpacket_mpb_desc-to-send-vmbus-messages.patch
+hv_netvsc-preserve-contiguous-pfn-grouping-in-the-page-buffer-array.patch
+hv_netvsc-remove-rmsg_pgcnt.patch
+arm64-dts-amlogic-dreambox-fix-missing-clkc_audio-node.patch
+arm64-dts-rockchip-remove-overdrive-mode-opps-from-rk3588j-soc-dtsi.patch
+drivers-hv-allow-vmbus_sendpacket_mpb_desc-to-create-multiple-ranges.patch
+drivers-hv-vmbus-remove-vmbus_sendpacket_pagebuffer.patch
+kbuild-disable-wdefault-const-init-unsafe.patch
+ftrace-fix-preemption-accounting-for-stacktrace-trigger-command.patch
+ftrace-fix-preemption-accounting-for-stacktrace-filter-command.patch
+tracing-samples-initialize-trace_array_printk-with-the-correct-function.patch
+phy-tegra-xusb-use-a-bitmask-for-utmi-pad-power-state-tracking.patch
+phy-fix-error-handling-in-tegra_xusb_port_init.patch
+phy-renesas-rcar-gen3-usb2-fix-role-detection-on-unbind-bind.patch
+phy-renesas-rcar-gen3-usb2-set-timing-registers-only-once.patch
+scsi-sd_zbc-block-respect-bio-vector-limits-for-report-zones-buffer.patch
+smb-client-fix-memory-leak-during-error-handling-for-posix-mkdir.patch
+spi-tegra114-use-value-to-check-for-invalid-delays.patch
+tpm-mask-tpm-rc-in-tpm2_start_auth_session.patch
+wifi-mt76-disable-napi-on-driver-removal.patch
+ring-buffer-fix-persistent-buffer-when-commit-page-is-the-reader-page.patch
+net-qede-initialize-qede_ll_ops-with-designated-initializer.patch
+mm-userfaultfd-correct-dirty-flags-set-for-both-present-and-swap-pte.patch
+dmaengine-ti-k3-udma-add-missing-locking.patch
+dmaengine-ti-k3-udma-use-cap_mask-directly-from-dma_device-structure-instead-of-a-local-copy.patch
+dmaengine-idxd-fix-memory-leak-in-error-handling-path-of-idxd_setup_wqs.patch
+dmaengine-idxd-fix-memory-leak-in-error-handling-path-of-idxd_setup_engines.patch
+dmaengine-idxd-fix-memory-leak-in-error-handling-path-of-idxd_setup_groups.patch
+dmaengine-idxd-add-missing-cleanup-for-early-error-out-in-idxd_setup_internals.patch
+dmaengine-idxd-add-missing-cleanups-in-cleanup-internals.patch
+dmaengine-idxd-add-missing-idxd-cleanup-to-fix-memory-leak-in-remove-call.patch
+dmaengine-idxd-fix-memory-leak-in-error-handling-path-of-idxd_alloc.patch
+dmaengine-idxd-fix-memory-leak-in-error-handling-path-of-idxd_pci_probe.patch
+dmaengine-idxd-refactor-remove-call-with-idxd_cleanup-helper.patch
--- /dev/null
+From 1fe4a44b7fa3955bcb7b4067c07b778fe90d8ee7 Mon Sep 17 00:00:00 2001
+From: Jethro Donaldson <devel@jro.nz>
+Date: Thu, 15 May 2025 01:23:23 +1200
+Subject: smb: client: fix memory leak during error handling for POSIX mkdir
+
+From: Jethro Donaldson <devel@jro.nz>
+
+commit 1fe4a44b7fa3955bcb7b4067c07b778fe90d8ee7 upstream.
+
+The response buffer for the CREATE request handled by smb311_posix_mkdir()
+is leaked on the error path (goto err_free_rsp_buf) because the structure
+pointer *rsp passed to free_rsp_buf() is not assigned until *after* the
+error condition is checked.
+
+As *rsp is initialised to NULL, free_rsp_buf() becomes a no-op and the leak
+is instead reported by __kmem_cache_shutdown() upon subsequent rmmod of
+cifs.ko if (and only if) the error path has been hit.
+
+Pass rsp_iov.iov_base to free_rsp_buf() instead, similar to the code in
+other functions in smb2pdu.c for which *rsp is assigned late.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Jethro Donaldson <devel@jro.nz>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/smb2pdu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/smb/client/smb2pdu.c
++++ b/fs/smb/client/smb2pdu.c
+@@ -2985,7 +2985,7 @@ replay_again:
+ /* Eventually save off posix specific response info and timestamps */
+
+ err_free_rsp_buf:
+- free_rsp_buf(resp_buftype, rsp);
++ free_rsp_buf(resp_buftype, rsp_iov.iov_base);
+ kfree(pc_buf);
+ err_free_req:
+ cifs_small_buf_release(req);
--- /dev/null
+From e979a7c79fbc706f6dac913af379ef4caa04d3d5 Mon Sep 17 00:00:00 2001
+From: Aaron Kling <webgeek1234@gmail.com>
+Date: Tue, 6 May 2025 13:36:59 -0500
+Subject: spi: tegra114: Use value to check for invalid delays
+
+From: Aaron Kling <webgeek1234@gmail.com>
+
+commit e979a7c79fbc706f6dac913af379ef4caa04d3d5 upstream.
+
+A delay unit of 0 is a valid entry, thus it is not valid to check for
+unused delays. Instead, check the value field; if that is zero, the
+given delay is unset.
+
+Fixes: 4426e6b4ecf6 ("spi: tegra114: Don't fail set_cs_timing when delays are zero")
+Cc: stable@vger.kernel.org
+Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
+Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
+Link: https://patch.msgid.link/20250506-spi-tegra114-fixup-v1-1-136dc2f732f3@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-tegra114.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/spi/spi-tegra114.c
++++ b/drivers/spi/spi-tegra114.c
+@@ -728,9 +728,9 @@ static int tegra_spi_set_hw_cs_timing(st
+ u32 inactive_cycles;
+ u8 cs_state;
+
+- if ((setup->unit && setup->unit != SPI_DELAY_UNIT_SCK) ||
+- (hold->unit && hold->unit != SPI_DELAY_UNIT_SCK) ||
+- (inactive->unit && inactive->unit != SPI_DELAY_UNIT_SCK)) {
++ if ((setup->value && setup->unit != SPI_DELAY_UNIT_SCK) ||
++ (hold->value && hold->unit != SPI_DELAY_UNIT_SCK) ||
++ (inactive->value && inactive->unit != SPI_DELAY_UNIT_SCK)) {
+ dev_err(&spi->dev,
+ "Invalid delay unit %d, should be SPI_DELAY_UNIT_SCK\n",
+ SPI_DELAY_UNIT_SCK);
--- /dev/null
+From 539fbab37881e32ba6a708a100de6db19e1e7e7d Mon Sep 17 00:00:00 2001
+From: Jarkko Sakkinen <jarkko@kernel.org>
+Date: Mon, 7 Apr 2025 15:28:05 +0300
+Subject: tpm: Mask TPM RC in tpm2_start_auth_session()
+
+From: Jarkko Sakkinen <jarkko@kernel.org>
+
+commit 539fbab37881e32ba6a708a100de6db19e1e7e7d upstream.
+
+tpm2_start_auth_session() does not mask TPM RC correctly from the callers:
+
+[ 28.766528] tpm tpm0: A TPM error (2307) occurred start auth session
+
+Process TPM RCs inside tpm2_start_auth_session(), and map them to POSIX
+error codes.
+
+Cc: stable@vger.kernel.org # v6.10+
+Fixes: 699e3efd6c64 ("tpm: Add HMAC session start and end functions")
+Reported-by: Herbert Xu <herbert@gondor.apana.org.au>
+Closes: https://lore.kernel.org/linux-integrity/Z_NgdRHuTKP6JK--@gondor.apana.org.au/
+Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/tpm/tpm2-sessions.c | 20 ++++++--------------
+ include/linux/tpm.h | 19 +++++++++++++++++++
+ 2 files changed, 25 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessions.c
+index 3f89635ba5e8..7b5049b3d476 100644
+--- a/drivers/char/tpm/tpm2-sessions.c
++++ b/drivers/char/tpm/tpm2-sessions.c
+@@ -40,11 +40,6 @@
+ *
+ * These are the usage functions:
+ *
+- * tpm2_start_auth_session() which allocates the opaque auth structure
+- * and gets a session from the TPM. This must be called before
+- * any of the following functions. The session is protected by a
+- * session_key which is derived from a random salt value
+- * encrypted to the NULL seed.
+ * tpm2_end_auth_session() kills the session and frees the resources.
+ * Under normal operation this function is done by
+ * tpm_buf_check_hmac_response(), so this is only to be used on
+@@ -963,16 +958,13 @@ static int tpm2_load_null(struct tpm_chip *chip, u32 *null_key)
+ }
+
+ /**
+- * tpm2_start_auth_session() - create a HMAC authentication session with the TPM
+- * @chip: the TPM chip structure to create the session with
++ * tpm2_start_auth_session() - Create an a HMAC authentication session
++ * @chip: A TPM chip
+ *
+- * This function loads the NULL seed from its saved context and starts
+- * an authentication session on the null seed, fills in the
+- * @chip->auth structure to contain all the session details necessary
+- * for performing the HMAC, encrypt and decrypt operations and
+- * returns. The NULL seed is flushed before this function returns.
++ * Loads the ephemeral key (null seed), and starts an HMAC authenticated
++ * session. The null seed is flushed before the return.
+ *
+- * Return: zero on success or actual error encountered.
++ * Returns zero on success, or a POSIX error code.
+ */
+ int tpm2_start_auth_session(struct tpm_chip *chip)
+ {
+@@ -1024,7 +1016,7 @@ int tpm2_start_auth_session(struct tpm_chip *chip)
+ /* hash algorithm for session */
+ tpm_buf_append_u16(&buf, TPM_ALG_SHA256);
+
+- rc = tpm_transmit_cmd(chip, &buf, 0, "start auth session");
++ rc = tpm_ret_to_err(tpm_transmit_cmd(chip, &buf, 0, "StartAuthSession"));
+ tpm2_flush_context(chip, null_key);
+
+ if (rc == TPM2_RC_SUCCESS)
+diff --git a/include/linux/tpm.h b/include/linux/tpm.h
+index 6c3125300c00..9ac9768cc8f7 100644
+--- a/include/linux/tpm.h
++++ b/include/linux/tpm.h
+@@ -257,6 +257,7 @@ enum tpm2_return_codes {
+ TPM2_RC_TESTING = 0x090A, /* RC_WARN */
+ TPM2_RC_REFERENCE_H0 = 0x0910,
+ TPM2_RC_RETRY = 0x0922,
++ TPM2_RC_SESSION_MEMORY = 0x0903,
+ };
+
+ enum tpm2_command_codes {
+@@ -437,6 +438,24 @@ static inline u32 tpm2_rc_value(u32 rc)
+ return (rc & BIT(7)) ? rc & 0xbf : rc;
+ }
+
++/*
++ * Convert a return value from tpm_transmit_cmd() to POSIX error code.
++ */
++static inline ssize_t tpm_ret_to_err(ssize_t ret)
++{
++ if (ret < 0)
++ return ret;
++
++ switch (tpm2_rc_value(ret)) {
++ case TPM2_RC_SUCCESS:
++ return 0;
++ case TPM2_RC_SESSION_MEMORY:
++ return -ENOMEM;
++ default:
++ return -EFAULT;
++ }
++}
++
+ #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE)
+
+ extern int tpm_is_tpm2(struct tpm_chip *chip);
+--
+2.49.0
+
--- /dev/null
+From 1b0c192c92ea1fe2dcb178f84adf15fe37c3e7c8 Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <rostedt@goodmis.org>
+Date: Fri, 9 May 2025 15:26:57 -0400
+Subject: tracing: samples: Initialize trace_array_printk() with the correct function
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+commit 1b0c192c92ea1fe2dcb178f84adf15fe37c3e7c8 upstream.
+
+When using trace_array_printk() on a created instance, the correct
+function to use to initialize it is:
+
+ trace_array_init_printk()
+
+Not
+
+ trace_printk_init_buffer()
+
+The former is a proper function to use, the latter is for initializing
+trace_printk() and causes the NOTICE banner to be displayed.
+
+Cc: stable@vger.kernel.org
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Divya Indi <divya.indi@oracle.com>
+Link: https://lore.kernel.org/20250509152657.0f6744d9@gandalf.local.home
+Fixes: 89ed42495ef4a ("tracing: Sample module to demonstrate kernel access to Ftrace instances.")
+Fixes: 38ce2a9e33db6 ("tracing: Add trace_array_init_printk() to initialize instance trace_printk() buffers")
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ samples/ftrace/sample-trace-array.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/samples/ftrace/sample-trace-array.c
++++ b/samples/ftrace/sample-trace-array.c
+@@ -112,7 +112,7 @@ static int __init sample_trace_array_ini
+ /*
+ * If context specific per-cpu buffers havent already been allocated.
+ */
+- trace_printk_init_buffers();
++ trace_array_init_printk(tr);
+
+ simple_tsk = kthread_run(simple_thread, NULL, "sample-instance");
+ if (IS_ERR(simple_tsk)) {
--- /dev/null
+From 78ab4be549533432d97ea8989d2f00b508fa68d8 Mon Sep 17 00:00:00 2001
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+Date: Tue, 6 May 2025 14:55:39 +0300
+Subject: wifi: mt76: disable napi on driver removal
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+commit 78ab4be549533432d97ea8989d2f00b508fa68d8 upstream.
+
+A warning on driver removal started occurring after commit 9dd05df8403b
+("net: warn if NAPI instance wasn't shut down"). Disable tx napi before
+deleting it in mt76_dma_cleanup().
+
+ WARNING: CPU: 4 PID: 18828 at net/core/dev.c:7288 __netif_napi_del_locked+0xf0/0x100
+ CPU: 4 UID: 0 PID: 18828 Comm: modprobe Not tainted 6.15.0-rc4 #4 PREEMPT(lazy)
+ Hardware name: ASUS System Product Name/PRIME X670E-PRO WIFI, BIOS 3035 09/05/2024
+ RIP: 0010:__netif_napi_del_locked+0xf0/0x100
+ Call Trace:
+ <TASK>
+ mt76_dma_cleanup+0x54/0x2f0 [mt76]
+ mt7921_pci_remove+0xd5/0x190 [mt7921e]
+ pci_device_remove+0x47/0xc0
+ device_release_driver_internal+0x19e/0x200
+ driver_detach+0x48/0x90
+ bus_remove_driver+0x6d/0xf0
+ pci_unregister_driver+0x2e/0xb0
+ __do_sys_delete_module.isra.0+0x197/0x2e0
+ do_syscall_64+0x7b/0x160
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Tested with mt7921e but the same pattern can be actually applied to other
+mt76 drivers calling mt76_dma_cleanup() during removal. Tx napi is enabled
+in their *_dma_init() functions and only toggled off and on again inside
+their suspend/resume/reset paths. So it should be okay to disable tx
+napi in such a generic way.
+
+Found by Linux Verification Center (linuxtesting.org).
+
+Fixes: 2ac515a5d74f ("mt76: mt76x02: use napi polling for tx cleanup")
+Cc: stable@vger.kernel.org
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Tested-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
+Link: https://patch.msgid.link/20250506115540.19045-1-pchelkin@ispras.ru
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/mediatek/mt76/dma.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/wireless/mediatek/mt76/dma.c
++++ b/drivers/net/wireless/mediatek/mt76/dma.c
+@@ -999,6 +999,7 @@ void mt76_dma_cleanup(struct mt76_dev *d
+ int i;
+
+ mt76_worker_disable(&dev->tx_worker);
++ napi_disable(&dev->tx_napi);
+ netif_napi_del(&dev->tx_napi);
+
+ for (i = 0; i < ARRAY_SIZE(dev->phys); i++) {