]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.6
authorSasha Levin <sashal@kernel.org>
Fri, 21 Feb 2025 16:51:11 +0000 (11:51 -0500)
committerSasha Levin <sashal@kernel.org>
Fri, 21 Feb 2025 16:51:11 +0000 (11:51 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
67 files changed:
queue-6.6/alsa-hda-cirrus-correct-the-full-scale-volume-set-lo.patch [new file with mode: 0644]
queue-6.6/alsa-hda-realtek-fixup-alc225-depop-procedure.patch [new file with mode: 0644]
queue-6.6/alsa-seq-drop-ump-events-when-no-ump-conversion-is-s.patch [new file with mode: 0644]
queue-6.6/arm64-dts-mediatek-mt8183-disable-dsi-display-output.patch [new file with mode: 0644]
queue-6.6/arm64-dts-mediatek-mt8183-pumpkin-add-hdmi-support.patch [new file with mode: 0644]
queue-6.6/arm64-dts-qcom-sm8450-add-missing-qcom-non-secure-do.patch [new file with mode: 0644]
queue-6.6/arm64-dts-qcom-sm8450-fix-adsp-memory-base-and-lengt.patch [new file with mode: 0644]
queue-6.6/arm64-dts-qcom-sm8550-add-dma-coherent-property.patch [new file with mode: 0644]
queue-6.6/arm64-dts-qcom-sm8550-add-missing-qcom-non-secure-do.patch [new file with mode: 0644]
queue-6.6/arm64-dts-qcom-sm8550-fix-adsp-memory-base-and-lengt.patch [new file with mode: 0644]
queue-6.6/arp-switch-to-dev_getbyhwaddr-in-arp_req_set_public.patch [new file with mode: 0644]
queue-6.6/asoc-renesas-rz-ssi-add-a-check-for-negative-sample_.patch [new file with mode: 0644]
queue-6.6/asoc-rockchip-i2s-tdm-fix-shift-config-for-snd_soc_d.patch [new file with mode: 0644]
queue-6.6/bluetooth-qca-fix-poor-rf-performance-for-wcn6855.patch [new file with mode: 0644]
queue-6.6/bluetooth-qca-support-downloading-board-id-specific-.patch [new file with mode: 0644]
queue-6.6/bluetooth-qca-update-firmware-name-to-support-board-.patch [new file with mode: 0644]
queue-6.6/cpufreq-dt-platdev-add-missing-module_description-ma.patch [new file with mode: 0644]
queue-6.6/cpufreq-fix-using-cpufreq-dt-as-module.patch [new file with mode: 0644]
queue-6.6/firmware-qcom-scm-fix-missing-read-barrier-in-qcom_s.patch [new file with mode: 0644]
queue-6.6/flow_dissector-fix-handling-of-mixed-port-and-port-r.patch [new file with mode: 0644]
queue-6.6/flow_dissector-fix-port-range-key-handling-in-bpf-co.patch [new file with mode: 0644]
queue-6.6/geneve-fix-use-after-free-in-geneve_find_dev.patch [new file with mode: 0644]
queue-6.6/geneve-suppress-list-corruption-splat-in-geneve_dest.patch [new file with mode: 0644]
queue-6.6/gtp-suppress-list-corruption-splat-in-gtp_net_exit_b.patch [new file with mode: 0644]
queue-6.6/ibmvnic-add-stat-for-tx-direct-vs-tx-batched.patch [new file with mode: 0644]
queue-6.6/ibmvnic-don-t-reference-skb-after-sending-to-vios.patch [new file with mode: 0644]
queue-6.6/ibmvnic-introduce-send-sub-crq-direct.patch [new file with mode: 0644]
queue-6.6/ibmvnic-return-error-code-on-tx-scrq-flush-fail.patch [new file with mode: 0644]
queue-6.6/input-serio-define-serio_pause_rx-guard-to-pause-and.patch [new file with mode: 0644]
queue-6.6/input-synaptics-fix-crash-when-enabling-pass-through.patch [new file with mode: 0644]
queue-6.6/md-factor-out-a-helper-from-mddev_put.patch [new file with mode: 0644]
queue-6.6/md-md-bitmap-add-sync_size-into-struct-md_bitmap_sta.patch [new file with mode: 0644]
queue-6.6/md-md-bitmap-replace-md_bitmap_status-with-a-new-hel.patch [new file with mode: 0644]
queue-6.6/md-md-bitmap-synchronize-bitmap_get_stats-with-bitma.patch [new file with mode: 0644]
queue-6.6/md-md-cluster-fix-spares-warnings-for-__le64.patch [new file with mode: 0644]
queue-6.6/md-simplify-md_seq_ops.patch [new file with mode: 0644]
queue-6.6/md-use-separate-work_struct-for-md_start_sync.patch [new file with mode: 0644]
queue-6.6/media-uvcvideo-only-save-async-fh-if-success.patch [new file with mode: 0644]
queue-6.6/media-uvcvideo-refactor-iterators.patch [new file with mode: 0644]
queue-6.6/media-uvcvideo-remove-dangling-pointers.patch [new file with mode: 0644]
queue-6.6/memcg-fix-soft-lockup-in-the-oom-process.patch [new file with mode: 0644]
queue-6.6/mm-update-mark_victim-tracepoints-fields.patch [new file with mode: 0644]
queue-6.6/net-add-non-rcu-dev_getbyhwaddr-helper.patch [new file with mode: 0644]
queue-6.6/net-axienet-set-mac_managed_pm.patch [new file with mode: 0644]
queue-6.6/net-sched-cls_api-fix-error-handling-causing-null-de.patch [new file with mode: 0644]
queue-6.6/nvmem-create-a-header-for-internal-sharing.patch [new file with mode: 0644]
queue-6.6/nvmem-imx-ocotp-ele-fix-mac-address-byte-order.patch [new file with mode: 0644]
queue-6.6/nvmem-move-and-rename-fixup_cell_info.patch [new file with mode: 0644]
queue-6.6/nvmem-simplify-the-add_cells-hook.patch [new file with mode: 0644]
queue-6.6/powerpc-64s-mm-move-__real_pte-stubs-into-hash-4k.h.patch [new file with mode: 0644]
queue-6.6/powerpc-64s-rewrite-__real_pte-and-__rpte_to_hidx-as.patch [new file with mode: 0644]
queue-6.6/powerpc-code-patching-fix-kasan-hit-by-not-flagging-.patch [new file with mode: 0644]
queue-6.6/s390-ism-add-release-function-for-struct-device.patch [new file with mode: 0644]
queue-6.6/scsi-core-do-not-retry-i-os-during-depopulation.patch [new file with mode: 0644]
queue-6.6/scsi-core-handle-depopulation-and-restoration-in-pro.patch [new file with mode: 0644]
queue-6.6/series
queue-6.6/soc-mediatek-mtk-devapc-convert-to-platform-remove-c.patch [new file with mode: 0644]
queue-6.6/soc-mediatek-mtk-devapc-fix-leaking-io-map-on-driver.patch [new file with mode: 0644]
queue-6.6/sockmap-vsock-for-connectible-sockets-allow-only-con.patch [new file with mode: 0644]
queue-6.6/tcp-adjust-rcvq_space-after-updating-scaling-ratio.patch [new file with mode: 0644]
queue-6.6/tcp-drop-secpath-at-the-same-time-as-we-currently-dr.patch [new file with mode: 0644]
queue-6.6/usb-gadget-core-create-sysfs-link-between-udc-and-ga.patch [new file with mode: 0644]
queue-6.6/usb-gadget-core-flush-gadget-workqueue-after-device-.patch [new file with mode: 0644]
queue-6.6/usb-gadget-f_midi-f_midi_complete-to-call-queue_work.patch [new file with mode: 0644]
queue-6.6/vsock-bpf-warn-on-socket-without-transport.patch [new file with mode: 0644]
queue-6.6/xfs-don-t-over-report-free-space-or-inodes-in-statvf.patch [new file with mode: 0644]
queue-6.6/xfs-report-realtime-block-quota-limits-on-realtime-d.patch [new file with mode: 0644]

diff --git a/queue-6.6/alsa-hda-cirrus-correct-the-full-scale-volume-set-lo.patch b/queue-6.6/alsa-hda-cirrus-correct-the-full-scale-volume-set-lo.patch
new file mode 100644 (file)
index 0000000..78950b7
--- /dev/null
@@ -0,0 +1,121 @@
+From 8fe5f5b2970a8e609c98c29dc2122f5faa951f5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Feb 2025 21:07:28 +0000
+Subject: ALSA: hda/cirrus: Correct the full scale volume set logic
+
+From: Vitaly Rodionov <vitalyr@opensource.cirrus.com>
+
+[ Upstream commit 08b613b9e2ba431db3bd15cb68ca72472a50ef5c ]
+
+This patch corrects the full-scale volume setting logic. On certain
+platforms, the full-scale volume bit is required. The current logic
+mistakenly sets this bit and incorrectly clears reserved bit 0, causing
+the headphone output to be muted.
+
+Fixes: 342b6b610ae2 ("ALSA: hda/cs8409: Fix Full Scale Volume setting for all variants")
+Signed-off-by: Vitaly Rodionov <vitalyr@opensource.cirrus.com>
+Link: https://patch.msgid.link/20250214210736.30814-1-vitalyr@opensource.cirrus.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_cs8409-tables.c |  6 +++---
+ sound/pci/hda/patch_cs8409.c        | 20 +++++++++++---------
+ sound/pci/hda/patch_cs8409.h        |  5 +++--
+ 3 files changed, 17 insertions(+), 14 deletions(-)
+
+diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c
+index 759f48038273d..621f947e38174 100644
+--- a/sound/pci/hda/patch_cs8409-tables.c
++++ b/sound/pci/hda/patch_cs8409-tables.c
+@@ -121,7 +121,7 @@ static const struct cs8409_i2c_param cs42l42_init_reg_seq[] = {
+       { CS42L42_MIXER_CHA_VOL, 0x3F },
+       { CS42L42_MIXER_CHB_VOL, 0x3F },
+       { CS42L42_MIXER_ADC_VOL, 0x3f },
+-      { CS42L42_HP_CTL, 0x03 },
++      { CS42L42_HP_CTL, 0x0D },
+       { CS42L42_MIC_DET_CTL1, 0xB6 },
+       { CS42L42_TIPSENSE_CTL, 0xC2 },
+       { CS42L42_HS_CLAMP_DISABLE, 0x01 },
+@@ -315,7 +315,7 @@ static const struct cs8409_i2c_param dolphin_c0_init_reg_seq[] = {
+       { CS42L42_ASP_TX_SZ_EN, 0x01 },
+       { CS42L42_PWR_CTL1, 0x0A },
+       { CS42L42_PWR_CTL2, 0x84 },
+-      { CS42L42_HP_CTL, 0x03 },
++      { CS42L42_HP_CTL, 0x0D },
+       { CS42L42_MIXER_CHA_VOL, 0x3F },
+       { CS42L42_MIXER_CHB_VOL, 0x3F },
+       { CS42L42_MIXER_ADC_VOL, 0x3f },
+@@ -371,7 +371,7 @@ static const struct cs8409_i2c_param dolphin_c1_init_reg_seq[] = {
+       { CS42L42_ASP_TX_SZ_EN, 0x00 },
+       { CS42L42_PWR_CTL1, 0x0E },
+       { CS42L42_PWR_CTL2, 0x84 },
+-      { CS42L42_HP_CTL, 0x01 },
++      { CS42L42_HP_CTL, 0x0D },
+       { CS42L42_MIXER_CHA_VOL, 0x3F },
+       { CS42L42_MIXER_CHB_VOL, 0x3F },
+       { CS42L42_MIXER_ADC_VOL, 0x3f },
+diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c
+index 892223d9e64ab..b003ac1990ba8 100644
+--- a/sound/pci/hda/patch_cs8409.c
++++ b/sound/pci/hda/patch_cs8409.c
+@@ -876,7 +876,7 @@ static void cs42l42_resume(struct sub_codec *cs42l42)
+               { CS42L42_DET_INT_STATUS2, 0x00 },
+               { CS42L42_TSRS_PLUG_STATUS, 0x00 },
+       };
+-      int fsv_old, fsv_new;
++      unsigned int fsv;
+       /* Bring CS42L42 out of Reset */
+       spec->gpio_data = snd_hda_codec_read(codec, CS8409_PIN_AFG, 0, AC_VERB_GET_GPIO_DATA, 0);
+@@ -893,13 +893,15 @@ static void cs42l42_resume(struct sub_codec *cs42l42)
+       /* Clear interrupts, by reading interrupt status registers */
+       cs8409_i2c_bulk_read(cs42l42, irq_regs, ARRAY_SIZE(irq_regs));
+-      fsv_old = cs8409_i2c_read(cs42l42, CS42L42_HP_CTL);
+-      if (cs42l42->full_scale_vol == CS42L42_FULL_SCALE_VOL_0DB)
+-              fsv_new = fsv_old & ~CS42L42_FULL_SCALE_VOL_MASK;
+-      else
+-              fsv_new = fsv_old & CS42L42_FULL_SCALE_VOL_MASK;
+-      if (fsv_new != fsv_old)
+-              cs8409_i2c_write(cs42l42, CS42L42_HP_CTL, fsv_new);
++      fsv = cs8409_i2c_read(cs42l42, CS42L42_HP_CTL);
++      if (cs42l42->full_scale_vol) {
++              // Set the full scale volume bit
++              fsv |= CS42L42_FULL_SCALE_VOL_MASK;
++              cs8409_i2c_write(cs42l42, CS42L42_HP_CTL, fsv);
++      }
++      // Unmute analog channels A and B
++      fsv = (fsv & ~CS42L42_ANA_MUTE_AB);
++      cs8409_i2c_write(cs42l42, CS42L42_HP_CTL, fsv);
+       /* we have to explicitly allow unsol event handling even during the
+        * resume phase so that the jack event is processed properly
+@@ -921,7 +923,7 @@ static void cs42l42_suspend(struct sub_codec *cs42l42)
+               { CS42L42_MIXER_CHA_VOL, 0x3F },
+               { CS42L42_MIXER_ADC_VOL, 0x3F },
+               { CS42L42_MIXER_CHB_VOL, 0x3F },
+-              { CS42L42_HP_CTL, 0x0F },
++              { CS42L42_HP_CTL, 0x0D },
+               { CS42L42_ASP_RX_DAI0_EN, 0x00 },
+               { CS42L42_ASP_CLK_CFG, 0x00 },
+               { CS42L42_PWR_CTL1, 0xFE },
+diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h
+index 5e48115caf096..14645d25e70fd 100644
+--- a/sound/pci/hda/patch_cs8409.h
++++ b/sound/pci/hda/patch_cs8409.h
+@@ -230,9 +230,10 @@ enum cs8409_coefficient_index_registers {
+ #define CS42L42_PDN_TIMEOUT_US                        (250000)
+ #define CS42L42_PDN_SLEEP_US                  (2000)
+ #define CS42L42_INIT_TIMEOUT_MS                       (45)
++#define CS42L42_ANA_MUTE_AB                   (0x0C)
+ #define CS42L42_FULL_SCALE_VOL_MASK           (2)
+-#define CS42L42_FULL_SCALE_VOL_0DB            (1)
+-#define CS42L42_FULL_SCALE_VOL_MINUS6DB               (0)
++#define CS42L42_FULL_SCALE_VOL_0DB            (0)
++#define CS42L42_FULL_SCALE_VOL_MINUS6DB               (1)
+ /* Dell BULLSEYE / WARLOCK / CYBORG Specific Definitions */
+-- 
+2.39.5
+
diff --git a/queue-6.6/alsa-hda-realtek-fixup-alc225-depop-procedure.patch b/queue-6.6/alsa-hda-realtek-fixup-alc225-depop-procedure.patch
new file mode 100644 (file)
index 0000000..60f5d6e
--- /dev/null
@@ -0,0 +1,36 @@
+From b6d241d387b34cb59018daa47feba5b3c8c5766f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Feb 2025 14:40:46 +0800
+Subject: ALSA: hda/realtek: Fixup ALC225 depop procedure
+
+From: Kailang Yang <kailang@realtek.com>
+
+[ Upstream commit 174448badb4409491bfba2e6b46f7aa078741c5e ]
+
+Headset MIC will no function when power_save=0.
+
+Fixes: 1fd50509fe14 ("ALSA: hda/realtek: Update ALC225 depop procedure")
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=219743
+Signed-off-by: Kailang Yang <kailang@realtek.com>
+Link: https://lore.kernel.org/0474a095ab0044d0939ec4bf4362423d@realtek.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index abe3d5b9b84b3..75162e5f712b4 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -3779,6 +3779,7 @@ static void alc225_init(struct hda_codec *codec)
+                                   AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+               msleep(75);
++              alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
+               alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
+       }
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.6/alsa-seq-drop-ump-events-when-no-ump-conversion-is-s.patch b/queue-6.6/alsa-seq-drop-ump-events-when-no-ump-conversion-is-s.patch
new file mode 100644 (file)
index 0000000..e8dcc50
--- /dev/null
@@ -0,0 +1,57 @@
+From 79efb5b59b14eb0ea1167ef00115198d1a26d616 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 18:00:30 +0100
+Subject: ALSA: seq: Drop UMP events when no UMP-conversion is set
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit e77aa4b2eaa7fb31b2a7a50214ecb946b2a8b0f6 ]
+
+When a destination client is a user client in the legacy MIDI mode and
+it sets the no-UMP-conversion flag, currently the all UMP events are
+still passed as-is.  But this may confuse the user-space, because the
+event packet size is different from the legacy mode.
+
+Since we cannot handle UMP events in user clients unless it's running
+in the UMP client mode, we should filter out those events instead of
+accepting blindly.  This patch addresses it by slightly adjusting the
+conditions for UMP event handling at the event delivery time.
+
+Fixes: 329ffe11a014 ("ALSA: seq: Allow suppressing UMP conversions")
+Link: https://lore.kernel.org/b77a2cd6-7b59-4eb0-a8db-22d507d3af5f@gmail.com
+Link: https://patch.msgid.link/20250217170034.21930-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/core/seq/seq_clientmgr.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
+index 8b7dfbc8e8207..54931ad0dc990 100644
+--- a/sound/core/seq/seq_clientmgr.c
++++ b/sound/core/seq/seq_clientmgr.c
+@@ -682,12 +682,18 @@ static int snd_seq_deliver_single_event(struct snd_seq_client *client,
+                                         dest_port->time_real);
+ #if IS_ENABLED(CONFIG_SND_SEQ_UMP)
+-      if (!(dest->filter & SNDRV_SEQ_FILTER_NO_CONVERT)) {
+-              if (snd_seq_ev_is_ump(event)) {
++      if (snd_seq_ev_is_ump(event)) {
++              if (!(dest->filter & SNDRV_SEQ_FILTER_NO_CONVERT)) {
+                       result = snd_seq_deliver_from_ump(client, dest, dest_port,
+                                                         event, atomic, hop);
+                       goto __skip;
+-              } else if (snd_seq_client_is_ump(dest)) {
++              } else if (dest->type == USER_CLIENT &&
++                         !snd_seq_client_is_ump(dest)) {
++                      result = 0; // drop the event
++                      goto __skip;
++              }
++      } else if (snd_seq_client_is_ump(dest)) {
++              if (!(dest->filter & SNDRV_SEQ_FILTER_NO_CONVERT)) {
+                       result = snd_seq_deliver_to_ump(client, dest, dest_port,
+                                                       event, atomic, hop);
+                       goto __skip;
+-- 
+2.39.5
+
diff --git a/queue-6.6/arm64-dts-mediatek-mt8183-disable-dsi-display-output.patch b/queue-6.6/arm64-dts-mediatek-mt8183-disable-dsi-display-output.patch
new file mode 100644 (file)
index 0000000..adce8d0
--- /dev/null
@@ -0,0 +1,61 @@
+From c63c74776e36f2386af8cef549aae9dba64af4e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Oct 2024 15:56:28 +0800
+Subject: arm64: dts: mediatek: mt8183: Disable DSI display output by default
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit 26f6e91fa29a58fdc76b47f94f8f6027944a490c ]
+
+Most SoC dtsi files have the display output interfaces disabled by
+default, and only enabled on boards that utilize them. The MT8183
+has it backwards: the display outputs are left enabled by default,
+and only disabled at the board level.
+
+Reverse the situation for the DSI output so that it follows the
+normal scheme. For ease of backporting the DPI output is handled
+in a separate patch.
+
+Fixes: 88ec840270e6 ("arm64: dts: mt8183: Add dsi node")
+Fixes: 19b6403f1e2a ("arm64: dts: mt8183: add mt8183 pumpkin board")
+Cc: stable@vger.kernel.org
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: Fei Shao <fshao@chromium.org>
+Link: https://lore.kernel.org/r/20241025075630.3917458-2-wenst@chromium.org
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts | 4 ----
+ arch/arm64/boot/dts/mediatek/mt8183.dtsi        | 1 +
+ 2 files changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
+index cc24cd3aded1c..63c7c65d7f4fd 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
+@@ -524,10 +524,6 @@
+       status = "okay";
+ };
+-&dsi0 {
+-      status = "disabled";
+-};
+-
+ &dpi0 {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&dpi_func_pins>;
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+index d1b6355148620..f3a1b96f1ee4d 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+@@ -1828,6 +1828,7 @@
+                       resets = <&mmsys MT8183_MMSYS_SW0_RST_B_DISP_DSI0>;
+                       phys = <&mipi_tx0>;
+                       phy-names = "dphy";
++                      status = "disabled";
+               };
+               mutex: mutex@14016000 {
+-- 
+2.39.5
+
diff --git a/queue-6.6/arm64-dts-mediatek-mt8183-pumpkin-add-hdmi-support.patch b/queue-6.6/arm64-dts-mediatek-mt8183-pumpkin-add-hdmi-support.patch
new file mode 100644 (file)
index 0000000..ec30643
--- /dev/null
@@ -0,0 +1,184 @@
+From 97ec9ef530c7bd3554acee79c276b8582075c785 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Sep 2024 17:41:49 +0800
+Subject: arm64: dts: mediatek: mt8183-pumpkin: add HDMI support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Fabien Parent <fparent@baylibre.com>
+
+[ Upstream commit 72f3e3d68cfda508ec4b6c8927c50814229cd04e ]
+
+The MT8183 Pumpkin board has a micro-HDMI connector. HDMI support is
+provided by an IT66121 DPI <-> HDMI bridge.
+
+Enable the DPI and add the node for the IT66121 bridge.
+
+Signed-off-by: Fabien Parent <fparent@baylibre.com>
+Co-developed-by: Pin-yen Lin <treapking@chromium.org>
+Signed-off-by: Pin-yen Lin <treapking@chromium.org>
+Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Link: https://lore.kernel.org/r/20240919094212.1902073-1-treapking@chromium.org
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Stable-dep-of: 26f6e91fa29a ("arm64: dts: mediatek: mt8183: Disable DSI display output by default")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../boot/dts/mediatek/mt8183-pumpkin.dts      | 123 ++++++++++++++++++
+ 1 file changed, 123 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
+index b5784a60c315d..cc24cd3aded1c 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
+@@ -63,6 +63,18 @@
+               pulldown-ohm = <0>;
+               io-channels = <&auxadc 0>;
+       };
++
++      connector {
++              compatible = "hdmi-connector";
++              label = "hdmi";
++              type = "d";
++
++              port {
++                      hdmi_connector_in: endpoint {
++                              remote-endpoint = <&hdmi_connector_out>;
++                      };
++              };
++      };
+ };
+ &auxadc {
+@@ -120,6 +132,43 @@
+       pinctrl-0 = <&i2c6_pins>;
+       status = "okay";
+       clock-frequency = <100000>;
++      #address-cells = <1>;
++      #size-cells = <0>;
++
++      it66121hdmitx: hdmitx@4c {
++              compatible = "ite,it66121";
++              reg = <0x4c>;
++              pinctrl-names = "default";
++              pinctrl-0 = <&ite_pins>;
++              reset-gpios = <&pio 160 GPIO_ACTIVE_LOW>;
++              interrupt-parent = <&pio>;
++              interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
++              vcn33-supply = <&mt6358_vcn33_reg>;
++              vcn18-supply = <&mt6358_vcn18_reg>;
++              vrf12-supply = <&mt6358_vrf12_reg>;
++
++              ports {
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      port@0 {
++                              reg = <0>;
++
++                              it66121_in: endpoint {
++                                      bus-width = <12>;
++                                      remote-endpoint = <&dpi_out>;
++                              };
++                      };
++
++                      port@1 {
++                              reg = <1>;
++
++                              hdmi_connector_out: endpoint {
++                                      remote-endpoint = <&hdmi_connector_in>;
++                              };
++                      };
++              };
++      };
+ };
+ &keyboard {
+@@ -368,6 +417,67 @@
+                       input-enable;
+               };
+       };
++
++      ite_pins: ite-pins {
++              pins-irq {
++                      pinmux = <PINMUX_GPIO4__FUNC_GPIO4>;
++                      input-enable;
++                      bias-pull-up;
++              };
++
++              pins-rst {
++                      pinmux = <PINMUX_GPIO160__FUNC_GPIO160>;
++                      output-high;
++              };
++      };
++
++      dpi_func_pins: dpi-func-pins {
++              pins-dpi {
++                      pinmux = <PINMUX_GPIO12__FUNC_I2S5_BCK>,
++                               <PINMUX_GPIO46__FUNC_I2S5_LRCK>,
++                               <PINMUX_GPIO47__FUNC_I2S5_DO>,
++                               <PINMUX_GPIO13__FUNC_DBPI_D0>,
++                               <PINMUX_GPIO14__FUNC_DBPI_D1>,
++                               <PINMUX_GPIO15__FUNC_DBPI_D2>,
++                               <PINMUX_GPIO16__FUNC_DBPI_D3>,
++                               <PINMUX_GPIO17__FUNC_DBPI_D4>,
++                               <PINMUX_GPIO18__FUNC_DBPI_D5>,
++                               <PINMUX_GPIO19__FUNC_DBPI_D6>,
++                               <PINMUX_GPIO20__FUNC_DBPI_D7>,
++                               <PINMUX_GPIO21__FUNC_DBPI_D8>,
++                               <PINMUX_GPIO22__FUNC_DBPI_D9>,
++                               <PINMUX_GPIO23__FUNC_DBPI_D10>,
++                               <PINMUX_GPIO24__FUNC_DBPI_D11>,
++                               <PINMUX_GPIO25__FUNC_DBPI_HSYNC>,
++                               <PINMUX_GPIO26__FUNC_DBPI_VSYNC>,
++                               <PINMUX_GPIO27__FUNC_DBPI_DE>,
++                               <PINMUX_GPIO28__FUNC_DBPI_CK>;
++              };
++      };
++
++      dpi_idle_pins: dpi-idle-pins {
++              pins-idle {
++                      pinmux = <PINMUX_GPIO12__FUNC_GPIO12>,
++                               <PINMUX_GPIO46__FUNC_GPIO46>,
++                               <PINMUX_GPIO47__FUNC_GPIO47>,
++                               <PINMUX_GPIO13__FUNC_GPIO13>,
++                               <PINMUX_GPIO14__FUNC_GPIO14>,
++                               <PINMUX_GPIO15__FUNC_GPIO15>,
++                               <PINMUX_GPIO16__FUNC_GPIO16>,
++                               <PINMUX_GPIO17__FUNC_GPIO17>,
++                               <PINMUX_GPIO18__FUNC_GPIO18>,
++                               <PINMUX_GPIO19__FUNC_GPIO19>,
++                               <PINMUX_GPIO20__FUNC_GPIO20>,
++                               <PINMUX_GPIO21__FUNC_GPIO21>,
++                               <PINMUX_GPIO22__FUNC_GPIO22>,
++                               <PINMUX_GPIO23__FUNC_GPIO23>,
++                               <PINMUX_GPIO24__FUNC_GPIO24>,
++                               <PINMUX_GPIO25__FUNC_GPIO25>,
++                               <PINMUX_GPIO26__FUNC_GPIO26>,
++                               <PINMUX_GPIO27__FUNC_GPIO27>,
++                               <PINMUX_GPIO28__FUNC_GPIO28>;
++              };
++      };
+ };
+ &mfg {
+@@ -417,3 +527,16 @@
+ &dsi0 {
+       status = "disabled";
+ };
++
++&dpi0 {
++      pinctrl-names = "default", "sleep";
++      pinctrl-0 = <&dpi_func_pins>;
++      pinctrl-1 = <&dpi_idle_pins>;
++      status = "okay";
++
++      port {
++              dpi_out: endpoint {
++                      remote-endpoint = <&it66121_in>;
++              };
++      };
++};
+-- 
+2.39.5
+
diff --git a/queue-6.6/arm64-dts-qcom-sm8450-add-missing-qcom-non-secure-do.patch b/queue-6.6/arm64-dts-qcom-sm8450-add-missing-qcom-non-secure-do.patch
new file mode 100644 (file)
index 0000000..0874ebb
--- /dev/null
@@ -0,0 +1,53 @@
+From 4cc31e49a9d7ca94264ba8a6556b5e886301b02a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Feb 2024 13:53:04 +0100
+Subject: arm64: dts: qcom: sm8450: add missing qcom,non-secure-domain property
+
+From: Neil Armstrong <neil.armstrong@linaro.org>
+
+[ Upstream commit 033fbfa0eb60e519f50e97ef93baec270cd28a88 ]
+
+By default the DSP domains are non secure, add the missing
+qcom,non-secure-domain property to mark them as non-secure.
+
+Fixes: 91d70eb70867 ("arm64: dts: qcom: sm8450: add fastrpc nodes")
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20240227-topic-sm8x50-upstream-fastrpc-non-secure-domain-v1-1-15c4c864310f@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: 13c96bee5d5e ("arm64: dts: qcom: sm8450: Fix ADSP memory base and length")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8450.dtsi | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi
+index 2a49a29713752..fb0162e65a38c 100644
+--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
+@@ -2135,6 +2135,7 @@
+                                       compatible = "qcom,fastrpc";
+                                       qcom,glink-channels = "fastrpcglink-apps-dsp";
+                                       label = "sdsp";
++                                      qcom,non-secure-domain;
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+@@ -2449,6 +2450,7 @@
+                                       compatible = "qcom,fastrpc";
+                                       qcom,glink-channels = "fastrpcglink-apps-dsp";
+                                       label = "adsp";
++                                      qcom,non-secure-domain;
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+@@ -2515,6 +2517,7 @@
+                                       compatible = "qcom,fastrpc";
+                                       qcom,glink-channels = "fastrpcglink-apps-dsp";
+                                       label = "cdsp";
++                                      qcom,non-secure-domain;
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+-- 
+2.39.5
+
diff --git a/queue-6.6/arm64-dts-qcom-sm8450-fix-adsp-memory-base-and-lengt.patch b/queue-6.6/arm64-dts-qcom-sm8450-fix-adsp-memory-base-and-lengt.patch
new file mode 100644 (file)
index 0000000..492fe6c
--- /dev/null
@@ -0,0 +1,265 @@
+From 5a3c9ee21fcc82e9ba9722f0fd8fabc55e848d7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Dec 2024 15:53:53 +0100
+Subject: arm64: dts: qcom: sm8450: Fix ADSP memory base and length
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 13c96bee5d5e5b61a9d8d000c9bb37bb9a2a0551 ]
+
+The address space in ADSP PAS (Peripheral Authentication Service)
+remoteproc node should point to the QDSP PUB address space
+(QDSP6...SS_PUB): 0x0300_0000 with length of 0x10000, which also matches
+downstream DTS.  0x3000_0000, value used so far, was in datasheet is the
+region of CDSP.
+
+Correct the base address and length, which also moves the node to
+different place to keep things sorted by unit address.  The diff looks
+big, but only the unit address and "reg" property were changed.  This
+should have no functional impact on Linux users, because PAS loader does
+not use this address space at all.
+
+Fixes: 1172729576fb ("arm64: dts: qcom: sm8450: Add remoteproc enablers and instances")
+Cc: stable@vger.kernel.org
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20241213-dts-qcom-cdsp-mpss-base-address-v3-4-2e0036fccd8d@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8450.dtsi | 212 +++++++++++++--------------
+ 1 file changed, 106 insertions(+), 106 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi
+index fb0162e65a38c..3b4d788230089 100644
+--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
+@@ -2161,6 +2161,112 @@
+                       };
+               };
++              remoteproc_adsp: remoteproc@3000000 {
++                      compatible = "qcom,sm8450-adsp-pas";
++                      reg = <0x0 0x03000000 0x0 0x10000>;
++
++                      interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
++                                            <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
++                                            <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
++                                            <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
++                                            <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>;
++                      interrupt-names = "wdog", "fatal", "ready",
++                                        "handover", "stop-ack";
++
++                      clocks = <&rpmhcc RPMH_CXO_CLK>;
++                      clock-names = "xo";
++
++                      power-domains = <&rpmhpd RPMHPD_LCX>,
++                                      <&rpmhpd RPMHPD_LMX>;
++                      power-domain-names = "lcx", "lmx";
++
++                      memory-region = <&adsp_mem>;
++
++                      qcom,qmp = <&aoss_qmp>;
++
++                      qcom,smem-states = <&smp2p_adsp_out 0>;
++                      qcom,smem-state-names = "stop";
++
++                      status = "disabled";
++
++                      remoteproc_adsp_glink: glink-edge {
++                              interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
++                                                           IPCC_MPROC_SIGNAL_GLINK_QMP
++                                                           IRQ_TYPE_EDGE_RISING>;
++                              mboxes = <&ipcc IPCC_CLIENT_LPASS
++                                              IPCC_MPROC_SIGNAL_GLINK_QMP>;
++
++                              label = "lpass";
++                              qcom,remote-pid = <2>;
++
++                              gpr {
++                                      compatible = "qcom,gpr";
++                                      qcom,glink-channels = "adsp_apps";
++                                      qcom,domain = <GPR_DOMAIN_ID_ADSP>;
++                                      qcom,intents = <512 20>;
++                                      #address-cells = <1>;
++                                      #size-cells = <0>;
++
++                                      q6apm: service@1 {
++                                              compatible = "qcom,q6apm";
++                                              reg = <GPR_APM_MODULE_IID>;
++                                              #sound-dai-cells = <0>;
++                                              qcom,protection-domain = "avs/audio",
++                                                                       "msm/adsp/audio_pd";
++
++                                              q6apmdai: dais {
++                                                      compatible = "qcom,q6apm-dais";
++                                                      iommus = <&apps_smmu 0x1801 0x0>;
++                                              };
++
++                                              q6apmbedai: bedais {
++                                                      compatible = "qcom,q6apm-lpass-dais";
++                                                      #sound-dai-cells = <1>;
++                                              };
++                                      };
++
++                                      q6prm: service@2 {
++                                              compatible = "qcom,q6prm";
++                                              reg = <GPR_PRM_MODULE_IID>;
++                                              qcom,protection-domain = "avs/audio",
++                                                                       "msm/adsp/audio_pd";
++
++                                              q6prmcc: clock-controller {
++                                                      compatible = "qcom,q6prm-lpass-clocks";
++                                                      #clock-cells = <2>;
++                                              };
++                                      };
++                              };
++
++                              fastrpc {
++                                      compatible = "qcom,fastrpc";
++                                      qcom,glink-channels = "fastrpcglink-apps-dsp";
++                                      label = "adsp";
++                                      qcom,non-secure-domain;
++                                      #address-cells = <1>;
++                                      #size-cells = <0>;
++
++                                      compute-cb@3 {
++                                              compatible = "qcom,fastrpc-compute-cb";
++                                              reg = <3>;
++                                              iommus = <&apps_smmu 0x1803 0x0>;
++                                      };
++
++                                      compute-cb@4 {
++                                              compatible = "qcom,fastrpc-compute-cb";
++                                              reg = <4>;
++                                              iommus = <&apps_smmu 0x1804 0x0>;
++                                      };
++
++                                      compute-cb@5 {
++                                              compatible = "qcom,fastrpc-compute-cb";
++                                              reg = <5>;
++                                              iommus = <&apps_smmu 0x1805 0x0>;
++                                      };
++                              };
++                      };
++              };
++
+               wsa2macro: codec@31e0000 {
+                       compatible = "qcom,sm8450-lpass-wsa-macro";
+                       reg = <0 0x031e0000 0 0x1000>;
+@@ -2369,112 +2475,6 @@
+                       status = "disabled";
+               };
+-              remoteproc_adsp: remoteproc@30000000 {
+-                      compatible = "qcom,sm8450-adsp-pas";
+-                      reg = <0 0x30000000 0 0x100>;
+-
+-                      interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
+-                                            <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
+-                                            <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
+-                                            <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
+-                                            <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>;
+-                      interrupt-names = "wdog", "fatal", "ready",
+-                                        "handover", "stop-ack";
+-
+-                      clocks = <&rpmhcc RPMH_CXO_CLK>;
+-                      clock-names = "xo";
+-
+-                      power-domains = <&rpmhpd RPMHPD_LCX>,
+-                                      <&rpmhpd RPMHPD_LMX>;
+-                      power-domain-names = "lcx", "lmx";
+-
+-                      memory-region = <&adsp_mem>;
+-
+-                      qcom,qmp = <&aoss_qmp>;
+-
+-                      qcom,smem-states = <&smp2p_adsp_out 0>;
+-                      qcom,smem-state-names = "stop";
+-
+-                      status = "disabled";
+-
+-                      remoteproc_adsp_glink: glink-edge {
+-                              interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
+-                                                           IPCC_MPROC_SIGNAL_GLINK_QMP
+-                                                           IRQ_TYPE_EDGE_RISING>;
+-                              mboxes = <&ipcc IPCC_CLIENT_LPASS
+-                                              IPCC_MPROC_SIGNAL_GLINK_QMP>;
+-
+-                              label = "lpass";
+-                              qcom,remote-pid = <2>;
+-
+-                              gpr {
+-                                      compatible = "qcom,gpr";
+-                                      qcom,glink-channels = "adsp_apps";
+-                                      qcom,domain = <GPR_DOMAIN_ID_ADSP>;
+-                                      qcom,intents = <512 20>;
+-                                      #address-cells = <1>;
+-                                      #size-cells = <0>;
+-
+-                                      q6apm: service@1 {
+-                                              compatible = "qcom,q6apm";
+-                                              reg = <GPR_APM_MODULE_IID>;
+-                                              #sound-dai-cells = <0>;
+-                                              qcom,protection-domain = "avs/audio",
+-                                                                       "msm/adsp/audio_pd";
+-
+-                                              q6apmdai: dais {
+-                                                      compatible = "qcom,q6apm-dais";
+-                                                      iommus = <&apps_smmu 0x1801 0x0>;
+-                                              };
+-
+-                                              q6apmbedai: bedais {
+-                                                      compatible = "qcom,q6apm-lpass-dais";
+-                                                      #sound-dai-cells = <1>;
+-                                              };
+-                                      };
+-
+-                                      q6prm: service@2 {
+-                                              compatible = "qcom,q6prm";
+-                                              reg = <GPR_PRM_MODULE_IID>;
+-                                              qcom,protection-domain = "avs/audio",
+-                                                                       "msm/adsp/audio_pd";
+-
+-                                              q6prmcc: clock-controller {
+-                                                      compatible = "qcom,q6prm-lpass-clocks";
+-                                                      #clock-cells = <2>;
+-                                              };
+-                                      };
+-                              };
+-
+-                              fastrpc {
+-                                      compatible = "qcom,fastrpc";
+-                                      qcom,glink-channels = "fastrpcglink-apps-dsp";
+-                                      label = "adsp";
+-                                      qcom,non-secure-domain;
+-                                      #address-cells = <1>;
+-                                      #size-cells = <0>;
+-
+-                                      compute-cb@3 {
+-                                              compatible = "qcom,fastrpc-compute-cb";
+-                                              reg = <3>;
+-                                              iommus = <&apps_smmu 0x1803 0x0>;
+-                                      };
+-
+-                                      compute-cb@4 {
+-                                              compatible = "qcom,fastrpc-compute-cb";
+-                                              reg = <4>;
+-                                              iommus = <&apps_smmu 0x1804 0x0>;
+-                                      };
+-
+-                                      compute-cb@5 {
+-                                              compatible = "qcom,fastrpc-compute-cb";
+-                                              reg = <5>;
+-                                              iommus = <&apps_smmu 0x1805 0x0>;
+-                                      };
+-                              };
+-                      };
+-              };
+-
+               remoteproc_cdsp: remoteproc@32300000 {
+                       compatible = "qcom,sm8450-cdsp-pas";
+                       reg = <0 0x32300000 0 0x10000>;
+-- 
+2.39.5
+
diff --git a/queue-6.6/arm64-dts-qcom-sm8550-add-dma-coherent-property.patch b/queue-6.6/arm64-dts-qcom-sm8550-add-dma-coherent-property.patch
new file mode 100644 (file)
index 0000000..030b8a6
--- /dev/null
@@ -0,0 +1,133 @@
+From 5511a73a9225f329eda072646d942bb2d673ebae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Jan 2024 15:54:12 +0530
+Subject: arm64: dts: qcom: sm8550: Add dma-coherent property
+
+From: Ling Xu <quic_lxu5@quicinc.com>
+
+[ Upstream commit 4a03b85b8491d8bfe84a26ff979507b6ae7122c1 ]
+
+Add dma-coherent property to fastRPC context bank nodes to pass dma
+sequence test in fastrpc sanity test, ensure that data integrity is
+maintained during DMA operations.
+
+Signed-off-by: Ling Xu <quic_lxu5@quicinc.com>
+Link: https://lore.kernel.org/r/20240125102413.3016-2-quic_lxu5@quicinc.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: a6a8f54bc2af ("arm64: dts: qcom: sm8550: Fix ADSP memory base and length")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8550.dtsi | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+index f3a0e1fe333c4..51407c482b51f 100644
+--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+@@ -4006,6 +4006,7 @@
+                                               reg = <3>;
+                                               iommus = <&apps_smmu 0x1003 0x80>,
+                                                        <&apps_smmu 0x1063 0x0>;
++                                              dma-coherent;
+                                       };
+                                       compute-cb@4 {
+@@ -4013,6 +4014,7 @@
+                                               reg = <4>;
+                                               iommus = <&apps_smmu 0x1004 0x80>,
+                                                        <&apps_smmu 0x1064 0x0>;
++                                              dma-coherent;
+                                       };
+                                       compute-cb@5 {
+@@ -4020,6 +4022,7 @@
+                                               reg = <5>;
+                                               iommus = <&apps_smmu 0x1005 0x80>,
+                                                        <&apps_smmu 0x1065 0x0>;
++                                              dma-coherent;
+                                       };
+                                       compute-cb@6 {
+@@ -4027,6 +4030,7 @@
+                                               reg = <6>;
+                                               iommus = <&apps_smmu 0x1006 0x80>,
+                                                        <&apps_smmu 0x1066 0x0>;
++                                              dma-coherent;
+                                       };
+                                       compute-cb@7 {
+@@ -4034,6 +4038,7 @@
+                                               reg = <7>;
+                                               iommus = <&apps_smmu 0x1007 0x80>,
+                                                        <&apps_smmu 0x1067 0x0>;
++                                              dma-coherent;
+                                       };
+                               };
+@@ -4140,6 +4145,7 @@
+                                               iommus = <&apps_smmu 0x1961 0x0>,
+                                                        <&apps_smmu 0x0c01 0x20>,
+                                                        <&apps_smmu 0x19c1 0x10>;
++                                              dma-coherent;
+                                       };
+                                       compute-cb@2 {
+@@ -4148,6 +4154,7 @@
+                                               iommus = <&apps_smmu 0x1962 0x0>,
+                                                        <&apps_smmu 0x0c02 0x20>,
+                                                        <&apps_smmu 0x19c2 0x10>;
++                                              dma-coherent;
+                                       };
+                                       compute-cb@3 {
+@@ -4156,6 +4163,7 @@
+                                               iommus = <&apps_smmu 0x1963 0x0>,
+                                                        <&apps_smmu 0x0c03 0x20>,
+                                                        <&apps_smmu 0x19c3 0x10>;
++                                              dma-coherent;
+                                       };
+                                       compute-cb@4 {
+@@ -4164,6 +4172,7 @@
+                                               iommus = <&apps_smmu 0x1964 0x0>,
+                                                        <&apps_smmu 0x0c04 0x20>,
+                                                        <&apps_smmu 0x19c4 0x10>;
++                                              dma-coherent;
+                                       };
+                                       compute-cb@5 {
+@@ -4172,6 +4181,7 @@
+                                               iommus = <&apps_smmu 0x1965 0x0>,
+                                                        <&apps_smmu 0x0c05 0x20>,
+                                                        <&apps_smmu 0x19c5 0x10>;
++                                              dma-coherent;
+                                       };
+                                       compute-cb@6 {
+@@ -4180,6 +4190,7 @@
+                                               iommus = <&apps_smmu 0x1966 0x0>,
+                                                        <&apps_smmu 0x0c06 0x20>,
+                                                        <&apps_smmu 0x19c6 0x10>;
++                                              dma-coherent;
+                                       };
+                                       compute-cb@7 {
+@@ -4188,6 +4199,7 @@
+                                               iommus = <&apps_smmu 0x1967 0x0>,
+                                                        <&apps_smmu 0x0c07 0x20>,
+                                                        <&apps_smmu 0x19c7 0x10>;
++                                              dma-coherent;
+                                       };
+                                       compute-cb@8 {
+@@ -4196,6 +4208,7 @@
+                                               iommus = <&apps_smmu 0x1968 0x0>,
+                                                        <&apps_smmu 0x0c08 0x20>,
+                                                        <&apps_smmu 0x19c8 0x10>;
++                                              dma-coherent;
+                                       };
+                                       /* note: secure cb9 in downstream */
+-- 
+2.39.5
+
diff --git a/queue-6.6/arm64-dts-qcom-sm8550-add-missing-qcom-non-secure-do.patch b/queue-6.6/arm64-dts-qcom-sm8550-add-missing-qcom-non-secure-do.patch
new file mode 100644 (file)
index 0000000..a7edd27
--- /dev/null
@@ -0,0 +1,45 @@
+From 5365e7c2c02a7013abfc0318c0e1677f4417cafe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Feb 2024 13:53:05 +0100
+Subject: arm64: dts: qcom: sm8550: add missing qcom,non-secure-domain property
+
+From: Neil Armstrong <neil.armstrong@linaro.org>
+
+[ Upstream commit 49c50ad9e6cbaa6a3da59cdd85d4ffb354ef65f4 ]
+
+By default the DSP domains are non secure, add the missing
+qcom,non-secure-domain property to mark them as non-secure.
+
+Fixes: d0c061e366ed ("arm64: dts: qcom: sm8550: add adsp, cdsp & mdss nodes")
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20240227-topic-sm8x50-upstream-fastrpc-non-secure-domain-v1-2-15c4c864310f@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: a6a8f54bc2af ("arm64: dts: qcom: sm8550: Fix ADSP memory base and length")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8550.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+index 51407c482b51f..500dfbd79fb69 100644
+--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+@@ -3998,6 +3998,7 @@
+                                       compatible = "qcom,fastrpc";
+                                       qcom,glink-channels = "fastrpcglink-apps-dsp";
+                                       label = "adsp";
++                                      qcom,non-secure-domain;
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+@@ -4136,6 +4137,7 @@
+                                       compatible = "qcom,fastrpc";
+                                       qcom,glink-channels = "fastrpcglink-apps-dsp";
+                                       label = "cdsp";
++                                      qcom,non-secure-domain;
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+-- 
+2.39.5
+
diff --git a/queue-6.6/arm64-dts-qcom-sm8550-fix-adsp-memory-base-and-lengt.patch b/queue-6.6/arm64-dts-qcom-sm8550-fix-adsp-memory-base-and-lengt.patch
new file mode 100644 (file)
index 0000000..94a61da
--- /dev/null
@@ -0,0 +1,318 @@
+From 0c7b4e920f31620058fdea31fb4f85e4bdfcf506 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Dec 2024 15:53:56 +0100
+Subject: arm64: dts: qcom: sm8550: Fix ADSP memory base and length
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit a6a8f54bc2af555738322783ba1e990c2ae7f443 ]
+
+The address space in ADSP PAS (Peripheral Authentication Service)
+remoteproc node should point to the QDSP PUB address space
+(QDSP6...SS_PUB): 0x0680_0000 with length of 0x10000.
+
+0x3000_0000, value used so far, is the main region of CDSP.  Downstream
+DTS uses 0x0300_0000, which is oddly similar to 0x3000_0000, yet quite
+different and points to unused area.
+
+Correct the base address and length, which also moves the node to
+different place to keep things sorted by unit address.  The diff looks
+big, but only the unit address and "reg" property were changed.  This
+should have no functional impact on Linux users, because PAS loader does
+not use this address space at all.
+
+Fixes: d0c061e366ed ("arm64: dts: qcom: sm8550: add adsp, cdsp & mdss nodes")
+Cc: stable@vger.kernel.org
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20241213-dts-qcom-cdsp-mpss-base-address-v3-7-2e0036fccd8d@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8550.dtsi | 262 +++++++++++++--------------
+ 1 file changed, 131 insertions(+), 131 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+index 500dfbd79fb69..bc9a1fca2db3a 100644
+--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+@@ -2026,6 +2026,137 @@
+                       };
+               };
++              remoteproc_adsp: remoteproc@6800000 {
++                      compatible = "qcom,sm8550-adsp-pas";
++                      reg = <0x0 0x06800000 0x0 0x10000>;
++
++                      interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
++                                            <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
++                                            <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
++                                            <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
++                                            <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>;
++                      interrupt-names = "wdog", "fatal", "ready",
++                                        "handover", "stop-ack";
++
++                      clocks = <&rpmhcc RPMH_CXO_CLK>;
++                      clock-names = "xo";
++
++                      power-domains = <&rpmhpd RPMHPD_LCX>,
++                                      <&rpmhpd RPMHPD_LMX>;
++                      power-domain-names = "lcx", "lmx";
++
++                      interconnects = <&lpass_lpicx_noc MASTER_LPASS_PROC 0 &mc_virt SLAVE_EBI1 0>;
++
++                      memory-region = <&adspslpi_mem>, <&q6_adsp_dtb_mem>;
++
++                      qcom,qmp = <&aoss_qmp>;
++
++                      qcom,smem-states = <&smp2p_adsp_out 0>;
++                      qcom,smem-state-names = "stop";
++
++                      status = "disabled";
++
++                      remoteproc_adsp_glink: glink-edge {
++                              interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
++                                                           IPCC_MPROC_SIGNAL_GLINK_QMP
++                                                           IRQ_TYPE_EDGE_RISING>;
++                              mboxes = <&ipcc IPCC_CLIENT_LPASS
++                                              IPCC_MPROC_SIGNAL_GLINK_QMP>;
++
++                              label = "lpass";
++                              qcom,remote-pid = <2>;
++
++                              fastrpc {
++                                      compatible = "qcom,fastrpc";
++                                      qcom,glink-channels = "fastrpcglink-apps-dsp";
++                                      label = "adsp";
++                                      qcom,non-secure-domain;
++                                      #address-cells = <1>;
++                                      #size-cells = <0>;
++
++                                      compute-cb@3 {
++                                              compatible = "qcom,fastrpc-compute-cb";
++                                              reg = <3>;
++                                              iommus = <&apps_smmu 0x1003 0x80>,
++                                                       <&apps_smmu 0x1063 0x0>;
++                                              dma-coherent;
++                                      };
++
++                                      compute-cb@4 {
++                                              compatible = "qcom,fastrpc-compute-cb";
++                                              reg = <4>;
++                                              iommus = <&apps_smmu 0x1004 0x80>,
++                                                       <&apps_smmu 0x1064 0x0>;
++                                              dma-coherent;
++                                      };
++
++                                      compute-cb@5 {
++                                              compatible = "qcom,fastrpc-compute-cb";
++                                              reg = <5>;
++                                              iommus = <&apps_smmu 0x1005 0x80>,
++                                                       <&apps_smmu 0x1065 0x0>;
++                                              dma-coherent;
++                                      };
++
++                                      compute-cb@6 {
++                                              compatible = "qcom,fastrpc-compute-cb";
++                                              reg = <6>;
++                                              iommus = <&apps_smmu 0x1006 0x80>,
++                                                       <&apps_smmu 0x1066 0x0>;
++                                              dma-coherent;
++                                      };
++
++                                      compute-cb@7 {
++                                              compatible = "qcom,fastrpc-compute-cb";
++                                              reg = <7>;
++                                              iommus = <&apps_smmu 0x1007 0x80>,
++                                                       <&apps_smmu 0x1067 0x0>;
++                                              dma-coherent;
++                                      };
++                              };
++
++                              gpr {
++                                      compatible = "qcom,gpr";
++                                      qcom,glink-channels = "adsp_apps";
++                                      qcom,domain = <GPR_DOMAIN_ID_ADSP>;
++                                      qcom,intents = <512 20>;
++                                      #address-cells = <1>;
++                                      #size-cells = <0>;
++
++                                      q6apm: service@1 {
++                                              compatible = "qcom,q6apm";
++                                              reg = <GPR_APM_MODULE_IID>;
++                                              #sound-dai-cells = <0>;
++                                              qcom,protection-domain = "avs/audio",
++                                                                       "msm/adsp/audio_pd";
++
++                                              q6apmdai: dais {
++                                                      compatible = "qcom,q6apm-dais";
++                                                      iommus = <&apps_smmu 0x1001 0x80>,
++                                                               <&apps_smmu 0x1061 0x0>;
++                                              };
++
++                                              q6apmbedai: bedais {
++                                                      compatible = "qcom,q6apm-lpass-dais";
++                                                      #sound-dai-cells = <1>;
++                                              };
++                                      };
++
++                                      q6prm: service@2 {
++                                              compatible = "qcom,q6prm";
++                                              reg = <GPR_PRM_MODULE_IID>;
++                                              qcom,protection-domain = "avs/audio",
++                                                                       "msm/adsp/audio_pd";
++
++                                              q6prmcc: clock-controller {
++                                                      compatible = "qcom,q6prm-lpass-clocks";
++                                                      #clock-cells = <2>;
++                                              };
++                                      };
++                              };
++                      };
++              };
++
+               lpass_wsa2macro: codec@6aa0000 {
+                       compatible = "qcom,sm8550-lpass-wsa-macro";
+                       reg = <0 0x06aa0000 0 0x1000>;
+@@ -3954,137 +4085,6 @@
+                       interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+               };
+-              remoteproc_adsp: remoteproc@30000000 {
+-                      compatible = "qcom,sm8550-adsp-pas";
+-                      reg = <0x0 0x30000000 0x0 0x100>;
+-
+-                      interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
+-                                            <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
+-                                            <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
+-                                            <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
+-                                            <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>;
+-                      interrupt-names = "wdog", "fatal", "ready",
+-                                        "handover", "stop-ack";
+-
+-                      clocks = <&rpmhcc RPMH_CXO_CLK>;
+-                      clock-names = "xo";
+-
+-                      power-domains = <&rpmhpd RPMHPD_LCX>,
+-                                      <&rpmhpd RPMHPD_LMX>;
+-                      power-domain-names = "lcx", "lmx";
+-
+-                      interconnects = <&lpass_lpicx_noc MASTER_LPASS_PROC 0 &mc_virt SLAVE_EBI1 0>;
+-
+-                      memory-region = <&adspslpi_mem>, <&q6_adsp_dtb_mem>;
+-
+-                      qcom,qmp = <&aoss_qmp>;
+-
+-                      qcom,smem-states = <&smp2p_adsp_out 0>;
+-                      qcom,smem-state-names = "stop";
+-
+-                      status = "disabled";
+-
+-                      remoteproc_adsp_glink: glink-edge {
+-                              interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
+-                                                           IPCC_MPROC_SIGNAL_GLINK_QMP
+-                                                           IRQ_TYPE_EDGE_RISING>;
+-                              mboxes = <&ipcc IPCC_CLIENT_LPASS
+-                                              IPCC_MPROC_SIGNAL_GLINK_QMP>;
+-
+-                              label = "lpass";
+-                              qcom,remote-pid = <2>;
+-
+-                              fastrpc {
+-                                      compatible = "qcom,fastrpc";
+-                                      qcom,glink-channels = "fastrpcglink-apps-dsp";
+-                                      label = "adsp";
+-                                      qcom,non-secure-domain;
+-                                      #address-cells = <1>;
+-                                      #size-cells = <0>;
+-
+-                                      compute-cb@3 {
+-                                              compatible = "qcom,fastrpc-compute-cb";
+-                                              reg = <3>;
+-                                              iommus = <&apps_smmu 0x1003 0x80>,
+-                                                       <&apps_smmu 0x1063 0x0>;
+-                                              dma-coherent;
+-                                      };
+-
+-                                      compute-cb@4 {
+-                                              compatible = "qcom,fastrpc-compute-cb";
+-                                              reg = <4>;
+-                                              iommus = <&apps_smmu 0x1004 0x80>,
+-                                                       <&apps_smmu 0x1064 0x0>;
+-                                              dma-coherent;
+-                                      };
+-
+-                                      compute-cb@5 {
+-                                              compatible = "qcom,fastrpc-compute-cb";
+-                                              reg = <5>;
+-                                              iommus = <&apps_smmu 0x1005 0x80>,
+-                                                       <&apps_smmu 0x1065 0x0>;
+-                                              dma-coherent;
+-                                      };
+-
+-                                      compute-cb@6 {
+-                                              compatible = "qcom,fastrpc-compute-cb";
+-                                              reg = <6>;
+-                                              iommus = <&apps_smmu 0x1006 0x80>,
+-                                                       <&apps_smmu 0x1066 0x0>;
+-                                              dma-coherent;
+-                                      };
+-
+-                                      compute-cb@7 {
+-                                              compatible = "qcom,fastrpc-compute-cb";
+-                                              reg = <7>;
+-                                              iommus = <&apps_smmu 0x1007 0x80>,
+-                                                       <&apps_smmu 0x1067 0x0>;
+-                                              dma-coherent;
+-                                      };
+-                              };
+-
+-                              gpr {
+-                                      compatible = "qcom,gpr";
+-                                      qcom,glink-channels = "adsp_apps";
+-                                      qcom,domain = <GPR_DOMAIN_ID_ADSP>;
+-                                      qcom,intents = <512 20>;
+-                                      #address-cells = <1>;
+-                                      #size-cells = <0>;
+-
+-                                      q6apm: service@1 {
+-                                              compatible = "qcom,q6apm";
+-                                              reg = <GPR_APM_MODULE_IID>;
+-                                              #sound-dai-cells = <0>;
+-                                              qcom,protection-domain = "avs/audio",
+-                                                                       "msm/adsp/audio_pd";
+-
+-                                              q6apmdai: dais {
+-                                                      compatible = "qcom,q6apm-dais";
+-                                                      iommus = <&apps_smmu 0x1001 0x80>,
+-                                                               <&apps_smmu 0x1061 0x0>;
+-                                              };
+-
+-                                              q6apmbedai: bedais {
+-                                                      compatible = "qcom,q6apm-lpass-dais";
+-                                                      #sound-dai-cells = <1>;
+-                                              };
+-                                      };
+-
+-                                      q6prm: service@2 {
+-                                              compatible = "qcom,q6prm";
+-                                              reg = <GPR_PRM_MODULE_IID>;
+-                                              qcom,protection-domain = "avs/audio",
+-                                                                       "msm/adsp/audio_pd";
+-
+-                                              q6prmcc: clock-controller {
+-                                                      compatible = "qcom,q6prm-lpass-clocks";
+-                                                      #clock-cells = <2>;
+-                                              };
+-                                      };
+-                              };
+-                      };
+-              };
+-
+               nsp_noc: interconnect@320c0000 {
+                       compatible = "qcom,sm8550-nsp-noc";
+                       reg = <0 0x320c0000 0 0xe080>;
+-- 
+2.39.5
+
diff --git a/queue-6.6/arp-switch-to-dev_getbyhwaddr-in-arp_req_set_public.patch b/queue-6.6/arp-switch-to-dev_getbyhwaddr-in-arp_req_set_public.patch
new file mode 100644 (file)
index 0000000..dc55af9
--- /dev/null
@@ -0,0 +1,47 @@
+From 7158cb2f448f124c0dffac0dbeb559dea3560bba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Feb 2025 05:49:31 -0800
+Subject: arp: switch to dev_getbyhwaddr() in arp_req_set_public()
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 4eae0ee0f1e6256d0b0b9dd6e72f1d9cf8f72e08 ]
+
+The arp_req_set_public() function is called with the rtnl lock held,
+which provides enough synchronization protection. This makes the RCU
+variant of dev_getbyhwaddr() unnecessary. Switch to using the simpler
+dev_getbyhwaddr() function since we already have the required rtnl
+locking.
+
+This change helps maintain consistency in the networking code by using
+the appropriate helper function for the existing locking context.
+Since we're not holding the RCU read lock in arp_req_set_public()
+existing code could trigger false positive locking warnings.
+
+Fixes: 941666c2e3e0 ("net: RCU conversion of dev_getbyhwaddr() and arp_ioctl()")
+Suggested-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Link: https://patch.msgid.link/20250218-arm_fix_selftest-v5-2-d3d6892db9e1@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/arp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
+index 02776453bf97a..784dc8b37be5a 100644
+--- a/net/ipv4/arp.c
++++ b/net/ipv4/arp.c
+@@ -1030,7 +1030,7 @@ static int arp_req_set_public(struct net *net, struct arpreq *r,
+       if (mask && mask != htonl(0xFFFFFFFF))
+               return -EINVAL;
+       if (!dev && (r->arp_flags & ATF_COM)) {
+-              dev = dev_getbyhwaddr_rcu(net, r->arp_ha.sa_family,
++              dev = dev_getbyhwaddr(net, r->arp_ha.sa_family,
+                                     r->arp_ha.sa_data);
+               if (!dev)
+                       return -ENODEV;
+-- 
+2.39.5
+
diff --git a/queue-6.6/asoc-renesas-rz-ssi-add-a-check-for-negative-sample_.patch b/queue-6.6/asoc-renesas-rz-ssi-add-a-check-for-negative-sample_.patch
new file mode 100644 (file)
index 0000000..d104777
--- /dev/null
@@ -0,0 +1,45 @@
+From e40008cd6d01ccf7975bc0d0cd801ba800b2326b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jan 2025 12:28:46 +0300
+Subject: ASoC: renesas: rz-ssi: Add a check for negative sample_space
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 82a0a3e6f8c02b3236b55e784a083fa4ee07c321 ]
+
+My static checker rule complains about this code.  The concern is that
+if "sample_space" is negative then the "sample_space >= runtime->channels"
+condition will not work as intended because it will be type promoted to a
+high unsigned int value.
+
+strm->fifo_sample_size is SSI_FIFO_DEPTH (32).  The SSIFSR_TDC_MASK is
+0x3f.  Without any further context it does seem like a reasonable warning
+and it can't hurt to add a check for negatives.
+
+Cc: stable@vger.kernel.org
+Fixes: 03e786bd4341 ("ASoC: sh: Add RZ/G2L SSIF-2 driver")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://patch.msgid.link/e07c3dc5-d885-4b04-a742-71f42243f4fd@stanley.mountain
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sh/rz-ssi.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c
+index 353863f49b313..54f096bdc7ee2 100644
+--- a/sound/soc/sh/rz-ssi.c
++++ b/sound/soc/sh/rz-ssi.c
+@@ -484,6 +484,8 @@ static int rz_ssi_pio_send(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
+       sample_space = strm->fifo_sample_size;
+       ssifsr = rz_ssi_reg_readl(ssi, SSIFSR);
+       sample_space -= (ssifsr >> SSIFSR_TDC_SHIFT) & SSIFSR_TDC_MASK;
++      if (sample_space < 0)
++              return -EINVAL;
+       /* Only add full frames at a time */
+       while (frames_left && (sample_space >= runtime->channels)) {
+-- 
+2.39.5
+
diff --git a/queue-6.6/asoc-rockchip-i2s-tdm-fix-shift-config-for-snd_soc_d.patch b/queue-6.6/asoc-rockchip-i2s-tdm-fix-shift-config-for-snd_soc_d.patch
new file mode 100644 (file)
index 0000000..87f3912
--- /dev/null
@@ -0,0 +1,46 @@
+From d962718b649e8880a57daea401b002473006c9c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Feb 2025 16:13:10 +0000
+Subject: ASoC: rockchip: i2s-tdm: fix shift config for SND_SOC_DAIFMT_DSP_[AB]
+
+From: John Keeping <jkeeping@inmusicbrands.com>
+
+[ Upstream commit 6b24e67b4056ba83b1e95e005b7e50fdb1cc6cf4 ]
+
+Commit 2f45a4e289779 ("ASoC: rockchip: i2s_tdm: Fixup config for
+SND_SOC_DAIFMT_DSP_A/B") applied a partial change to fix the
+configuration for DSP A and DSP B formats.
+
+The shift control also needs updating to set the correct offset for
+frame data compared to LRCK.  Set the correct values.
+
+Fixes: 081068fd64140 ("ASoC: rockchip: add support for i2s-tdm controller")
+Signed-off-by: John Keeping <jkeeping@inmusicbrands.com>
+Link: https://patch.msgid.link/20250204161311.2117240-1-jkeeping@inmusicbrands.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/rockchip/rockchip_i2s_tdm.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c
+index 14e5c53e697b0..7ae93cbaea9a7 100644
+--- a/sound/soc/rockchip/rockchip_i2s_tdm.c
++++ b/sound/soc/rockchip/rockchip_i2s_tdm.c
+@@ -453,11 +453,11 @@ static int rockchip_i2s_tdm_set_fmt(struct snd_soc_dai *cpu_dai,
+                       break;
+               case SND_SOC_DAIFMT_DSP_A:
+                       val = I2S_TXCR_TFS_TDM_PCM;
+-                      tdm_val = TDM_SHIFT_CTRL(0);
++                      tdm_val = TDM_SHIFT_CTRL(2);
+                       break;
+               case SND_SOC_DAIFMT_DSP_B:
+                       val = I2S_TXCR_TFS_TDM_PCM;
+-                      tdm_val = TDM_SHIFT_CTRL(2);
++                      tdm_val = TDM_SHIFT_CTRL(4);
+                       break;
+               default:
+                       ret = -EINVAL;
+-- 
+2.39.5
+
diff --git a/queue-6.6/bluetooth-qca-fix-poor-rf-performance-for-wcn6855.patch b/queue-6.6/bluetooth-qca-fix-poor-rf-performance-for-wcn6855.patch
new file mode 100644 (file)
index 0000000..9b3cbd0
--- /dev/null
@@ -0,0 +1,48 @@
+From 2e5d6e22149a5c3076dd5438b6b57bd878b7c1bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jan 2025 22:43:23 +0800
+Subject: Bluetooth: qca: Fix poor RF performance for WCN6855
+
+From: Zijun Hu <quic_zijuhu@quicinc.com>
+
+[ Upstream commit a2fad248947d702ed3dcb52b8377c1a3ae201e44 ]
+
+For WCN6855, board ID specific NVM needs to be downloaded once board ID
+is available, but the default NVM is always downloaded currently.
+
+The wrong NVM causes poor RF performance, and effects user experience
+for several types of laptop with WCN6855 on the market.
+
+Fix by downloading board ID specific NVM if board ID is available.
+
+Fixes: 095327fede00 ("Bluetooth: hci_qca: Add support for QTI Bluetooth chip wcn6855")
+Cc: stable@vger.kernel.org # 6.4
+Signed-off-by: Zijun Hu <quic_zijuhu@quicinc.com>
+Tested-by: Johan Hovold <johan+linaro@kernel.org>
+Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
+Tested-by: Steev Klimaszewski <steev@kali.org> #Thinkpad X13s
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btqca.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
+index 484a860785fde..892e2540f008a 100644
+--- a/drivers/bluetooth/btqca.c
++++ b/drivers/bluetooth/btqca.c
+@@ -927,8 +927,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
+                                "qca/msnv%02x.bin", rom_ver);
+                       break;
+               case QCA_WCN6855:
+-                      snprintf(config.fwname, sizeof(config.fwname),
+-                               "qca/hpnv%02x.bin", rom_ver);
++                      qca_read_fw_board_id(hdev, &boardid);
++                      qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname),
++                                                "hpnv", soc_type, ver, rom_ver, boardid);
+                       break;
+               case QCA_WCN7850:
+                       qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname),
+-- 
+2.39.5
+
diff --git a/queue-6.6/bluetooth-qca-support-downloading-board-id-specific-.patch b/queue-6.6/bluetooth-qca-support-downloading-board-id-specific-.patch
new file mode 100644 (file)
index 0000000..4b87e4b
--- /dev/null
@@ -0,0 +1,66 @@
+From 43c4baefd3cd32782be7882dd8631ee7d25d23b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Apr 2024 15:49:34 +0800
+Subject: Bluetooth: qca: Support downloading board id specific NVM for WCN7850
+
+From: Zijun Hu <quic_zijuhu@quicinc.com>
+
+[ Upstream commit e41137d8bd1a8e8bab8dcbfe3ec056418db3df18 ]
+
+Download board id specific NVM instead of default for WCN7850 if board id
+is available.
+
+Signed-off-by: Zijun Hu <quic_zijuhu@quicinc.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: a2fad248947d ("Bluetooth: qca: Fix poor RF performance for WCN6855")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btqca.c | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
+index 35fb26cbf2294..513ff87a7a049 100644
+--- a/drivers/bluetooth/btqca.c
++++ b/drivers/bluetooth/btqca.c
+@@ -739,6 +739,19 @@ static void qca_generate_hsp_nvm_name(char *fwname, size_t max_size,
+               snprintf(fwname, max_size, "qca/hpnv%02x%s.%x", rom_ver, variant, bid);
+ }
++static inline void qca_get_nvm_name_generic(struct qca_fw_config *cfg,
++                                          const char *stem, u8 rom_ver, u16 bid)
++{
++      if (bid == 0x0)
++              snprintf(cfg->fwname, sizeof(cfg->fwname), "qca/%snv%02x.bin", stem, rom_ver);
++      else if (bid & 0xff00)
++              snprintf(cfg->fwname, sizeof(cfg->fwname),
++                       "qca/%snv%02x.b%x", stem, rom_ver, bid);
++      else
++              snprintf(cfg->fwname, sizeof(cfg->fwname),
++                       "qca/%snv%02x.b%02x", stem, rom_ver, bid);
++}
++
+ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
+                  enum qca_btsoc_type soc_type, struct qca_btsoc_version ver,
+                  const char *firmware_name)
+@@ -819,7 +832,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
+       /* Give the controller some time to get ready to receive the NVM */
+       msleep(10);
+-      if (soc_type == QCA_QCA2066)
++      if (soc_type == QCA_QCA2066 || soc_type == QCA_WCN7850)
+               qca_read_fw_board_id(hdev, &boardid);
+       /* Download NVM configuration */
+@@ -861,8 +874,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
+                                "qca/hpnv%02x.bin", rom_ver);
+                       break;
+               case QCA_WCN7850:
+-                      snprintf(config.fwname, sizeof(config.fwname),
+-                               "qca/hmtnv%02x.bin", rom_ver);
++                      qca_get_nvm_name_generic(&config, "hmt", rom_ver, boardid);
+                       break;
+               default:
+-- 
+2.39.5
+
diff --git a/queue-6.6/bluetooth-qca-update-firmware-name-to-support-board-.patch b/queue-6.6/bluetooth-qca-update-firmware-name-to-support-board-.patch
new file mode 100644 (file)
index 0000000..8aa22d9
--- /dev/null
@@ -0,0 +1,202 @@
+From 0b91e6fda0be5a9f47fe69281c88dc11592e8ace Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jan 2025 17:26:49 +0800
+Subject: Bluetooth: qca: Update firmware-name to support board specific nvm
+
+From: Cheng Jiang <quic_chejiang@quicinc.com>
+
+[ Upstream commit a4c5a468c6329bde7dfd46bacff2cbf5f8a8152e ]
+
+Different connectivity boards may be attached to the same platform. For
+example, QCA6698-based boards can support either a two-antenna or
+three-antenna solution, both of which work on the sa8775p-ride platform.
+Due to differences in connectivity boards and variations in RF
+performance from different foundries, different NVM configurations are
+used based on the board ID.
+
+Therefore, in the firmware-name property, if the NVM file has an
+extension, the NVM file will be used. Otherwise, the system will first
+try the .bNN (board ID) file, and if that fails, it will fall back to
+the .bin file.
+
+Possible configurations:
+firmware-name = "QCA6698/hpnv21";
+firmware-name = "QCA6698/hpnv21.bin";
+
+Signed-off-by: Cheng Jiang <quic_chejiang@quicinc.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: a2fad248947d ("Bluetooth: qca: Fix poor RF performance for WCN6855")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btqca.c | 113 ++++++++++++++++++++++++++++----------
+ 1 file changed, 85 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
+index 513ff87a7a049..484a860785fde 100644
+--- a/drivers/bluetooth/btqca.c
++++ b/drivers/bluetooth/btqca.c
+@@ -289,6 +289,39 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
+ }
+ EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd);
++static bool qca_filename_has_extension(const char *filename)
++{
++      const char *suffix = strrchr(filename, '.');
++
++      /* File extensions require a dot, but not as the first or last character */
++      if (!suffix || suffix == filename || *(suffix + 1) == '\0')
++              return 0;
++
++      /* Avoid matching directories with names that look like files with extensions */
++      return !strchr(suffix, '/');
++}
++
++static bool qca_get_alt_nvm_file(char *filename, size_t max_size)
++{
++      char fwname[64];
++      const char *suffix;
++
++      /* nvm file name has an extension, replace with .bin */
++      if (qca_filename_has_extension(filename)) {
++              suffix = strrchr(filename, '.');
++              strscpy(fwname, filename, suffix - filename + 1);
++              snprintf(fwname + (suffix - filename),
++                     sizeof(fwname) - (suffix - filename), ".bin");
++              /* If nvm file is already the default one, return false to skip the retry. */
++              if (strcmp(fwname, filename) == 0)
++                      return false;
++
++              snprintf(filename, max_size, "%s", fwname);
++              return true;
++      }
++      return false;
++}
++
+ static int qca_tlv_check_data(struct hci_dev *hdev,
+                              struct qca_fw_config *config,
+                              u8 *fw_data, size_t fw_size,
+@@ -586,6 +619,19 @@ static int qca_download_firmware(struct hci_dev *hdev,
+                                          config->fwname, ret);
+                               return ret;
+                       }
++              }
++              /* If the board-specific file is missing, try loading the default
++               * one, unless that was attempted already.
++               */
++              else if (config->type == TLV_TYPE_NVM &&
++                       qca_get_alt_nvm_file(config->fwname, sizeof(config->fwname))) {
++                      bt_dev_info(hdev, "QCA Downloading %s", config->fwname);
++                      ret = request_firmware(&fw, config->fwname, &hdev->dev);
++                      if (ret) {
++                              bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
++                                         config->fwname, ret);
++                              return ret;
++                      }
+               } else {
+                       bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
+                                  config->fwname, ret);
+@@ -722,34 +768,38 @@ static int qca_check_bdaddr(struct hci_dev *hdev, const struct qca_fw_config *co
+       return 0;
+ }
+-static void qca_generate_hsp_nvm_name(char *fwname, size_t max_size,
++static void qca_get_nvm_name_by_board(char *fwname, size_t max_size,
++              const char *stem, enum qca_btsoc_type soc_type,
+               struct qca_btsoc_version ver, u8 rom_ver, u16 bid)
+ {
+       const char *variant;
++      const char *prefix;
+-      /* hsp gf chip */
+-      if ((le32_to_cpu(ver.soc_id) & QCA_HSP_GF_SOC_MASK) == QCA_HSP_GF_SOC_ID)
+-              variant = "g";
+-      else
+-              variant = "";
++      /* Set the default value to variant and prefix */
++      variant = "";
++      prefix = "b";
+-      if (bid == 0x0)
+-              snprintf(fwname, max_size, "qca/hpnv%02x%s.bin", rom_ver, variant);
+-      else
+-              snprintf(fwname, max_size, "qca/hpnv%02x%s.%x", rom_ver, variant, bid);
+-}
++      if (soc_type == QCA_QCA2066)
++              prefix = "";
+-static inline void qca_get_nvm_name_generic(struct qca_fw_config *cfg,
+-                                          const char *stem, u8 rom_ver, u16 bid)
+-{
+-      if (bid == 0x0)
+-              snprintf(cfg->fwname, sizeof(cfg->fwname), "qca/%snv%02x.bin", stem, rom_ver);
+-      else if (bid & 0xff00)
+-              snprintf(cfg->fwname, sizeof(cfg->fwname),
+-                       "qca/%snv%02x.b%x", stem, rom_ver, bid);
+-      else
+-              snprintf(cfg->fwname, sizeof(cfg->fwname),
+-                       "qca/%snv%02x.b%02x", stem, rom_ver, bid);
++      if (soc_type == QCA_WCN6855 || soc_type == QCA_QCA2066) {
++              /* If the chip is manufactured by GlobalFoundries */
++              if ((le32_to_cpu(ver.soc_id) & QCA_HSP_GF_SOC_MASK) == QCA_HSP_GF_SOC_ID)
++                      variant = "g";
++      }
++
++      if (rom_ver != 0) {
++              if (bid == 0x0 || bid == 0xffff)
++                      snprintf(fwname, max_size, "qca/%s%02x%s.bin", stem, rom_ver, variant);
++              else
++                      snprintf(fwname, max_size, "qca/%s%02x%s.%s%02x", stem, rom_ver,
++                                              variant, prefix, bid);
++      } else {
++              if (bid == 0x0 || bid == 0xffff)
++                      snprintf(fwname, max_size, "qca/%s%s.bin", stem, variant);
++              else
++                      snprintf(fwname, max_size, "qca/%s%s.%s%02x", stem, variant, prefix, bid);
++      }
+ }
+ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
+@@ -838,8 +888,14 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
+       /* Download NVM configuration */
+       config.type = TLV_TYPE_NVM;
+       if (firmware_name) {
+-              snprintf(config.fwname, sizeof(config.fwname),
+-                       "qca/%s", firmware_name);
++              /* The firmware name has an extension, use it directly */
++              if (qca_filename_has_extension(firmware_name)) {
++                      snprintf(config.fwname, sizeof(config.fwname), "qca/%s", firmware_name);
++              } else {
++                      qca_read_fw_board_id(hdev, &boardid);
++                      qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname),
++                               firmware_name, soc_type, ver, 0, boardid);
++              }
+       } else {
+               switch (soc_type) {
+               case QCA_WCN3990:
+@@ -858,8 +914,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
+                                "qca/apnv%02x.bin", rom_ver);
+                       break;
+               case QCA_QCA2066:
+-                      qca_generate_hsp_nvm_name(config.fwname,
+-                              sizeof(config.fwname), ver, rom_ver, boardid);
++                      qca_get_nvm_name_by_board(config.fwname,
++                              sizeof(config.fwname), "hpnv", soc_type, ver,
++                              rom_ver, boardid);
+                       break;
+               case QCA_QCA6390:
+                       snprintf(config.fwname, sizeof(config.fwname),
+@@ -874,9 +931,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
+                                "qca/hpnv%02x.bin", rom_ver);
+                       break;
+               case QCA_WCN7850:
+-                      qca_get_nvm_name_generic(&config, "hmt", rom_ver, boardid);
++                      qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname),
++                               "hmtnv", soc_type, ver, rom_ver, boardid);
+                       break;
+-
+               default:
+                       snprintf(config.fwname, sizeof(config.fwname),
+                                "qca/nvm_%08x.bin", soc_ver);
+-- 
+2.39.5
+
diff --git a/queue-6.6/cpufreq-dt-platdev-add-missing-module_description-ma.patch b/queue-6.6/cpufreq-dt-platdev-add-missing-module_description-ma.patch
new file mode 100644 (file)
index 0000000..fa664ae
--- /dev/null
@@ -0,0 +1,35 @@
+From 049303b8b0223c93d891450bdd9ac547679e5d47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 Jun 2024 15:14:00 -0700
+Subject: cpufreq: dt-platdev: add missing MODULE_DESCRIPTION() macro
+
+From: Jeff Johnson <quic_jjohnson@quicinc.com>
+
+[ Upstream commit 64e018d7a8990c11734704a0767c47fd8efd5388 ]
+
+make allmodconfig && make W=1 C=1 reports:
+WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/cpufreq/cpufreq-dt-platdev.o
+
+Add the missing invocation of the MODULE_DESCRIPTION() macro.
+
+Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Stable-dep-of: f1f010c9d9c6 ("cpufreq: fix using cpufreq-dt as module")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/cpufreq-dt-platdev.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
+index fb2875ce1fdd5..99c31837084c0 100644
+--- a/drivers/cpufreq/cpufreq-dt-platdev.c
++++ b/drivers/cpufreq/cpufreq-dt-platdev.c
+@@ -225,4 +225,5 @@ static int __init cpufreq_dt_platdev_init(void)
+                              sizeof(struct cpufreq_dt_platform_data)));
+ }
+ core_initcall(cpufreq_dt_platdev_init);
++MODULE_DESCRIPTION("Generic DT based cpufreq platdev driver");
+ MODULE_LICENSE("GPL");
+-- 
+2.39.5
+
diff --git a/queue-6.6/cpufreq-fix-using-cpufreq-dt-as-module.patch b/queue-6.6/cpufreq-fix-using-cpufreq-dt-as-module.patch
new file mode 100644 (file)
index 0000000..c2eba7e
--- /dev/null
@@ -0,0 +1,67 @@
+From 059d6f9c5da44dfa4d60abb52d69aa56b7de81f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Nov 2024 22:02:51 +0100
+Subject: cpufreq: fix using cpufreq-dt as module
+
+From: Andreas Kemnade <andreas@kemnade.info>
+
+[ Upstream commit f1f010c9d9c62c865d9f54e94075800ba764b4d9 ]
+
+This driver can be built as a module since commit 3b062a086984 ("cpufreq:
+dt-platdev: Support building as module"), but unfortunately this caused
+a regression because the cputfreq-dt-platdev.ko module does not autoload.
+
+Usually, this is solved by just using the MODULE_DEVICE_TABLE() macro to
+export all the device IDs as module aliases. But this driver is special
+due how matches with devices and decides what platform supports.
+
+There are two of_device_id lists, an allow list that are for CPU devices
+that always match and a deny list that's for devices that must not match.
+
+The driver registers a cpufreq-dt platform device for all the CPU device
+nodes that either are in the allow list or contain an operating-points-v2
+property and are not in the deny list.
+
+Enforce builtin compile of cpufreq-dt-platdev to make autoload work.
+
+Fixes: 3b062a086984 ("cpufreq: dt-platdev: Support building as module")
+Link: https://lore.kernel.org/all/20241104201424.2a42efdd@akair/
+Link: https://lore.kernel.org/all/20241119111918.1732531-1-javierm@redhat.com/
+Cc: stable@vger.kernel.org
+Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
+Reported-by: Radu Rendec <rrendec@redhat.com>
+Reported-by: Javier Martinez Canillas <javierm@redhat.com>
+[ Viresh: Picked commit log from Javier, updated tags ]
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/Kconfig              | 2 +-
+ drivers/cpufreq/cpufreq-dt-platdev.c | 2 --
+ 2 files changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
+index f429b9b37b76c..7e773c47a4fcd 100644
+--- a/drivers/cpufreq/Kconfig
++++ b/drivers/cpufreq/Kconfig
+@@ -218,7 +218,7 @@ config CPUFREQ_DT
+         If in doubt, say N.
+ config CPUFREQ_DT_PLATDEV
+-      tristate "Generic DT based cpufreq platdev driver"
++      bool "Generic DT based cpufreq platdev driver"
+       depends on OF
+       help
+         This adds a generic DT based cpufreq platdev driver for frequency
+diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
+index 99c31837084c0..09becf14653b5 100644
+--- a/drivers/cpufreq/cpufreq-dt-platdev.c
++++ b/drivers/cpufreq/cpufreq-dt-platdev.c
+@@ -225,5 +225,3 @@ static int __init cpufreq_dt_platdev_init(void)
+                              sizeof(struct cpufreq_dt_platform_data)));
+ }
+ core_initcall(cpufreq_dt_platdev_init);
+-MODULE_DESCRIPTION("Generic DT based cpufreq platdev driver");
+-MODULE_LICENSE("GPL");
+-- 
+2.39.5
+
diff --git a/queue-6.6/firmware-qcom-scm-fix-missing-read-barrier-in-qcom_s.patch b/queue-6.6/firmware-qcom-scm-fix-missing-read-barrier-in-qcom_s.patch
new file mode 100644 (file)
index 0000000..c4067d4
--- /dev/null
@@ -0,0 +1,71 @@
+From 3299012631064cb83587e5113d6a97c5c426f119 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Dec 2024 15:27:54 +0100
+Subject: firmware: qcom: scm: Fix missing read barrier in
+ qcom_scm_is_available()
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 0a744cceebd0480cb39587b3b1339d66a9d14063 ]
+
+Commit 2e4955167ec5 ("firmware: qcom: scm: Fix __scm and waitq
+completion variable initialization") introduced a write barrier in probe
+function to store global '__scm' variable.  It also claimed that it
+added a read barrier, because as we all known barriers are paired (see
+memory-barriers.txt: "Note that write barriers should normally be paired
+with read or address-dependency barriers"), however it did not really
+add it.
+
+The offending commit used READ_ONCE() to access '__scm' global which is
+not a barrier.
+
+The barrier is needed so the store to '__scm' will be properly visible.
+This is most likely not fatal in current driver design, because missing
+read barrier would mean qcom_scm_is_available() callers will access old
+value, NULL.  Driver does not support unbinding and does not correctly
+handle probe failures, thus there is no risk of stale or old pointer in
+'__scm' variable.
+
+However for code correctness, readability and to be sure that we did not
+mess up something in this tricky topic of SMP barriers, add a read
+barrier for accessing '__scm'.  Change also comment from useless/obvious
+what does barrier do, to what is expected: which other parts of the code
+are involved here.
+
+Fixes: 2e4955167ec5 ("firmware: qcom: scm: Fix __scm and waitq completion variable initialization")
+Cc: stable@vger.kernel.org
+Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20241209-qcom-scm-missing-barriers-and-all-sort-of-srap-v2-1-9061013c8d92@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/qcom_scm.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
+index 7af59985f1c1f..4c5c2b73d42c2 100644
+--- a/drivers/firmware/qcom_scm.c
++++ b/drivers/firmware/qcom_scm.c
+@@ -1339,7 +1339,8 @@ static int qcom_scm_find_dload_address(struct device *dev, u64 *addr)
+  */
+ bool qcom_scm_is_available(void)
+ {
+-      return !!READ_ONCE(__scm);
++      /* Paired with smp_store_release() in qcom_scm_probe */
++      return !!smp_load_acquire(&__scm);
+ }
+ EXPORT_SYMBOL_GPL(qcom_scm_is_available);
+@@ -1457,7 +1458,7 @@ static int qcom_scm_probe(struct platform_device *pdev)
+       if (ret)
+               return ret;
+-      /* Let all above stores be available after this */
++      /* Paired with smp_load_acquire() in qcom_scm_is_available(). */
+       smp_store_release(&__scm, scm);
+       irq = platform_get_irq_optional(pdev, 0);
+-- 
+2.39.5
+
diff --git a/queue-6.6/flow_dissector-fix-handling-of-mixed-port-and-port-r.patch b/queue-6.6/flow_dissector-fix-handling-of-mixed-port-and-port-r.patch
new file mode 100644 (file)
index 0000000..865df0d
--- /dev/null
@@ -0,0 +1,94 @@
+From 567811550ccbfd43d388faa52630b8ac7ff7789b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 20:32:07 -0800
+Subject: flow_dissector: Fix handling of mixed port and port-range keys
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+[ Upstream commit 3e5796862c692ea608d96f0a1437f9290f44953a ]
+
+This patch fixes a bug in TC flower filter where rules combining a
+specific destination port with a source port range weren't working
+correctly.
+
+The specific case was when users tried to configure rules like:
+
+tc filter add dev ens38 ingress protocol ip flower ip_proto udp \
+dst_port 5000 src_port 2000-3000 action drop
+
+The root cause was in the flow dissector code. While both
+FLOW_DISSECTOR_KEY_PORTS and FLOW_DISSECTOR_KEY_PORTS_RANGE flags
+were being set correctly in the classifier, the __skb_flow_dissect_ports()
+function was only populating one of them: whichever came first in
+the enum check. This meant that when the code needed both a specific
+port and a port range, one of them would be left as 0, causing the
+filter to not match packets as expected.
+
+Fix it by removing the either/or logic and instead checking and
+populating both key types independently when they're in use.
+
+Fixes: 8ffb055beae5 ("cls_flower: Fix the behavior using port ranges with hw-offload")
+Reported-by: Qiang Zhang <dtzq01@gmail.com>
+Closes: https://lore.kernel.org/netdev/CAPx+-5uvFxkhkz4=j_Xuwkezjn9U6kzKTD5jz4tZ9msSJ0fOJA@mail.gmail.com/
+Cc: Yoshiki Komachi <komachi.yoshiki@gmail.com>
+Cc: Jamal Hadi Salim <jhs@mojatatu.com>
+Cc: Jiri Pirko <jiri@resnulli.us>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20250218043210.732959-2-xiyou.wangcong@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/flow_dissector.c | 31 +++++++++++++++++++------------
+ 1 file changed, 19 insertions(+), 12 deletions(-)
+
+diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
+index 00a5c41c1831d..842da66034158 100644
+--- a/net/core/flow_dissector.c
++++ b/net/core/flow_dissector.c
+@@ -829,23 +829,30 @@ __skb_flow_dissect_ports(const struct sk_buff *skb,
+                        void *target_container, const void *data,
+                        int nhoff, u8 ip_proto, int hlen)
+ {
+-      enum flow_dissector_key_id dissector_ports = FLOW_DISSECTOR_KEY_MAX;
+-      struct flow_dissector_key_ports *key_ports;
++      struct flow_dissector_key_ports_range *key_ports_range = NULL;
++      struct flow_dissector_key_ports *key_ports = NULL;
++      __be32 ports;
+       if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS))
+-              dissector_ports = FLOW_DISSECTOR_KEY_PORTS;
+-      else if (dissector_uses_key(flow_dissector,
+-                                  FLOW_DISSECTOR_KEY_PORTS_RANGE))
+-              dissector_ports = FLOW_DISSECTOR_KEY_PORTS_RANGE;
++              key_ports = skb_flow_dissector_target(flow_dissector,
++                                                    FLOW_DISSECTOR_KEY_PORTS,
++                                                    target_container);
+-      if (dissector_ports == FLOW_DISSECTOR_KEY_MAX)
++      if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS_RANGE))
++              key_ports_range = skb_flow_dissector_target(flow_dissector,
++                                                          FLOW_DISSECTOR_KEY_PORTS_RANGE,
++                                                          target_container);
++
++      if (!key_ports && !key_ports_range)
+               return;
+-      key_ports = skb_flow_dissector_target(flow_dissector,
+-                                            dissector_ports,
+-                                            target_container);
+-      key_ports->ports = __skb_flow_get_ports(skb, nhoff, ip_proto,
+-                                              data, hlen);
++      ports = __skb_flow_get_ports(skb, nhoff, ip_proto, data, hlen);
++
++      if (key_ports)
++              key_ports->ports = ports;
++
++      if (key_ports_range)
++              key_ports_range->tp.ports = ports;
+ }
+ static void
+-- 
+2.39.5
+
diff --git a/queue-6.6/flow_dissector-fix-port-range-key-handling-in-bpf-co.patch b/queue-6.6/flow_dissector-fix-port-range-key-handling-in-bpf-co.patch
new file mode 100644 (file)
index 0000000..af155cd
--- /dev/null
@@ -0,0 +1,76 @@
+From 299b599ee3fcf1fc072e14505cbf59ffeb6b01e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 20:32:09 -0800
+Subject: flow_dissector: Fix port range key handling in BPF conversion
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+[ Upstream commit 69ab34f705fbfabcace64b5d53bb7a4450fac875 ]
+
+Fix how port range keys are handled in __skb_flow_bpf_to_target() by:
+- Separating PORTS and PORTS_RANGE key handling
+- Using correct key_ports_range structure for range keys
+- Properly initializing both key types independently
+
+This ensures port range information is correctly stored in its dedicated
+structure rather than incorrectly using the regular ports key structure.
+
+Fixes: 59fb9b62fb6c ("flow_dissector: Fix to use new variables for port ranges in bpf hook")
+Reported-by: Qiang Zhang <dtzq01@gmail.com>
+Closes: https://lore.kernel.org/netdev/CAPx+-5uvFxkhkz4=j_Xuwkezjn9U6kzKTD5jz4tZ9msSJ0fOJA@mail.gmail.com/
+Cc: Yoshiki Komachi <komachi.yoshiki@gmail.com>
+Cc: Jamal Hadi Salim <jhs@mojatatu.com>
+Cc: Jiri Pirko <jiri@resnulli.us>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Link: https://patch.msgid.link/20250218043210.732959-4-xiyou.wangcong@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/flow_dissector.c | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
+index 842da66034158..aafa754b6cbab 100644
+--- a/net/core/flow_dissector.c
++++ b/net/core/flow_dissector.c
+@@ -907,6 +907,7 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys,
+                                    struct flow_dissector *flow_dissector,
+                                    void *target_container)
+ {
++      struct flow_dissector_key_ports_range *key_ports_range = NULL;
+       struct flow_dissector_key_ports *key_ports = NULL;
+       struct flow_dissector_key_control *key_control;
+       struct flow_dissector_key_basic *key_basic;
+@@ -951,20 +952,21 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys,
+               key_control->addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
+       }
+-      if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS))
++      if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS)) {
+               key_ports = skb_flow_dissector_target(flow_dissector,
+                                                     FLOW_DISSECTOR_KEY_PORTS,
+                                                     target_container);
+-      else if (dissector_uses_key(flow_dissector,
+-                                  FLOW_DISSECTOR_KEY_PORTS_RANGE))
+-              key_ports = skb_flow_dissector_target(flow_dissector,
+-                                                    FLOW_DISSECTOR_KEY_PORTS_RANGE,
+-                                                    target_container);
+-
+-      if (key_ports) {
+               key_ports->src = flow_keys->sport;
+               key_ports->dst = flow_keys->dport;
+       }
++      if (dissector_uses_key(flow_dissector,
++                             FLOW_DISSECTOR_KEY_PORTS_RANGE)) {
++              key_ports_range = skb_flow_dissector_target(flow_dissector,
++                                                          FLOW_DISSECTOR_KEY_PORTS_RANGE,
++                                                          target_container);
++              key_ports_range->tp.src = flow_keys->sport;
++              key_ports_range->tp.dst = flow_keys->dport;
++      }
+       if (dissector_uses_key(flow_dissector,
+                              FLOW_DISSECTOR_KEY_FLOW_LABEL)) {
+-- 
+2.39.5
+
diff --git a/queue-6.6/geneve-fix-use-after-free-in-geneve_find_dev.patch b/queue-6.6/geneve-fix-use-after-free-in-geneve_find_dev.patch
new file mode 100644 (file)
index 0000000..fcf2f9c
--- /dev/null
@@ -0,0 +1,200 @@
+From f8e727b85c174ba5c295a9b1fd9aa73fced4c5c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Feb 2025 13:33:54 +0900
+Subject: geneve: Fix use-after-free in geneve_find_dev().
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 9593172d93b9f91c362baec4643003dc29802929 ]
+
+syzkaller reported a use-after-free in geneve_find_dev() [0]
+without repro.
+
+geneve_configure() links struct geneve_dev.next to
+net_generic(net, geneve_net_id)->geneve_list.
+
+The net here could differ from dev_net(dev) if IFLA_NET_NS_PID,
+IFLA_NET_NS_FD, or IFLA_TARGET_NETNSID is set.
+
+When dev_net(dev) is dismantled, geneve_exit_batch_rtnl() finally
+calls unregister_netdevice_queue() for each dev in the netns,
+and later the dev is freed.
+
+However, its geneve_dev.next is still linked to the backend UDP
+socket netns.
+
+Then, use-after-free will occur when another geneve dev is created
+in the netns.
+
+Let's call geneve_dellink() instead in geneve_destroy_tunnels().
+
+[0]:
+BUG: KASAN: slab-use-after-free in geneve_find_dev drivers/net/geneve.c:1295 [inline]
+BUG: KASAN: slab-use-after-free in geneve_configure+0x234/0x858 drivers/net/geneve.c:1343
+Read of size 2 at addr ffff000054d6ee24 by task syz.1.4029/13441
+
+CPU: 1 UID: 0 PID: 13441 Comm: syz.1.4029 Not tainted 6.13.0-g0ad9617c78ac #24 dc35ca22c79fb82e8e7bc5c9c9adafea898b1e3d
+Hardware name: linux,dummy-virt (DT)
+Call trace:
+ show_stack+0x38/0x50 arch/arm64/kernel/stacktrace.c:466 (C)
+ __dump_stack lib/dump_stack.c:94 [inline]
+ dump_stack_lvl+0xbc/0x108 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378 [inline]
+ print_report+0x16c/0x6f0 mm/kasan/report.c:489
+ kasan_report+0xc0/0x120 mm/kasan/report.c:602
+ __asan_report_load2_noabort+0x20/0x30 mm/kasan/report_generic.c:379
+ geneve_find_dev drivers/net/geneve.c:1295 [inline]
+ geneve_configure+0x234/0x858 drivers/net/geneve.c:1343
+ geneve_newlink+0xb8/0x128 drivers/net/geneve.c:1634
+ rtnl_newlink_create+0x23c/0x868 net/core/rtnetlink.c:3795
+ __rtnl_newlink net/core/rtnetlink.c:3906 [inline]
+ rtnl_newlink+0x1054/0x1630 net/core/rtnetlink.c:4021
+ rtnetlink_rcv_msg+0x61c/0x918 net/core/rtnetlink.c:6911
+ netlink_rcv_skb+0x1dc/0x398 net/netlink/af_netlink.c:2543
+ rtnetlink_rcv+0x34/0x50 net/core/rtnetlink.c:6938
+ netlink_unicast_kernel net/netlink/af_netlink.c:1322 [inline]
+ netlink_unicast+0x618/0x838 net/netlink/af_netlink.c:1348
+ netlink_sendmsg+0x5fc/0x8b0 net/netlink/af_netlink.c:1892
+ sock_sendmsg_nosec net/socket.c:713 [inline]
+ __sock_sendmsg net/socket.c:728 [inline]
+ ____sys_sendmsg+0x410/0x6f8 net/socket.c:2568
+ ___sys_sendmsg+0x178/0x1d8 net/socket.c:2622
+ __sys_sendmsg net/socket.c:2654 [inline]
+ __do_sys_sendmsg net/socket.c:2659 [inline]
+ __se_sys_sendmsg net/socket.c:2657 [inline]
+ __arm64_sys_sendmsg+0x12c/0x1c8 net/socket.c:2657
+ __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
+ invoke_syscall+0x90/0x278 arch/arm64/kernel/syscall.c:49
+ el0_svc_common+0x13c/0x250 arch/arm64/kernel/syscall.c:132
+ do_el0_svc+0x54/0x70 arch/arm64/kernel/syscall.c:151
+ el0_svc+0x4c/0xa8 arch/arm64/kernel/entry-common.c:744
+ el0t_64_sync_handler+0x78/0x108 arch/arm64/kernel/entry-common.c:762
+ el0t_64_sync+0x198/0x1a0 arch/arm64/kernel/entry.S:600
+
+Allocated by task 13247:
+ kasan_save_stack mm/kasan/common.c:47 [inline]
+ kasan_save_track+0x30/0x68 mm/kasan/common.c:68
+ kasan_save_alloc_info+0x44/0x58 mm/kasan/generic.c:568
+ poison_kmalloc_redzone mm/kasan/common.c:377 [inline]
+ __kasan_kmalloc+0x84/0xa0 mm/kasan/common.c:394
+ kasan_kmalloc include/linux/kasan.h:260 [inline]
+ __do_kmalloc_node mm/slub.c:4298 [inline]
+ __kmalloc_node_noprof+0x2a0/0x560 mm/slub.c:4304
+ __kvmalloc_node_noprof+0x9c/0x230 mm/util.c:645
+ alloc_netdev_mqs+0xb8/0x11a0 net/core/dev.c:11470
+ rtnl_create_link+0x2b8/0xb50 net/core/rtnetlink.c:3604
+ rtnl_newlink_create+0x19c/0x868 net/core/rtnetlink.c:3780
+ __rtnl_newlink net/core/rtnetlink.c:3906 [inline]
+ rtnl_newlink+0x1054/0x1630 net/core/rtnetlink.c:4021
+ rtnetlink_rcv_msg+0x61c/0x918 net/core/rtnetlink.c:6911
+ netlink_rcv_skb+0x1dc/0x398 net/netlink/af_netlink.c:2543
+ rtnetlink_rcv+0x34/0x50 net/core/rtnetlink.c:6938
+ netlink_unicast_kernel net/netlink/af_netlink.c:1322 [inline]
+ netlink_unicast+0x618/0x838 net/netlink/af_netlink.c:1348
+ netlink_sendmsg+0x5fc/0x8b0 net/netlink/af_netlink.c:1892
+ sock_sendmsg_nosec net/socket.c:713 [inline]
+ __sock_sendmsg net/socket.c:728 [inline]
+ ____sys_sendmsg+0x410/0x6f8 net/socket.c:2568
+ ___sys_sendmsg+0x178/0x1d8 net/socket.c:2622
+ __sys_sendmsg net/socket.c:2654 [inline]
+ __do_sys_sendmsg net/socket.c:2659 [inline]
+ __se_sys_sendmsg net/socket.c:2657 [inline]
+ __arm64_sys_sendmsg+0x12c/0x1c8 net/socket.c:2657
+ __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
+ invoke_syscall+0x90/0x278 arch/arm64/kernel/syscall.c:49
+ el0_svc_common+0x13c/0x250 arch/arm64/kernel/syscall.c:132
+ do_el0_svc+0x54/0x70 arch/arm64/kernel/syscall.c:151
+ el0_svc+0x4c/0xa8 arch/arm64/kernel/entry-common.c:744
+ el0t_64_sync_handler+0x78/0x108 arch/arm64/kernel/entry-common.c:762
+ el0t_64_sync+0x198/0x1a0 arch/arm64/kernel/entry.S:600
+
+Freed by task 45:
+ kasan_save_stack mm/kasan/common.c:47 [inline]
+ kasan_save_track+0x30/0x68 mm/kasan/common.c:68
+ kasan_save_free_info+0x58/0x70 mm/kasan/generic.c:582
+ poison_slab_object mm/kasan/common.c:247 [inline]
+ __kasan_slab_free+0x48/0x68 mm/kasan/common.c:264
+ kasan_slab_free include/linux/kasan.h:233 [inline]
+ slab_free_hook mm/slub.c:2353 [inline]
+ slab_free mm/slub.c:4613 [inline]
+ kfree+0x140/0x420 mm/slub.c:4761
+ kvfree+0x4c/0x68 mm/util.c:688
+ netdev_release+0x94/0xc8 net/core/net-sysfs.c:2065
+ device_release+0x98/0x1c0
+ kobject_cleanup lib/kobject.c:689 [inline]
+ kobject_release lib/kobject.c:720 [inline]
+ kref_put include/linux/kref.h:65 [inline]
+ kobject_put+0x2b0/0x438 lib/kobject.c:737
+ netdev_run_todo+0xe5c/0xfc8 net/core/dev.c:11185
+ rtnl_unlock+0x20/0x38 net/core/rtnetlink.c:151
+ cleanup_net+0x4fc/0x8c0 net/core/net_namespace.c:648
+ process_one_work+0x700/0x1398 kernel/workqueue.c:3236
+ process_scheduled_works kernel/workqueue.c:3317 [inline]
+ worker_thread+0x8c4/0xe10 kernel/workqueue.c:3398
+ kthread+0x4bc/0x608 kernel/kthread.c:464
+ ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:862
+
+The buggy address belongs to the object at ffff000054d6e000
+ which belongs to the cache kmalloc-cg-4k of size 4096
+The buggy address is located 3620 bytes inside of
+ freed 4096-byte region [ffff000054d6e000, ffff000054d6f000)
+
+The buggy address belongs to the physical page:
+page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x94d68
+head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
+memcg:ffff000016276181
+flags: 0x3fffe0000000040(head|node=0|zone=0|lastcpupid=0x1ffff)
+page_type: f5(slab)
+raw: 03fffe0000000040 ffff0000c000f500 dead000000000122 0000000000000000
+raw: 0000000000000000 0000000000040004 00000001f5000000 ffff000016276181
+head: 03fffe0000000040 ffff0000c000f500 dead000000000122 0000000000000000
+head: 0000000000000000 0000000000040004 00000001f5000000 ffff000016276181
+head: 03fffe0000000003 fffffdffc1535a01 ffffffffffffffff 0000000000000000
+head: 0000000000000008 0000000000000000 00000000ffffffff 0000000000000000
+page dumped because: kasan: bad access detected
+
+Memory state around the buggy address:
+ ffff000054d6ed00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ffff000054d6ed80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+>ffff000054d6ee00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+                               ^
+ ffff000054d6ee80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ffff000054d6ef00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+
+Fixes: 2d07dc79fe04 ("geneve: add initial netdev driver for GENEVE tunnels")
+Reported-by: syzkaller <syzkaller@googlegroups.com>
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20250213043354.91368-1-kuniyu@amazon.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/geneve.c | 11 +++--------
+ 1 file changed, 3 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
+index b939d4711c59b..c2066f19295d4 100644
+--- a/drivers/net/geneve.c
++++ b/drivers/net/geneve.c
+@@ -1966,16 +1966,11 @@ static void geneve_destroy_tunnels(struct net *net, struct list_head *head)
+       /* gather any geneve devices that were moved into this ns */
+       for_each_netdev_safe(net, dev, aux)
+               if (dev->rtnl_link_ops == &geneve_link_ops)
+-                      unregister_netdevice_queue(dev, head);
++                      geneve_dellink(dev, head);
+       /* now gather any other geneve devices that were created in this ns */
+-      list_for_each_entry_safe(geneve, next, &gn->geneve_list, next) {
+-              /* If geneve->dev is in the same netns, it was already added
+-               * to the list by the previous loop.
+-               */
+-              if (!net_eq(dev_net(geneve->dev), net))
+-                      unregister_netdevice_queue(geneve->dev, head);
+-      }
++      list_for_each_entry_safe(geneve, next, &gn->geneve_list, next)
++              geneve_dellink(geneve->dev, head);
+ }
+ static void __net_exit geneve_exit_batch_net(struct list_head *net_list)
+-- 
+2.39.5
+
diff --git a/queue-6.6/geneve-suppress-list-corruption-splat-in-geneve_dest.patch b/queue-6.6/geneve-suppress-list-corruption-splat-in-geneve_dest.patch
new file mode 100644 (file)
index 0000000..6551aac
--- /dev/null
@@ -0,0 +1,50 @@
+From c7148408e5f0552bd4c5cd444b45823bc5c92a80 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 12:37:05 -0800
+Subject: geneve: Suppress list corruption splat in geneve_destroy_tunnels().
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 62fab6eef61f245dc8797e3a6a5b890ef40e8628 ]
+
+As explained in the previous patch, iterating for_each_netdev() and
+gn->geneve_list during ->exit_batch_rtnl() could trigger ->dellink()
+twice for the same device.
+
+If CONFIG_DEBUG_LIST is enabled, we will see a list_del() corruption
+splat in the 2nd call of geneve_dellink().
+
+Let's remove for_each_netdev() in geneve_destroy_tunnels() and delegate
+that part to default_device_exit_batch().
+
+Fixes: 9593172d93b9 ("geneve: Fix use-after-free in geneve_find_dev().")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20250217203705.40342-3-kuniyu@amazon.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/geneve.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
+index c2066f19295d4..27761334e1bff 100644
+--- a/drivers/net/geneve.c
++++ b/drivers/net/geneve.c
+@@ -1961,14 +1961,7 @@ static void geneve_destroy_tunnels(struct net *net, struct list_head *head)
+ {
+       struct geneve_net *gn = net_generic(net, geneve_net_id);
+       struct geneve_dev *geneve, *next;
+-      struct net_device *dev, *aux;
+-      /* gather any geneve devices that were moved into this ns */
+-      for_each_netdev_safe(net, dev, aux)
+-              if (dev->rtnl_link_ops == &geneve_link_ops)
+-                      geneve_dellink(dev, head);
+-
+-      /* now gather any other geneve devices that were created in this ns */
+       list_for_each_entry_safe(geneve, next, &gn->geneve_list, next)
+               geneve_dellink(geneve->dev, head);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.6/gtp-suppress-list-corruption-splat-in-gtp_net_exit_b.patch b/queue-6.6/gtp-suppress-list-corruption-splat-in-gtp_net_exit_b.patch
new file mode 100644 (file)
index 0000000..cfa7da7
--- /dev/null
@@ -0,0 +1,121 @@
+From 863141e4608c723c030afd25c73cf78bf37ae7de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 12:37:04 -0800
+Subject: gtp: Suppress list corruption splat in gtp_net_exit_batch_rtnl().
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 4ccacf86491d33d2486b62d4d44864d7101b299d ]
+
+Brad Spengler reported the list_del() corruption splat in
+gtp_net_exit_batch_rtnl(). [0]
+
+Commit eb28fd76c0a0 ("gtp: Destroy device along with udp socket's netns
+dismantle.") added the for_each_netdev() loop in gtp_net_exit_batch_rtnl()
+to destroy devices in each netns as done in geneve and ip tunnels.
+
+However, this could trigger ->dellink() twice for the same device during
+->exit_batch_rtnl().
+
+Say we have two netns A & B and gtp device B that resides in netns B but
+whose UDP socket is in netns A.
+
+  1. cleanup_net() processes netns A and then B.
+
+  2. gtp_net_exit_batch_rtnl() finds the device B while iterating
+     netns A's gn->gtp_dev_list and calls ->dellink().
+
+  [ device B is not yet unlinked from netns B
+    as unregister_netdevice_many() has not been called. ]
+
+  3. gtp_net_exit_batch_rtnl() finds the device B while iterating
+     netns B's for_each_netdev() and calls ->dellink().
+
+gtp_dellink() cleans up the device's hash table, unlinks the dev from
+gn->gtp_dev_list, and calls unregister_netdevice_queue().
+
+Basically, calling gtp_dellink() multiple times is fine unless
+CONFIG_DEBUG_LIST is enabled.
+
+Let's remove for_each_netdev() in gtp_net_exit_batch_rtnl() and
+delegate the destruction to default_device_exit_batch() as done
+in bareudp.
+
+[0]:
+list_del corruption, ffff8880aaa62c00->next (autoslab_size_M_dev_P_net_core_dev_11127_8_1328_8_S_4096_A_64_n_139+0xc00/0x1000 [slab object]) is LIST_POISON1 (ffffffffffffff02) (prev is 0xffffffffffffff04)
+kernel BUG at lib/list_debug.c:58!
+Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN
+CPU: 1 UID: 0 PID: 1804 Comm: kworker/u8:7 Tainted: G                T   6.12.13-grsec-full-20250211091339 #1
+Tainted: [T]=RANDSTRUCT
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
+Workqueue: netns cleanup_net
+RIP: 0010:[<ffffffff84947381>] __list_del_entry_valid_or_report+0x141/0x200 lib/list_debug.c:58
+Code: c2 76 91 31 c0 e8 9f b1 f7 fc 0f 0b 4d 89 f0 48 c7 c1 02 ff ff ff 48 89 ea 48 89 ee 48 c7 c7 e0 c2 76 91 31 c0 e8 7f b1 f7 fc <0f> 0b 4d 89 e8 48 c7 c1 04 ff ff ff 48 89 ea 48 89 ee 48 c7 c7 60
+RSP: 0018:fffffe8040b4fbd0 EFLAGS: 00010283
+RAX: 00000000000000cc RBX: dffffc0000000000 RCX: ffffffff818c4054
+RDX: ffffffff84947381 RSI: ffffffff818d1512 RDI: 0000000000000000
+RBP: ffff8880aaa62c00 R08: 0000000000000001 R09: fffffbd008169f32
+R10: fffffe8040b4f997 R11: 0000000000000001 R12: a1988d84f24943e4
+R13: ffffffffffffff02 R14: ffffffffffffff04 R15: ffff8880aaa62c08
+RBX: kasan shadow of 0x0
+RCX: __wake_up_klogd.part.0+0x74/0xe0 kernel/printk/printk.c:4554
+RDX: __list_del_entry_valid_or_report+0x141/0x200 lib/list_debug.c:58
+RSI: vprintk+0x72/0x100 kernel/printk/printk_safe.c:71
+RBP: autoslab_size_M_dev_P_net_core_dev_11127_8_1328_8_S_4096_A_64_n_139+0xc00/0x1000 [slab object]
+RSP: process kstack fffffe8040b4fbd0+0x7bd0/0x8000 [kworker/u8:7+netns 1804 ]
+R09: kasan shadow of process kstack fffffe8040b4f990+0x7990/0x8000 [kworker/u8:7+netns 1804 ]
+R10: process kstack fffffe8040b4f997+0x7997/0x8000 [kworker/u8:7+netns 1804 ]
+R15: autoslab_size_M_dev_P_net_core_dev_11127_8_1328_8_S_4096_A_64_n_139+0xc08/0x1000 [slab object]
+FS:  0000000000000000(0000) GS:ffff888116000000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 0000748f5372c000 CR3: 0000000015408000 CR4: 00000000003406f0 shadow CR4: 00000000003406f0
+Stack:
+ 0000000000000000 ffffffff8a0c35e7 ffffffff8a0c3603 ffff8880aaa62c00
+ ffff8880aaa62c00 0000000000000004 ffff88811145311c 0000000000000005
+ 0000000000000001 ffff8880aaa62000 fffffe8040b4fd40 ffffffff8a0c360d
+Call Trace:
+ <TASK>
+ [<ffffffff8a0c360d>] __list_del_entry_valid include/linux/list.h:131 [inline] fffffe8040b4fc28
+ [<ffffffff8a0c360d>] __list_del_entry include/linux/list.h:248 [inline] fffffe8040b4fc28
+ [<ffffffff8a0c360d>] list_del include/linux/list.h:262 [inline] fffffe8040b4fc28
+ [<ffffffff8a0c360d>] gtp_dellink+0x16d/0x360 drivers/net/gtp.c:1557 fffffe8040b4fc28
+ [<ffffffff8a0d0404>] gtp_net_exit_batch_rtnl+0x124/0x2c0 drivers/net/gtp.c:2495 fffffe8040b4fc88
+ [<ffffffff8e705b24>] cleanup_net+0x5a4/0xbe0 net/core/net_namespace.c:635 fffffe8040b4fcd0
+ [<ffffffff81754c97>] process_one_work+0xbd7/0x2160 kernel/workqueue.c:3326 fffffe8040b4fd88
+ [<ffffffff81757195>] process_scheduled_works kernel/workqueue.c:3407 [inline] fffffe8040b4fec0
+ [<ffffffff81757195>] worker_thread+0x6b5/0xfa0 kernel/workqueue.c:3488 fffffe8040b4fec0
+ [<ffffffff817782a0>] kthread+0x360/0x4c0 kernel/kthread.c:397 fffffe8040b4ff78
+ [<ffffffff814d8594>] ret_from_fork+0x74/0xe0 arch/x86/kernel/process.c:172 fffffe8040b4ffb8
+ [<ffffffff8110f509>] ret_from_fork_asm+0x29/0xc0 arch/x86/entry/entry_64.S:399 fffffe8040b4ffe8
+ </TASK>
+Modules linked in:
+
+Fixes: eb28fd76c0a0 ("gtp: Destroy device along with udp socket's netns dismantle.")
+Reported-by: Brad Spengler <spender@grsecurity.net>
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20250217203705.40342-2-kuniyu@amazon.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/gtp.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
+index 47238c3ec82e7..55160a5fc90fc 100644
+--- a/drivers/net/gtp.c
++++ b/drivers/net/gtp.c
+@@ -1895,11 +1895,6 @@ static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list,
+       list_for_each_entry(net, net_list, exit_list) {
+               struct gtp_net *gn = net_generic(net, gtp_net_id);
+               struct gtp_dev *gtp, *gtp_next;
+-              struct net_device *dev;
+-
+-              for_each_netdev(net, dev)
+-                      if (dev->rtnl_link_ops == &gtp_link_ops)
+-                              gtp_dellink(dev, dev_to_kill);
+               list_for_each_entry_safe(gtp, gtp_next, &gn->gtp_dev_list, list)
+                       gtp_dellink(gtp->dev, dev_to_kill);
+-- 
+2.39.5
+
diff --git a/queue-6.6/ibmvnic-add-stat-for-tx-direct-vs-tx-batched.patch b/queue-6.6/ibmvnic-add-stat-for-tx-direct-vs-tx-batched.patch
new file mode 100644 (file)
index 0000000..0ff0bfe
--- /dev/null
@@ -0,0 +1,127 @@
+From cbeebd53e54f7e37837331e317166a3d2e86b0aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Oct 2024 11:35:31 -0500
+Subject: ibmvnic: Add stat for tx direct vs tx batched
+
+From: Nick Child <nnac123@linux.ibm.com>
+
+[ Upstream commit 2ee73c54a615b74d2e7ee6f20844fd3ba63fc485 ]
+
+Allow tracking of packets sent with send_subcrq direct vs
+indirect. `ethtool -S <dev>` will now provide a counter
+of the number of uses of each xmit method. This metric will
+be useful in performance debugging.
+
+Signed-off-by: Nick Child <nnac123@linux.ibm.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20241001163531.1803152-1-nnac123@linux.ibm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: bdf5d13aa05e ("ibmvnic: Don't reference skb after sending to VIOS")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 23 ++++++++++++++++-------
+ drivers/net/ethernet/ibm/ibmvnic.h |  3 ++-
+ 2 files changed, 18 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index e2e4a1a2fa74f..cd5224f6c42a3 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -2326,7 +2326,7 @@ static void ibmvnic_tx_scrq_clean_buffer(struct ibmvnic_adapter *adapter,
+               tx_buff = &tx_pool->tx_buff[index];
+               adapter->netdev->stats.tx_packets--;
+               adapter->netdev->stats.tx_bytes -= tx_buff->skb->len;
+-              adapter->tx_stats_buffers[queue_num].packets--;
++              adapter->tx_stats_buffers[queue_num].batched_packets--;
+               adapter->tx_stats_buffers[queue_num].bytes -=
+                                               tx_buff->skb->len;
+               dev_kfree_skb_any(tx_buff->skb);
+@@ -2418,7 +2418,8 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
+       unsigned int tx_map_failed = 0;
+       union sub_crq indir_arr[16];
+       unsigned int tx_dropped = 0;
+-      unsigned int tx_packets = 0;
++      unsigned int tx_dpackets = 0;
++      unsigned int tx_bpackets = 0;
+       unsigned int tx_bytes = 0;
+       dma_addr_t data_dma_addr;
+       struct netdev_queue *txq;
+@@ -2577,6 +2578,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
+               if (lpar_rc != H_SUCCESS)
+                       goto tx_err;
++              tx_dpackets++;
+               goto early_exit;
+       }
+@@ -2605,6 +2607,8 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
+                       goto tx_err;
+       }
++      tx_bpackets++;
++
+ early_exit:
+       if (atomic_add_return(num_entries, &tx_scrq->used)
+                                       >= adapter->req_tx_entries_per_subcrq) {
+@@ -2612,7 +2616,6 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
+               netif_stop_subqueue(netdev, queue_num);
+       }
+-      tx_packets++;
+       tx_bytes += skb->len;
+       txq_trans_cond_update(txq);
+       ret = NETDEV_TX_OK;
+@@ -2642,10 +2645,11 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
+       rcu_read_unlock();
+       netdev->stats.tx_dropped += tx_dropped;
+       netdev->stats.tx_bytes += tx_bytes;
+-      netdev->stats.tx_packets += tx_packets;
++      netdev->stats.tx_packets += tx_bpackets + tx_dpackets;
+       adapter->tx_send_failed += tx_send_failed;
+       adapter->tx_map_failed += tx_map_failed;
+-      adapter->tx_stats_buffers[queue_num].packets += tx_packets;
++      adapter->tx_stats_buffers[queue_num].batched_packets += tx_bpackets;
++      adapter->tx_stats_buffers[queue_num].direct_packets += tx_dpackets;
+       adapter->tx_stats_buffers[queue_num].bytes += tx_bytes;
+       adapter->tx_stats_buffers[queue_num].dropped_packets += tx_dropped;
+@@ -3811,7 +3815,10 @@ static void ibmvnic_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+               memcpy(data, ibmvnic_stats[i].name, ETH_GSTRING_LEN);
+       for (i = 0; i < adapter->req_tx_queues; i++) {
+-              snprintf(data, ETH_GSTRING_LEN, "tx%d_packets", i);
++              snprintf(data, ETH_GSTRING_LEN, "tx%d_batched_packets", i);
++              data += ETH_GSTRING_LEN;
++
++              snprintf(data, ETH_GSTRING_LEN, "tx%d_direct_packets", i);
+               data += ETH_GSTRING_LEN;
+               snprintf(data, ETH_GSTRING_LEN, "tx%d_bytes", i);
+@@ -3876,7 +3883,9 @@ static void ibmvnic_get_ethtool_stats(struct net_device *dev,
+                                     (adapter, ibmvnic_stats[i].offset));
+       for (j = 0; j < adapter->req_tx_queues; j++) {
+-              data[i] = adapter->tx_stats_buffers[j].packets;
++              data[i] = adapter->tx_stats_buffers[j].batched_packets;
++              i++;
++              data[i] = adapter->tx_stats_buffers[j].direct_packets;
+               i++;
+               data[i] = adapter->tx_stats_buffers[j].bytes;
+               i++;
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h
+index 4e18b4cefa972..b3fc18db4f4c3 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.h
++++ b/drivers/net/ethernet/ibm/ibmvnic.h
+@@ -213,7 +213,8 @@ struct ibmvnic_statistics {
+ #define NUM_TX_STATS 3
+ struct ibmvnic_tx_queue_stats {
+-      u64 packets;
++      u64 batched_packets;
++      u64 direct_packets;
+       u64 bytes;
+       u64 dropped_packets;
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.6/ibmvnic-don-t-reference-skb-after-sending-to-vios.patch b/queue-6.6/ibmvnic-don-t-reference-skb-after-sending-to-vios.patch
new file mode 100644 (file)
index 0000000..dfd0540
--- /dev/null
@@ -0,0 +1,85 @@
+From 80da7f18ac58a97bb2d25870f7fe8c13ff8ac8c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Feb 2025 09:52:33 -0600
+Subject: ibmvnic: Don't reference skb after sending to VIOS
+
+From: Nick Child <nnac123@linux.ibm.com>
+
+[ Upstream commit bdf5d13aa05ec314d4385b31ac974d6c7e0997c9 ]
+
+Previously, after successfully flushing the xmit buffer to VIOS,
+the tx_bytes stat was incremented by the length of the skb.
+
+It is invalid to access the skb memory after sending the buffer to
+the VIOS because, at any point after sending, the VIOS can trigger
+an interrupt to free this memory. A race between reading skb->len
+and freeing the skb is possible (especially during LPM) and will
+result in use-after-free:
+ ==================================================================
+ BUG: KASAN: slab-use-after-free in ibmvnic_xmit+0x75c/0x1808 [ibmvnic]
+ Read of size 4 at addr c00000024eb48a70 by task hxecom/14495
+ <...>
+ Call Trace:
+ [c000000118f66cf0] [c0000000018cba6c] dump_stack_lvl+0x84/0xe8 (unreliable)
+ [c000000118f66d20] [c0000000006f0080] print_report+0x1a8/0x7f0
+ [c000000118f66df0] [c0000000006f08f0] kasan_report+0x128/0x1f8
+ [c000000118f66f00] [c0000000006f2868] __asan_load4+0xac/0xe0
+ [c000000118f66f20] [c0080000046eac84] ibmvnic_xmit+0x75c/0x1808 [ibmvnic]
+ [c000000118f67340] [c0000000014be168] dev_hard_start_xmit+0x150/0x358
+ <...>
+ Freed by task 0:
+ kasan_save_stack+0x34/0x68
+ kasan_save_track+0x2c/0x50
+ kasan_save_free_info+0x64/0x108
+ __kasan_mempool_poison_object+0x148/0x2d4
+ napi_skb_cache_put+0x5c/0x194
+ net_tx_action+0x154/0x5b8
+ handle_softirqs+0x20c/0x60c
+ do_softirq_own_stack+0x6c/0x88
+ <...>
+ The buggy address belongs to the object at c00000024eb48a00 which
+  belongs to the cache skbuff_head_cache of size 224
+==================================================================
+
+Fixes: 032c5e82847a ("Driver for IBM System i/p VNIC protocol")
+Signed-off-by: Nick Child <nnac123@linux.ibm.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250214155233.235559-1-nnac123@linux.ibm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index cd5224f6c42a3..4f18addc191b8 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -2424,6 +2424,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
+       dma_addr_t data_dma_addr;
+       struct netdev_queue *txq;
+       unsigned long lpar_rc;
++      unsigned int skblen;
+       union sub_crq tx_crq;
+       unsigned int offset;
+       int num_entries = 1;
+@@ -2526,6 +2527,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
+       tx_buff->skb = skb;
+       tx_buff->index = bufidx;
+       tx_buff->pool_index = queue_num;
++      skblen = skb->len;
+       memset(&tx_crq, 0, sizeof(tx_crq));
+       tx_crq.v1.first = IBMVNIC_CRQ_CMD;
+@@ -2616,7 +2618,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
+               netif_stop_subqueue(netdev, queue_num);
+       }
+-      tx_bytes += skb->len;
++      tx_bytes += skblen;
+       txq_trans_cond_update(txq);
+       ret = NETDEV_TX_OK;
+       goto out;
+-- 
+2.39.5
+
diff --git a/queue-6.6/ibmvnic-introduce-send-sub-crq-direct.patch b/queue-6.6/ibmvnic-introduce-send-sub-crq-direct.patch
new file mode 100644 (file)
index 0000000..e4c9542
--- /dev/null
@@ -0,0 +1,170 @@
+From 9605faea97bbc7b0457f6459c7e4771e0b65671c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Aug 2024 16:18:07 -0500
+Subject: ibmvnic: Introduce send sub-crq direct
+
+From: Nick Child <nnac123@linux.ibm.com>
+
+[ Upstream commit 74839f7a82689bf5a21a5447cae8e3a7b7a606d2 ]
+
+Firmware supports two hcalls to send a sub-crq request:
+H_SEND_SUB_CRQ_INDIRECT and H_SEND_SUB_CRQ. The indirect hcall allows
+for submission of batched messages while the other hcall is limited to
+only one message. This protocol is defined in PAPR section 17.2.3.3.
+
+Previously, the ibmvnic xmit function only used the indirect hcall. This
+allowed the driver to batch it's skbs. A single skb can occupy a few
+entries per hcall depending on if FW requires skb header information or
+not. The FW only needs header information if the packet is segmented.
+
+By this logic, if an skb is not GSO then it can fit in one sub-crq
+message and therefore is a candidate for H_SEND_SUB_CRQ.
+Batching skb transmission is only useful when there are more packets
+coming down the line (ie netdev_xmit_more is true).
+
+As it turns out, H_SEND_SUB_CRQ induces less latency than
+H_SEND_SUB_CRQ_INDIRECT. Therefore, use H_SEND_SUB_CRQ where
+appropriate.
+
+Small latency gains seen when doing TCP_RR_150 (request/response
+workload). Ftrace results (graph-time=1):
+  Previous:
+     ibmvnic_xmit = 29618270.83 us / 8860058.0 hits = AVG 3.34
+     ibmvnic_tx_scrq_flush = 21972231.02 us / 6553972.0 hits = AVG 3.35
+  Now:
+     ibmvnic_xmit = 22153350.96 us / 8438942.0 hits = AVG 2.63
+     ibmvnic_tx_scrq_flush = 15858922.4 us / 6244076.0 hits = AVG 2.54
+
+Signed-off-by: Nick Child <nnac123@linux.ibm.com>
+Link: https://patch.msgid.link/20240807211809.1259563-6-nnac123@linux.ibm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: bdf5d13aa05e ("ibmvnic: Don't reference skb after sending to VIOS")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 52 ++++++++++++++++++++++++++----
+ 1 file changed, 46 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index e1e4dc81ad309..e2e4a1a2fa74f 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -117,6 +117,7 @@ static void free_long_term_buff(struct ibmvnic_adapter *adapter,
+                               struct ibmvnic_long_term_buff *ltb);
+ static void ibmvnic_disable_irqs(struct ibmvnic_adapter *adapter);
+ static void flush_reset_queue(struct ibmvnic_adapter *adapter);
++static void print_subcrq_error(struct device *dev, int rc, const char *func);
+ struct ibmvnic_stat {
+       char name[ETH_GSTRING_LEN];
+@@ -2350,8 +2351,29 @@ static void ibmvnic_tx_scrq_clean_buffer(struct ibmvnic_adapter *adapter,
+       }
+ }
++static int send_subcrq_direct(struct ibmvnic_adapter *adapter,
++                            u64 remote_handle, u64 *entry)
++{
++      unsigned int ua = adapter->vdev->unit_address;
++      struct device *dev = &adapter->vdev->dev;
++      int rc;
++
++      /* Make sure the hypervisor sees the complete request */
++      dma_wmb();
++      rc = plpar_hcall_norets(H_SEND_SUB_CRQ, ua,
++                              cpu_to_be64(remote_handle),
++                              cpu_to_be64(entry[0]), cpu_to_be64(entry[1]),
++                              cpu_to_be64(entry[2]), cpu_to_be64(entry[3]));
++
++      if (rc)
++              print_subcrq_error(dev, rc, __func__);
++
++      return rc;
++}
++
+ static int ibmvnic_tx_scrq_flush(struct ibmvnic_adapter *adapter,
+-                               struct ibmvnic_sub_crq_queue *tx_scrq)
++                               struct ibmvnic_sub_crq_queue *tx_scrq,
++                               bool indirect)
+ {
+       struct ibmvnic_ind_xmit_queue *ind_bufp;
+       u64 dma_addr;
+@@ -2366,7 +2388,13 @@ static int ibmvnic_tx_scrq_flush(struct ibmvnic_adapter *adapter,
+       if (!entries)
+               return 0;
+-      rc = send_subcrq_indirect(adapter, handle, dma_addr, entries);
++
++      if (indirect)
++              rc = send_subcrq_indirect(adapter, handle, dma_addr, entries);
++      else
++              rc = send_subcrq_direct(adapter, handle,
++                                      (u64 *)ind_bufp->indir_arr);
++
+       if (rc)
+               ibmvnic_tx_scrq_clean_buffer(adapter, tx_scrq);
+       else
+@@ -2424,7 +2452,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
+               tx_dropped++;
+               tx_send_failed++;
+               ret = NETDEV_TX_OK;
+-              lpar_rc = ibmvnic_tx_scrq_flush(adapter, tx_scrq);
++              lpar_rc = ibmvnic_tx_scrq_flush(adapter, tx_scrq, true);
+               if (lpar_rc != H_SUCCESS)
+                       goto tx_err;
+               goto out;
+@@ -2442,7 +2470,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
+               tx_send_failed++;
+               tx_dropped++;
+               ret = NETDEV_TX_OK;
+-              lpar_rc = ibmvnic_tx_scrq_flush(adapter, tx_scrq);
++              lpar_rc = ibmvnic_tx_scrq_flush(adapter, tx_scrq, true);
+               if (lpar_rc != H_SUCCESS)
+                       goto tx_err;
+               goto out;
+@@ -2540,6 +2568,16 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
+               tx_crq.v1.flags1 |= IBMVNIC_TX_LSO;
+               tx_crq.v1.mss = cpu_to_be16(skb_shinfo(skb)->gso_size);
+               hdrs += 2;
++      } else if (!ind_bufp->index && !netdev_xmit_more()) {
++              ind_bufp->indir_arr[0] = tx_crq;
++              ind_bufp->index = 1;
++              tx_buff->num_entries = 1;
++              netdev_tx_sent_queue(txq, skb->len);
++              lpar_rc = ibmvnic_tx_scrq_flush(adapter, tx_scrq, false);
++              if (lpar_rc != H_SUCCESS)
++                      goto tx_err;
++
++              goto early_exit;
+       }
+       if ((*hdrs >> 7) & 1)
+@@ -2549,7 +2587,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
+       tx_buff->num_entries = num_entries;
+       /* flush buffer if current entry can not fit */
+       if (num_entries + ind_bufp->index > IBMVNIC_MAX_IND_DESCS) {
+-              lpar_rc = ibmvnic_tx_scrq_flush(adapter, tx_scrq);
++              lpar_rc = ibmvnic_tx_scrq_flush(adapter, tx_scrq, true);
+               if (lpar_rc != H_SUCCESS)
+                       goto tx_flush_err;
+       }
+@@ -2557,15 +2595,17 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
+       indir_arr[0] = tx_crq;
+       memcpy(&ind_bufp->indir_arr[ind_bufp->index], &indir_arr[0],
+              num_entries * sizeof(struct ibmvnic_generic_scrq));
++
+       ind_bufp->index += num_entries;
+       if (__netdev_tx_sent_queue(txq, skb->len,
+                                  netdev_xmit_more() &&
+                                  ind_bufp->index < IBMVNIC_MAX_IND_DESCS)) {
+-              lpar_rc = ibmvnic_tx_scrq_flush(adapter, tx_scrq);
++              lpar_rc = ibmvnic_tx_scrq_flush(adapter, tx_scrq, true);
+               if (lpar_rc != H_SUCCESS)
+                       goto tx_err;
+       }
++early_exit:
+       if (atomic_add_return(num_entries, &tx_scrq->used)
+                                       >= adapter->req_tx_entries_per_subcrq) {
+               netdev_dbg(netdev, "Stopping queue %d\n", queue_num);
+-- 
+2.39.5
+
diff --git a/queue-6.6/ibmvnic-return-error-code-on-tx-scrq-flush-fail.patch b/queue-6.6/ibmvnic-return-error-code-on-tx-scrq-flush-fail.patch
new file mode 100644 (file)
index 0000000..4db87da
--- /dev/null
@@ -0,0 +1,82 @@
+From ff41b80ef86322f6b7cba4174b3bea0b8c9a4c79 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Apr 2024 11:41:28 -0500
+Subject: ibmvnic: Return error code on TX scrq flush fail
+
+From: Nick Child <nnac123@linux.ibm.com>
+
+[ Upstream commit 5cb431dcf8048572e9ffc6c30cdbd8832cbe502d ]
+
+In ibmvnic_xmit() if ibmvnic_tx_scrq_flush() returns H_CLOSED then
+it will inform upper level networking functions to disable tx
+queues. H_CLOSED signals that the connection with the vnic server is
+down and a transport event is expected to recover the device.
+
+Previously, ibmvnic_tx_scrq_flush() was hard-coded to return success.
+Therefore, the queues would remain active until ibmvnic_cleanup() is
+called within do_reset().
+
+The problem is that do_reset() depends on the RTNL lock. If several
+ibmvnic devices are resetting then there can be a long wait time until
+the last device can grab the lock. During this time the tx/rx queues
+still appear active to upper level functions.
+
+FYI, we do make a call to netif_carrier_off() outside the RTNL lock but
+its calls to dev_deactivate() are also dependent on the RTNL lock.
+
+As a result, large amounts of retransmissions were observed in a short
+period of time, eventually leading to ETIMEOUT. This was specifically
+seen with HNV devices, likely because of even more RTNL dependencies.
+
+Therefore, ensure the return code of ibmvnic_tx_scrq_flush() is
+propagated to the xmit function to allow for an earlier (and lock-less)
+response to a transport event.
+
+Signed-off-by: Nick Child <nnac123@linux.ibm.com>
+Link: https://lore.kernel.org/r/20240416164128.387920-1-nnac123@linux.ibm.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: bdf5d13aa05e ("ibmvnic: Don't reference skb after sending to VIOS")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index 61685c3053ad7..e1e4dc81ad309 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -2371,7 +2371,7 @@ static int ibmvnic_tx_scrq_flush(struct ibmvnic_adapter *adapter,
+               ibmvnic_tx_scrq_clean_buffer(adapter, tx_scrq);
+       else
+               ind_bufp->index = 0;
+-      return 0;
++      return rc;
+ }
+ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
+@@ -2424,7 +2424,9 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
+               tx_dropped++;
+               tx_send_failed++;
+               ret = NETDEV_TX_OK;
+-              ibmvnic_tx_scrq_flush(adapter, tx_scrq);
++              lpar_rc = ibmvnic_tx_scrq_flush(adapter, tx_scrq);
++              if (lpar_rc != H_SUCCESS)
++                      goto tx_err;
+               goto out;
+       }
+@@ -2439,8 +2441,10 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
+               dev_kfree_skb_any(skb);
+               tx_send_failed++;
+               tx_dropped++;
+-              ibmvnic_tx_scrq_flush(adapter, tx_scrq);
+               ret = NETDEV_TX_OK;
++              lpar_rc = ibmvnic_tx_scrq_flush(adapter, tx_scrq);
++              if (lpar_rc != H_SUCCESS)
++                      goto tx_err;
+               goto out;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.6/input-serio-define-serio_pause_rx-guard-to-pause-and.patch b/queue-6.6/input-serio-define-serio_pause_rx-guard-to-pause-and.patch
new file mode 100644 (file)
index 0000000..2be95bd
--- /dev/null
@@ -0,0 +1,52 @@
+From f38e56cee2b4fcd0445075dbcc043b94bc30d740 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Sep 2024 21:17:06 -0700
+Subject: Input: serio - define serio_pause_rx guard to pause and resume serio
+ ports
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+[ Upstream commit 0e45a09a1da0872786885c505467aab8fb29b5b4 ]
+
+serio_pause_rx() and serio_continue_rx() are usually used together to
+temporarily stop receiving interrupts/data for a given serio port.
+Define "serio_pause_rx" guard for this so that the port is always
+resumed once critical section is over.
+
+Example:
+
+       scoped_guard(serio_pause_rx, elo->serio) {
+               elo->expected_packet = toupper(packet[0]);
+               init_completion(&elo->cmd_done);
+       }
+
+Link: https://lore.kernel.org/r/20240905041732.2034348-2-dmitry.torokhov@gmail.com
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Stable-dep-of: 08bd5b7c9a24 ("Input: synaptics - fix crash when enabling pass-through port")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/serio.h | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/include/linux/serio.h b/include/linux/serio.h
+index 6c27d413da921..e105ff2ee651a 100644
+--- a/include/linux/serio.h
++++ b/include/linux/serio.h
+@@ -6,6 +6,7 @@
+ #define _SERIO_H
++#include <linux/cleanup.h>
+ #include <linux/types.h>
+ #include <linux/interrupt.h>
+ #include <linux/list.h>
+@@ -161,4 +162,6 @@ static inline void serio_continue_rx(struct serio *serio)
+       spin_unlock_irq(&serio->lock);
+ }
++DEFINE_GUARD(serio_pause_rx, struct serio *, serio_pause_rx(_T), serio_continue_rx(_T))
++
+ #endif
+-- 
+2.39.5
+
diff --git a/queue-6.6/input-synaptics-fix-crash-when-enabling-pass-through.patch b/queue-6.6/input-synaptics-fix-crash-when-enabling-pass-through.patch
new file mode 100644 (file)
index 0000000..0be9f87
--- /dev/null
@@ -0,0 +1,138 @@
+From 01acf412d2e4c8732bbf2f0943fe5d11e4681a47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jan 2025 09:23:40 -0800
+Subject: Input: synaptics - fix crash when enabling pass-through port
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+[ Upstream commit 08bd5b7c9a2401faabdaa1472d45c7de0755fd7e ]
+
+When enabling a pass-through port an interrupt might come before psmouse
+driver binds to the pass-through port. However synaptics sub-driver
+tries to access psmouse instance presumably associated with the
+pass-through port to figure out if only 1 byte of response or entire
+protocol packet needs to be forwarded to the pass-through port and may
+crash if psmouse instance has not been attached to the port yet.
+
+Fix the crash by introducing open() and close() methods for the port and
+check if the port is open before trying to access psmouse instance.
+Because psmouse calls serio_open() only after attaching psmouse instance
+to serio port instance this prevents the potential crash.
+
+Reported-by: Takashi Iwai <tiwai@suse.de>
+Fixes: 100e16959c3c ("Input: libps2 - attach ps2dev instances as serio port's drvdata")
+Link: https://bugzilla.suse.com/show_bug.cgi?id=1219522
+Cc: stable@vger.kernel.org
+Reviewed-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/Z4qSHORvPn7EU2j1@google.com
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/mouse/synaptics.c | 56 ++++++++++++++++++++++++---------
+ drivers/input/mouse/synaptics.h |  1 +
+ 2 files changed, 43 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
+index cff3393f0dd00..26677432ac836 100644
+--- a/drivers/input/mouse/synaptics.c
++++ b/drivers/input/mouse/synaptics.c
+@@ -667,23 +667,50 @@ static void synaptics_pt_stop(struct serio *serio)
+       serio_continue_rx(parent->ps2dev.serio);
+ }
++static int synaptics_pt_open(struct serio *serio)
++{
++      struct psmouse *parent = psmouse_from_serio(serio->parent);
++      struct synaptics_data *priv = parent->private;
++
++      guard(serio_pause_rx)(parent->ps2dev.serio);
++      priv->pt_port_open = true;
++
++      return 0;
++}
++
++static void synaptics_pt_close(struct serio *serio)
++{
++      struct psmouse *parent = psmouse_from_serio(serio->parent);
++      struct synaptics_data *priv = parent->private;
++
++      guard(serio_pause_rx)(parent->ps2dev.serio);
++      priv->pt_port_open = false;
++}
++
+ static int synaptics_is_pt_packet(u8 *buf)
+ {
+       return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4;
+ }
+-static void synaptics_pass_pt_packet(struct serio *ptport, u8 *packet)
++static void synaptics_pass_pt_packet(struct synaptics_data *priv, u8 *packet)
+ {
+-      struct psmouse *child = psmouse_from_serio(ptport);
++      struct serio *ptport;
+-      if (child && child->state == PSMOUSE_ACTIVATED) {
+-              serio_interrupt(ptport, packet[1], 0);
+-              serio_interrupt(ptport, packet[4], 0);
+-              serio_interrupt(ptport, packet[5], 0);
+-              if (child->pktsize == 4)
+-                      serio_interrupt(ptport, packet[2], 0);
+-      } else {
+-              serio_interrupt(ptport, packet[1], 0);
++      ptport = priv->pt_port;
++      if (!ptport)
++              return;
++
++      serio_interrupt(ptport, packet[1], 0);
++
++      if (priv->pt_port_open) {
++              struct psmouse *child = psmouse_from_serio(ptport);
++
++              if (child->state == PSMOUSE_ACTIVATED) {
++                      serio_interrupt(ptport, packet[4], 0);
++                      serio_interrupt(ptport, packet[5], 0);
++                      if (child->pktsize == 4)
++                              serio_interrupt(ptport, packet[2], 0);
++              }
+       }
+ }
+@@ -722,6 +749,8 @@ static void synaptics_pt_create(struct psmouse *psmouse)
+       serio->write = synaptics_pt_write;
+       serio->start = synaptics_pt_start;
+       serio->stop = synaptics_pt_stop;
++      serio->open = synaptics_pt_open;
++      serio->close = synaptics_pt_close;
+       serio->parent = psmouse->ps2dev.serio;
+       psmouse->pt_activate = synaptics_pt_activate;
+@@ -1218,11 +1247,10 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse)
+               if (SYN_CAP_PASS_THROUGH(priv->info.capabilities) &&
+                   synaptics_is_pt_packet(psmouse->packet)) {
+-                      if (priv->pt_port)
+-                              synaptics_pass_pt_packet(priv->pt_port,
+-                                                       psmouse->packet);
+-              } else
++                      synaptics_pass_pt_packet(priv, psmouse->packet);
++              } else {
+                       synaptics_process_packet(psmouse);
++              }
+               return PSMOUSE_FULL_PACKET;
+       }
+diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
+index 08533d1b1b16f..4b34f13b9f761 100644
+--- a/drivers/input/mouse/synaptics.h
++++ b/drivers/input/mouse/synaptics.h
+@@ -188,6 +188,7 @@ struct synaptics_data {
+       bool disable_gesture;                   /* disable gestures */
+       struct serio *pt_port;                  /* Pass-through serio port */
++      bool pt_port_open;
+       /*
+        * Last received Advanced Gesture Mode (AGM) packet. An AGM packet
+-- 
+2.39.5
+
diff --git a/queue-6.6/md-factor-out-a-helper-from-mddev_put.patch b/queue-6.6/md-factor-out-a-helper-from-mddev_put.patch
new file mode 100644 (file)
index 0000000..23d4b9f
--- /dev/null
@@ -0,0 +1,69 @@
+From 1e6244068d989889c500ad7139e2fa5c0137658c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Sep 2023 14:12:40 +0800
+Subject: md: factor out a helper from mddev_put()
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 3d8d32873c7b6d9cec5b40c2ddb8c7c55961694f ]
+
+There are no functional changes, prepare to simplify md_seq_ops in next
+patch.
+
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Link: https://lore.kernel.org/r/20230927061241.1552837-2-yukuai1@huaweicloud.com
+Stable-dep-of: 8d28d0ddb986 ("md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md.c | 29 +++++++++++++++++------------
+ 1 file changed, 17 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 342407ea87d83..836e8ed58c8ad 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -633,23 +633,28 @@ static inline struct mddev *mddev_get(struct mddev *mddev)
+ static void mddev_delayed_delete(struct work_struct *ws);
++static void __mddev_put(struct mddev *mddev)
++{
++      if (mddev->raid_disks || !list_empty(&mddev->disks) ||
++          mddev->ctime || mddev->hold_active)
++              return;
++
++      /* Array is not configured at all, and not held active, so destroy it */
++      set_bit(MD_DELETED, &mddev->flags);
++
++      /*
++       * Call queue_work inside the spinlock so that flush_workqueue() after
++       * mddev_find will succeed in waiting for the work to be done.
++       */
++      queue_work(md_misc_wq, &mddev->del_work);
++}
++
+ void mddev_put(struct mddev *mddev)
+ {
+       if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock))
+               return;
+-      if (!mddev->raid_disks && list_empty(&mddev->disks) &&
+-          mddev->ctime == 0 && !mddev->hold_active) {
+-              /* Array is not configured at all, and not held active,
+-               * so destroy it */
+-              set_bit(MD_DELETED, &mddev->flags);
+-              /*
+-               * Call queue_work inside the spinlock so that
+-               * flush_workqueue() after mddev_find will succeed in waiting
+-               * for the work to be done.
+-               */
+-              queue_work(md_misc_wq, &mddev->del_work);
+-      }
++      __mddev_put(mddev);
+       spin_unlock(&all_mddevs_lock);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.6/md-md-bitmap-add-sync_size-into-struct-md_bitmap_sta.patch b/queue-6.6/md-md-bitmap-add-sync_size-into-struct-md_bitmap_sta.patch
new file mode 100644 (file)
index 0000000..39cc5af
--- /dev/null
@@ -0,0 +1,130 @@
+From de123127a63e00066cff40f19425b6ff3db07b08 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Aug 2024 15:44:16 +0800
+Subject: md/md-bitmap: add 'sync_size' into struct md_bitmap_stats
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit ec6bb299c7c3dd4ca1724d13d5f5fae3ee54fc65 ]
+
+To avoid dereferencing bitmap directly in md-cluster to prepare
+inventing a new bitmap.
+
+BTW, also fix following checkpatch warnings:
+
+WARNING: Deprecated use of 'kmap_atomic', prefer 'kmap_local_page' instead
+WARNING: Deprecated use of 'kunmap_atomic', prefer 'kunmap_local' instead
+
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20240826074452.1490072-7-yukuai1@huaweicloud.com
+Signed-off-by: Song Liu <song@kernel.org>
+Stable-dep-of: 8d28d0ddb986 ("md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md-bitmap.c  |  6 ++++++
+ drivers/md/md-bitmap.h  |  1 +
+ drivers/md/md-cluster.c | 34 ++++++++++++++++++++--------------
+ 3 files changed, 27 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
+index f7b02d87a6da7..80b0cd7b88995 100644
+--- a/drivers/md/md-bitmap.c
++++ b/drivers/md/md-bitmap.c
+@@ -2115,10 +2115,15 @@ EXPORT_SYMBOL_GPL(md_bitmap_copy_from_slot);
+ int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats)
+ {
+       struct bitmap_counts *counts;
++      bitmap_super_t *sb;
+       if (!bitmap)
+               return -ENOENT;
++      sb = kmap_local_page(bitmap->storage.sb_page);
++      stats->sync_size = le64_to_cpu(sb->sync_size);
++      kunmap_local(sb);
++
+       counts = &bitmap->counts;
+       stats->missing_pages = counts->missing_pages;
+       stats->pages = counts->pages;
+@@ -2126,6 +2131,7 @@ int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats)
+       return 0;
+ }
++EXPORT_SYMBOL_GPL(md_bitmap_get_stats);
+ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
+                 int chunksize, int init)
+diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h
+index 60b86ee939081..840efd1b8a01c 100644
+--- a/drivers/md/md-bitmap.h
++++ b/drivers/md/md-bitmap.h
+@@ -236,6 +236,7 @@ struct bitmap {
+ struct md_bitmap_stats {
+       unsigned long   missing_pages;
++      unsigned long   sync_size;
+       unsigned long   pages;
+       struct file     *file;
+ };
+diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c
+index ca4d3a8d5dd76..6a89f6b5d64f9 100644
+--- a/drivers/md/md-cluster.c
++++ b/drivers/md/md-cluster.c
+@@ -1190,18 +1190,21 @@ static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsiz
+  */
+ static int cluster_check_sync_size(struct mddev *mddev)
+ {
+-      int i, rv;
+-      bitmap_super_t *sb;
+-      unsigned long my_sync_size, sync_size = 0;
+-      int node_num = mddev->bitmap_info.nodes;
+       int current_slot = md_cluster_ops->slot_number(mddev);
++      int node_num = mddev->bitmap_info.nodes;
+       struct bitmap *bitmap = mddev->bitmap;
+-      char str[64];
+       struct dlm_lock_resource *bm_lockres;
++      struct md_bitmap_stats stats;
++      unsigned long sync_size = 0;
++      unsigned long my_sync_size;
++      char str[64];
++      int i, rv;
+-      sb = kmap_atomic(bitmap->storage.sb_page);
+-      my_sync_size = le64_to_cpu(sb->sync_size);
+-      kunmap_atomic(sb);
++      rv = md_bitmap_get_stats(bitmap, &stats);
++      if (rv)
++              return rv;
++
++      my_sync_size = stats.sync_size;
+       for (i = 0; i < node_num; i++) {
+               if (i == current_slot)
+@@ -1230,15 +1233,18 @@ static int cluster_check_sync_size(struct mddev *mddev)
+                       md_bitmap_update_sb(bitmap);
+               lockres_free(bm_lockres);
+-              sb = kmap_atomic(bitmap->storage.sb_page);
+-              if (sync_size == 0)
+-                      sync_size = le64_to_cpu(sb->sync_size);
+-              else if (sync_size != le64_to_cpu(sb->sync_size)) {
+-                      kunmap_atomic(sb);
++              rv = md_bitmap_get_stats(bitmap, &stats);
++              if (rv) {
++                      md_bitmap_free(bitmap);
++                      return rv;
++              }
++
++              if (sync_size == 0) {
++                      sync_size = stats.sync_size;
++              } else if (sync_size != stats.sync_size) {
+                       md_bitmap_free(bitmap);
+                       return -1;
+               }
+-              kunmap_atomic(sb);
+               md_bitmap_free(bitmap);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.6/md-md-bitmap-replace-md_bitmap_status-with-a-new-hel.patch b/queue-6.6/md-md-bitmap-replace-md_bitmap_status-with-a-new-hel.patch
new file mode 100644 (file)
index 0000000..41cf91a
--- /dev/null
@@ -0,0 +1,144 @@
+From 0774b740b6c6d955ea82931e22db0a7c216aafaa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Aug 2024 15:44:12 +0800
+Subject: md/md-bitmap: replace md_bitmap_status() with a new helper
+ md_bitmap_get_stats()
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 38f287d7e495ae00d4481702f44ff7ca79f5c9bc ]
+
+There are no functional changes, and the new helper will be used in
+multiple places in following patches to avoid dereferencing bitmap
+directly.
+
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20240826074452.1490072-3-yukuai1@huaweicloud.com
+Signed-off-by: Song Liu <song@kernel.org>
+Stable-dep-of: 8d28d0ddb986 ("md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md-bitmap.c | 25 ++++++-------------------
+ drivers/md/md-bitmap.h |  8 +++++++-
+ drivers/md/md.c        | 29 ++++++++++++++++++++++++++++-
+ 3 files changed, 41 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
+index 2085b1705f144..f7b02d87a6da7 100644
+--- a/drivers/md/md-bitmap.c
++++ b/drivers/md/md-bitmap.c
+@@ -2112,32 +2112,19 @@ int md_bitmap_copy_from_slot(struct mddev *mddev, int slot,
+ }
+ EXPORT_SYMBOL_GPL(md_bitmap_copy_from_slot);
+-
+-void md_bitmap_status(struct seq_file *seq, struct bitmap *bitmap)
++int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats)
+ {
+-      unsigned long chunk_kb;
+       struct bitmap_counts *counts;
+       if (!bitmap)
+-              return;
++              return -ENOENT;
+       counts = &bitmap->counts;
++      stats->missing_pages = counts->missing_pages;
++      stats->pages = counts->pages;
++      stats->file = bitmap->storage.file;
+-      chunk_kb = bitmap->mddev->bitmap_info.chunksize >> 10;
+-      seq_printf(seq, "bitmap: %lu/%lu pages [%luKB], "
+-                 "%lu%s chunk",
+-                 counts->pages - counts->missing_pages,
+-                 counts->pages,
+-                 (counts->pages - counts->missing_pages)
+-                 << (PAGE_SHIFT - 10),
+-                 chunk_kb ? chunk_kb : bitmap->mddev->bitmap_info.chunksize,
+-                 chunk_kb ? "KB" : "B");
+-      if (bitmap->storage.file) {
+-              seq_printf(seq, ", file: ");
+-              seq_file_path(seq, bitmap->storage.file, " \t\n");
+-      }
+-
+-      seq_printf(seq, "\n");
++      return 0;
+ }
+ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
+diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h
+index 8b89e260a93b7..60b86ee939081 100644
+--- a/drivers/md/md-bitmap.h
++++ b/drivers/md/md-bitmap.h
+@@ -234,6 +234,12 @@ struct bitmap {
+       int cluster_slot;               /* Slot offset for clustered env */
+ };
++struct md_bitmap_stats {
++      unsigned long   missing_pages;
++      unsigned long   pages;
++      struct file     *file;
++};
++
+ /* the bitmap API */
+ /* these are used only by md/bitmap */
+@@ -244,7 +250,7 @@ void md_bitmap_destroy(struct mddev *mddev);
+ void md_bitmap_print_sb(struct bitmap *bitmap);
+ void md_bitmap_update_sb(struct bitmap *bitmap);
+-void md_bitmap_status(struct seq_file *seq, struct bitmap *bitmap);
++int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats);
+ int  md_bitmap_setallbits(struct bitmap *bitmap);
+ void md_bitmap_write_all(struct bitmap *bitmap);
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 27a6a11b71ee4..b73649fd8e039 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -8290,6 +8290,33 @@ static void md_seq_stop(struct seq_file *seq, void *v)
+       spin_unlock(&all_mddevs_lock);
+ }
++static void md_bitmap_status(struct seq_file *seq, struct mddev *mddev)
++{
++      struct md_bitmap_stats stats;
++      unsigned long used_pages;
++      unsigned long chunk_kb;
++      int err;
++
++      err = md_bitmap_get_stats(mddev->bitmap, &stats);
++      if (err)
++              return;
++
++      chunk_kb = mddev->bitmap_info.chunksize >> 10;
++      used_pages = stats.pages - stats.missing_pages;
++
++      seq_printf(seq, "bitmap: %lu/%lu pages [%luKB], %lu%s chunk",
++                 used_pages, stats.pages, used_pages << (PAGE_SHIFT - 10),
++                 chunk_kb ? chunk_kb : mddev->bitmap_info.chunksize,
++                 chunk_kb ? "KB" : "B");
++
++      if (stats.file) {
++              seq_puts(seq, ", file: ");
++              seq_file_path(seq, stats.file, " \t\n");
++      }
++
++      seq_putc(seq, '\n');
++}
++
+ static int md_seq_show(struct seq_file *seq, void *v)
+ {
+       struct mddev *mddev = list_entry(v, struct mddev, all_mddevs);
+@@ -8365,7 +8392,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
+               } else
+                       seq_printf(seq, "\n       ");
+-              md_bitmap_status(seq, mddev->bitmap);
++              md_bitmap_status(seq, mddev);
+               seq_printf(seq, "\n");
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.6/md-md-bitmap-synchronize-bitmap_get_stats-with-bitma.patch b/queue-6.6/md-md-bitmap-synchronize-bitmap_get_stats-with-bitma.patch
new file mode 100644 (file)
index 0000000..cc61efd
--- /dev/null
@@ -0,0 +1,88 @@
+From f41040c9cfcd2ca71a95fabf83b861188d8118c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jan 2025 17:20:55 +0800
+Subject: md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 8d28d0ddb986f56920ac97ae704cc3340a699a30 ]
+
+After commit ec6bb299c7c3 ("md/md-bitmap: add 'sync_size' into struct
+md_bitmap_stats"), following panic is reported:
+
+Oops: general protection fault, probably for non-canonical address
+RIP: 0010:bitmap_get_stats+0x2b/0xa0
+Call Trace:
+ <TASK>
+ md_seq_show+0x2d2/0x5b0
+ seq_read_iter+0x2b9/0x470
+ seq_read+0x12f/0x180
+ proc_reg_read+0x57/0xb0
+ vfs_read+0xf6/0x380
+ ksys_read+0x6c/0xf0
+ do_syscall_64+0x82/0x170
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Root cause is that bitmap_get_stats() can be called at anytime if mddev
+is still there, even if bitmap is destroyed, or not fully initialized.
+Deferenceing bitmap in this case can crash the kernel. Meanwhile, the
+above commit start to deferencing bitmap->storage, make the problem
+easier to trigger.
+
+Fix the problem by protecting bitmap_get_stats() with bitmap_info.mutex.
+
+Cc: stable@vger.kernel.org # v6.12+
+Fixes: 32a7627cf3a3 ("[PATCH] md: optimised resync using Bitmap based intent logging")
+Reported-and-tested-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+Closes: https://lore.kernel.org/linux-raid/ca3a91a2-50ae-4f68-b317-abd9889f3907@oracle.com/T/#m6e5086c95201135e4941fe38f9efa76daf9666c5
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20250124092055.4050195-1-yukuai1@huaweicloud.com
+Signed-off-by: Song Liu <song@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md-bitmap.c | 5 ++++-
+ drivers/md/md.c        | 5 +++++
+ 2 files changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
+index 80b0cd7b88995..deb40a8ba3999 100644
+--- a/drivers/md/md-bitmap.c
++++ b/drivers/md/md-bitmap.c
+@@ -2119,7 +2119,10 @@ int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats)
+       if (!bitmap)
+               return -ENOENT;
+-
++      if (bitmap->mddev->bitmap_info.external)
++              return -ENOENT;
++      if (!bitmap->storage.sb_page) /* no superblock */
++              return -EINVAL;
+       sb = kmap_local_page(bitmap->storage.sb_page);
+       stats->sync_size = le64_to_cpu(sb->sync_size);
+       kunmap_local(sb);
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index b73649fd8e039..534c4efd935f6 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -8327,6 +8327,10 @@ static int md_seq_show(struct seq_file *seq, void *v)
+               return 0;
+       spin_unlock(&all_mddevs_lock);
++
++      /* prevent bitmap to be freed after checking */
++      mutex_lock(&mddev->bitmap_info.mutex);
++
+       spin_lock(&mddev->lock);
+       if (mddev->pers || mddev->raid_disks || !list_empty(&mddev->disks)) {
+               seq_printf(seq, "%s : %sactive", mdname(mddev),
+@@ -8397,6 +8401,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
+               seq_printf(seq, "\n");
+       }
+       spin_unlock(&mddev->lock);
++      mutex_unlock(&mddev->bitmap_info.mutex);
+       spin_lock(&all_mddevs_lock);
+       if (atomic_dec_and_test(&mddev->active))
+               __mddev_put(mddev);
+-- 
+2.39.5
+
diff --git a/queue-6.6/md-md-cluster-fix-spares-warnings-for-__le64.patch b/queue-6.6/md-md-cluster-fix-spares-warnings-for-__le64.patch
new file mode 100644 (file)
index 0000000..345d444
--- /dev/null
@@ -0,0 +1,55 @@
+From 3c1283e04955d0949edc50fb7de53a1bbc197675 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Aug 2024 15:44:15 +0800
+Subject: md/md-cluster: fix spares warnings for __le64
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 82697ccf7e495c1ba81e315c2886d6220ff84c2c ]
+
+drivers/md/md-cluster.c:1220:22: warning: incorrect type in assignment (different base types)
+drivers/md/md-cluster.c:1220:22:    expected unsigned long my_sync_size
+drivers/md/md-cluster.c:1220:22:    got restricted __le64 [usertype] sync_size
+drivers/md/md-cluster.c:1252:35: warning: incorrect type in assignment (different base types)
+drivers/md/md-cluster.c:1252:35:    expected unsigned long sync_size
+drivers/md/md-cluster.c:1252:35:    got restricted __le64 [usertype] sync_size
+drivers/md/md-cluster.c:1253:41: warning: restricted __le64 degrades to integer
+
+Fix the warnings by using le64_to_cpu() to convet __le64 to integer.
+
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20240826074452.1490072-6-yukuai1@huaweicloud.com
+Signed-off-by: Song Liu <song@kernel.org>
+Stable-dep-of: 8d28d0ddb986 ("md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md-cluster.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c
+index 1e26eb2233495..ca4d3a8d5dd76 100644
+--- a/drivers/md/md-cluster.c
++++ b/drivers/md/md-cluster.c
+@@ -1200,7 +1200,7 @@ static int cluster_check_sync_size(struct mddev *mddev)
+       struct dlm_lock_resource *bm_lockres;
+       sb = kmap_atomic(bitmap->storage.sb_page);
+-      my_sync_size = sb->sync_size;
++      my_sync_size = le64_to_cpu(sb->sync_size);
+       kunmap_atomic(sb);
+       for (i = 0; i < node_num; i++) {
+@@ -1232,8 +1232,8 @@ static int cluster_check_sync_size(struct mddev *mddev)
+               sb = kmap_atomic(bitmap->storage.sb_page);
+               if (sync_size == 0)
+-                      sync_size = sb->sync_size;
+-              else if (sync_size != sb->sync_size) {
++                      sync_size = le64_to_cpu(sb->sync_size);
++              else if (sync_size != le64_to_cpu(sb->sync_size)) {
+                       kunmap_atomic(sb);
+                       md_bitmap_free(bitmap);
+                       return -1;
+-- 
+2.39.5
+
diff --git a/queue-6.6/md-simplify-md_seq_ops.patch b/queue-6.6/md-simplify-md_seq_ops.patch
new file mode 100644 (file)
index 0000000..3635571
--- /dev/null
@@ -0,0 +1,181 @@
+From a49017c061f1439948f224c7e0fa5e1ae3337b46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Sep 2023 14:12:41 +0800
+Subject: md: simplify md_seq_ops
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit cf1b6d4441fffd0ba8ae4ced6a12f578c95ca049 ]
+
+Before this patch, the implementation is hacky and hard to understand:
+
+1) md_seq_start set pos to 1;
+2) md_seq_show found pos is 1, then print Personalities;
+3) md_seq_next found pos is 1, then it update pos to the first mddev;
+4) md_seq_show found pos is not 1 or 2, show mddev;
+5) md_seq_next found pos is not 1 or 2, update pos to next mddev;
+6) loop 4-5 until the last mddev, then md_seq_next update pos to 2;
+7) md_seq_show found pos is 2, then print unused devices;
+8) md_seq_next found pos is 2, stop;
+
+This patch remove the magic value and use seq_list_start/next/stop()
+directly, and move printing "Personalities" to md_seq_start(),
+"unsed devices" to md_seq_stop():
+
+1) md_seq_start print Personalities, and then set pos to first mddev;
+2) md_seq_show show mddev;
+3) md_seq_next update pos to next mddev;
+4) loop 2-3 until the last mddev;
+5) md_seq_stop print unsed devices;
+
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Link: https://lore.kernel.org/r/20230927061241.1552837-3-yukuai1@huaweicloud.com
+Stable-dep-of: 8d28d0ddb986 ("md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md.c | 100 +++++++++++-------------------------------------
+ 1 file changed, 22 insertions(+), 78 deletions(-)
+
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 836e8ed58c8ad..27a6a11b71ee4 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -8260,105 +8260,46 @@ static int status_resync(struct seq_file *seq, struct mddev *mddev)
+ }
+ static void *md_seq_start(struct seq_file *seq, loff_t *pos)
++      __acquires(&all_mddevs_lock)
+ {
+-      struct list_head *tmp;
+-      loff_t l = *pos;
+-      struct mddev *mddev;
++      struct md_personality *pers;
+-      if (l == 0x10000) {
+-              ++*pos;
+-              return (void *)2;
+-      }
+-      if (l > 0x10000)
+-              return NULL;
+-      if (!l--)
+-              /* header */
+-              return (void*)1;
++      seq_puts(seq, "Personalities : ");
++      spin_lock(&pers_lock);
++      list_for_each_entry(pers, &pers_list, list)
++              seq_printf(seq, "[%s] ", pers->name);
++
++      spin_unlock(&pers_lock);
++      seq_puts(seq, "\n");
++      seq->poll_event = atomic_read(&md_event_count);
+       spin_lock(&all_mddevs_lock);
+-      list_for_each(tmp,&all_mddevs)
+-              if (!l--) {
+-                      mddev = list_entry(tmp, struct mddev, all_mddevs);
+-                      if (!mddev_get(mddev))
+-                              continue;
+-                      spin_unlock(&all_mddevs_lock);
+-                      return mddev;
+-              }
+-      spin_unlock(&all_mddevs_lock);
+-      if (!l--)
+-              return (void*)2;/* tail */
+-      return NULL;
++
++      return seq_list_start(&all_mddevs, *pos);
+ }
+ static void *md_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+-      struct list_head *tmp;
+-      struct mddev *next_mddev, *mddev = v;
+-      struct mddev *to_put = NULL;
+-
+-      ++*pos;
+-      if (v == (void*)2)
+-              return NULL;
+-
+-      spin_lock(&all_mddevs_lock);
+-      if (v == (void*)1) {
+-              tmp = all_mddevs.next;
+-      } else {
+-              to_put = mddev;
+-              tmp = mddev->all_mddevs.next;
+-      }
+-
+-      for (;;) {
+-              if (tmp == &all_mddevs) {
+-                      next_mddev = (void*)2;
+-                      *pos = 0x10000;
+-                      break;
+-              }
+-              next_mddev = list_entry(tmp, struct mddev, all_mddevs);
+-              if (mddev_get(next_mddev))
+-                      break;
+-              mddev = next_mddev;
+-              tmp = mddev->all_mddevs.next;
+-      }
+-      spin_unlock(&all_mddevs_lock);
+-
+-      if (to_put)
+-              mddev_put(to_put);
+-      return next_mddev;
+-
++      return seq_list_next(v, &all_mddevs, pos);
+ }
+ static void md_seq_stop(struct seq_file *seq, void *v)
++      __releases(&all_mddevs_lock)
+ {
+-      struct mddev *mddev = v;
+-
+-      if (mddev && v != (void*)1 && v != (void*)2)
+-              mddev_put(mddev);
++      status_unused(seq);
++      spin_unlock(&all_mddevs_lock);
+ }
+ static int md_seq_show(struct seq_file *seq, void *v)
+ {
+-      struct mddev *mddev = v;
++      struct mddev *mddev = list_entry(v, struct mddev, all_mddevs);
+       sector_t sectors;
+       struct md_rdev *rdev;
+-      if (v == (void*)1) {
+-              struct md_personality *pers;
+-              seq_printf(seq, "Personalities : ");
+-              spin_lock(&pers_lock);
+-              list_for_each_entry(pers, &pers_list, list)
+-                      seq_printf(seq, "[%s] ", pers->name);
+-
+-              spin_unlock(&pers_lock);
+-              seq_printf(seq, "\n");
+-              seq->poll_event = atomic_read(&md_event_count);
++      if (!mddev_get(mddev))
+               return 0;
+-      }
+-      if (v == (void*)2) {
+-              status_unused(seq);
+-              return 0;
+-      }
++      spin_unlock(&all_mddevs_lock);
+       spin_lock(&mddev->lock);
+       if (mddev->pers || mddev->raid_disks || !list_empty(&mddev->disks)) {
+               seq_printf(seq, "%s : %sactive", mdname(mddev),
+@@ -8429,6 +8370,9 @@ static int md_seq_show(struct seq_file *seq, void *v)
+               seq_printf(seq, "\n");
+       }
+       spin_unlock(&mddev->lock);
++      spin_lock(&all_mddevs_lock);
++      if (atomic_dec_and_test(&mddev->active))
++              __mddev_put(mddev);
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.6/md-use-separate-work_struct-for-md_start_sync.patch b/queue-6.6/md-use-separate-work_struct-for-md_start_sync.patch
new file mode 100644 (file)
index 0000000..dec85b3
--- /dev/null
@@ -0,0 +1,90 @@
+From a7ba22e00cf1205f5cb4ae22f9a8780dd2330f96 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Aug 2023 11:16:16 +0800
+Subject: md: use separate work_struct for md_start_sync()
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit ac619781967bd5663c29606246b50dbebd8b3473 ]
+
+It's a little weird to borrow 'del_work' for md_start_sync(), declare
+a new work_struct 'sync_work' for md_start_sync().
+
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Reviewed-by: Xiao Ni <xni@redhat.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Link: https://lore.kernel.org/r/20230825031622.1530464-2-yukuai1@huaweicloud.com
+Stable-dep-of: 8d28d0ddb986 ("md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md.c | 10 ++++++----
+ drivers/md/md.h |  5 ++++-
+ 2 files changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 9bc19a5a4119b..342407ea87d83 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -648,13 +648,13 @@ void mddev_put(struct mddev *mddev)
+                * flush_workqueue() after mddev_find will succeed in waiting
+                * for the work to be done.
+                */
+-              INIT_WORK(&mddev->del_work, mddev_delayed_delete);
+               queue_work(md_misc_wq, &mddev->del_work);
+       }
+       spin_unlock(&all_mddevs_lock);
+ }
+ static void md_safemode_timeout(struct timer_list *t);
++static void md_start_sync(struct work_struct *ws);
+ void mddev_init(struct mddev *mddev)
+ {
+@@ -679,6 +679,9 @@ void mddev_init(struct mddev *mddev)
+       mddev->resync_min = 0;
+       mddev->resync_max = MaxSector;
+       mddev->level = LEVEL_NONE;
++
++      INIT_WORK(&mddev->sync_work, md_start_sync);
++      INIT_WORK(&mddev->del_work, mddev_delayed_delete);
+ }
+ EXPORT_SYMBOL_GPL(mddev_init);
+@@ -9333,7 +9336,7 @@ static int remove_and_add_spares(struct mddev *mddev,
+ static void md_start_sync(struct work_struct *ws)
+ {
+-      struct mddev *mddev = container_of(ws, struct mddev, del_work);
++      struct mddev *mddev = container_of(ws, struct mddev, sync_work);
+       rcu_assign_pointer(mddev->sync_thread,
+                          md_register_thread(md_do_sync, mddev, "resync"));
+@@ -9546,8 +9549,7 @@ void md_check_recovery(struct mddev *mddev)
+                                */
+                               md_bitmap_write_all(mddev->bitmap);
+                       }
+-                      INIT_WORK(&mddev->del_work, md_start_sync);
+-                      queue_work(md_misc_wq, &mddev->del_work);
++                      queue_work(md_misc_wq, &mddev->sync_work);
+                       goto unlock;
+               }
+       not_running:
+diff --git a/drivers/md/md.h b/drivers/md/md.h
+index f29fa8650cd0f..46995558d3bd9 100644
+--- a/drivers/md/md.h
++++ b/drivers/md/md.h
+@@ -453,7 +453,10 @@ struct mddev {
+       struct kernfs_node              *sysfs_degraded;        /*handle for 'degraded' */
+       struct kernfs_node              *sysfs_level;           /*handle for 'level' */
+-      struct work_struct del_work;    /* used for delayed sysfs removal */
++      /* used for delayed sysfs removal */
++      struct work_struct del_work;
++      /* used for register new sync thread */
++      struct work_struct sync_work;
+       /* "lock" protects:
+        *   flush_bio transition from NULL to !NULL
+-- 
+2.39.5
+
diff --git a/queue-6.6/media-uvcvideo-only-save-async-fh-if-success.patch b/queue-6.6/media-uvcvideo-only-save-async-fh-if-success.patch
new file mode 100644 (file)
index 0000000..9e47bde
--- /dev/null
@@ -0,0 +1,90 @@
+From bdbd431462fb9f9ac6e30fe18e91e528193f64ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Dec 2024 21:20:08 +0000
+Subject: media: uvcvideo: Only save async fh if success
+
+From: Ricardo Ribalda <ribalda@chromium.org>
+
+[ Upstream commit d9fecd096f67a4469536e040a8a10bbfb665918b ]
+
+Now we keep a reference to the active fh for any call to uvc_ctrl_set,
+regardless if it is an actual set or if it is a just a try or if the
+device refused the operation.
+
+We should only keep the file handle if the device actually accepted
+applying the operation.
+
+Cc: stable@vger.kernel.org
+Fixes: e5225c820c05 ("media: uvcvideo: Send a control event when a Control Change interrupt arrives")
+Suggested-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Link: https://lore.kernel.org/r/20241203-uvc-fix-async-v6-1-26c867231118@chromium.org
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/uvc/uvc_ctrl.c | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
+index f78e0c02b3379..478e2c1fdf0fd 100644
+--- a/drivers/media/usb/uvc/uvc_ctrl.c
++++ b/drivers/media/usb/uvc/uvc_ctrl.c
+@@ -1762,7 +1762,10 @@ int uvc_ctrl_begin(struct uvc_video_chain *chain)
+ }
+ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
+-      struct uvc_entity *entity, int rollback, struct uvc_control **err_ctrl)
++                                struct uvc_fh *handle,
++                                struct uvc_entity *entity,
++                                int rollback,
++                                struct uvc_control **err_ctrl)
+ {
+       struct uvc_control *ctrl;
+       unsigned int i;
+@@ -1810,6 +1813,10 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
+                               *err_ctrl = ctrl;
+                       return ret;
+               }
++
++              if (!rollback && handle &&
++                  ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)
++                      ctrl->handle = handle;
+       }
+       return 0;
+@@ -1846,8 +1853,8 @@ int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
+       /* Find the control. */
+       list_for_each_entry(entity, &chain->entities, chain) {
+-              ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback,
+-                                           &err_ctrl);
++              ret = uvc_ctrl_commit_entity(chain->dev, handle, entity,
++                                           rollback, &err_ctrl);
+               if (ret < 0) {
+                       if (ctrls)
+                               ctrls->error_idx =
+@@ -1997,9 +2004,6 @@ int uvc_ctrl_set(struct uvc_fh *handle,
+       mapping->set(mapping, value,
+               uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
+-      if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)
+-              ctrl->handle = handle;
+-
+       ctrl->dirty = 1;
+       ctrl->modified = 1;
+       return 0;
+@@ -2328,7 +2332,7 @@ int uvc_ctrl_restore_values(struct uvc_device *dev)
+                       ctrl->dirty = 1;
+               }
+-              ret = uvc_ctrl_commit_entity(dev, entity, 0, NULL);
++              ret = uvc_ctrl_commit_entity(dev, NULL, entity, 0, NULL);
+               if (ret < 0)
+                       return ret;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.6/media-uvcvideo-refactor-iterators.patch b/queue-6.6/media-uvcvideo-refactor-iterators.patch
new file mode 100644 (file)
index 0000000..c15e80d
--- /dev/null
@@ -0,0 +1,87 @@
+From 7480d2c9c6e75b5b7464fe59c3c77cbb363a0a89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Apr 2024 15:04:42 +0000
+Subject: media: uvcvideo: Refactor iterators
+
+From: Ricardo Ribalda <ribalda@chromium.org>
+
+[ Upstream commit 64627daf0c5f7838111f52bbbd1a597cb5d6871a ]
+
+Avoid using the iterators after the list_for_each() constructs.
+This patch should be a NOP, but makes cocci, happier:
+
+drivers/media/usb/uvc/uvc_ctrl.c:1861:44-50: ERROR: invalid reference to the index variable of the iterator on line 1850
+drivers/media/usb/uvc/uvc_ctrl.c:2195:17-23: ERROR: invalid reference to the index variable of the iterator on line 2179
+
+Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Stable-dep-of: d9fecd096f67 ("media: uvcvideo: Only save async fh if success")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/uvc/uvc_ctrl.c | 24 +++++++++++++-----------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
+index ce70e96b8fb52..f78e0c02b3379 100644
+--- a/drivers/media/usb/uvc/uvc_ctrl.c
++++ b/drivers/media/usb/uvc/uvc_ctrl.c
+@@ -1848,16 +1848,18 @@ int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
+       list_for_each_entry(entity, &chain->entities, chain) {
+               ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback,
+                                            &err_ctrl);
+-              if (ret < 0)
++              if (ret < 0) {
++                      if (ctrls)
++                              ctrls->error_idx =
++                                      uvc_ctrl_find_ctrl_idx(entity, ctrls,
++                                                             err_ctrl);
+                       goto done;
++              }
+       }
+       if (!rollback)
+               uvc_ctrl_send_events(handle, ctrls->controls, ctrls->count);
+ done:
+-      if (ret < 0 && ctrls)
+-              ctrls->error_idx = uvc_ctrl_find_ctrl_idx(entity, ctrls,
+-                                                        err_ctrl);
+       mutex_unlock(&chain->ctrl_mutex);
+       return ret;
+ }
+@@ -2170,7 +2172,7 @@ static int uvc_ctrl_init_xu_ctrl(struct uvc_device *dev,
+ int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
+       struct uvc_xu_control_query *xqry)
+ {
+-      struct uvc_entity *entity;
++      struct uvc_entity *entity, *iter;
+       struct uvc_control *ctrl;
+       unsigned int i;
+       bool found;
+@@ -2180,16 +2182,16 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
+       int ret;
+       /* Find the extension unit. */
+-      found = false;
+-      list_for_each_entry(entity, &chain->entities, chain) {
+-              if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT &&
+-                  entity->id == xqry->unit) {
+-                      found = true;
++      entity = NULL;
++      list_for_each_entry(iter, &chain->entities, chain) {
++              if (UVC_ENTITY_TYPE(iter) == UVC_VC_EXTENSION_UNIT &&
++                  iter->id == xqry->unit) {
++                      entity = iter;
+                       break;
+               }
+       }
+-      if (!found) {
++      if (!entity) {
+               uvc_dbg(chain->dev, CONTROL, "Extension unit %u not found\n",
+                       xqry->unit);
+               return -ENOENT;
+-- 
+2.39.5
+
diff --git a/queue-6.6/media-uvcvideo-remove-dangling-pointers.patch b/queue-6.6/media-uvcvideo-remove-dangling-pointers.patch
new file mode 100644 (file)
index 0000000..afa9b65
--- /dev/null
@@ -0,0 +1,179 @@
+From 129293d5f759d938d6568e015995a1b6172e8667 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Dec 2024 21:20:10 +0000
+Subject: media: uvcvideo: Remove dangling pointers
+
+From: Ricardo Ribalda <ribalda@chromium.org>
+
+[ Upstream commit 221cd51efe4565501a3dbf04cc011b537dcce7fb ]
+
+When an async control is written, we copy a pointer to the file handle
+that started the operation. That pointer will be used when the device is
+done. Which could be anytime in the future.
+
+If the user closes that file descriptor, its structure will be freed,
+and there will be one dangling pointer per pending async control, that
+the driver will try to use.
+
+Clean all the dangling pointers during release().
+
+To avoid adding a performance penalty in the most common case (no async
+operation), a counter has been introduced with some logic to make sure
+that it is properly handled.
+
+Cc: stable@vger.kernel.org
+Fixes: e5225c820c05 ("media: uvcvideo: Send a control event when a Control Change interrupt arrives")
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Link: https://lore.kernel.org/r/20241203-uvc-fix-async-v6-3-26c867231118@chromium.org
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/uvc/uvc_ctrl.c | 59 ++++++++++++++++++++++++++++++--
+ drivers/media/usb/uvc/uvc_v4l2.c |  2 ++
+ drivers/media/usb/uvc/uvcvideo.h |  9 ++++-
+ 3 files changed, 67 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
+index 478e2c1fdf0fd..028c4a5049af9 100644
+--- a/drivers/media/usb/uvc/uvc_ctrl.c
++++ b/drivers/media/usb/uvc/uvc_ctrl.c
+@@ -1532,6 +1532,40 @@ static void uvc_ctrl_send_slave_event(struct uvc_video_chain *chain,
+       uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes);
+ }
++static void uvc_ctrl_set_handle(struct uvc_fh *handle, struct uvc_control *ctrl,
++                              struct uvc_fh *new_handle)
++{
++      lockdep_assert_held(&handle->chain->ctrl_mutex);
++
++      if (new_handle) {
++              if (ctrl->handle)
++                      dev_warn_ratelimited(&handle->stream->dev->udev->dev,
++                                           "UVC non compliance: Setting an async control with a pending operation.");
++
++              if (new_handle == ctrl->handle)
++                      return;
++
++              if (ctrl->handle) {
++                      WARN_ON(!ctrl->handle->pending_async_ctrls);
++                      if (ctrl->handle->pending_async_ctrls)
++                              ctrl->handle->pending_async_ctrls--;
++              }
++
++              ctrl->handle = new_handle;
++              handle->pending_async_ctrls++;
++              return;
++      }
++
++      /* Cannot clear the handle for a control not owned by us.*/
++      if (WARN_ON(ctrl->handle != handle))
++              return;
++
++      ctrl->handle = NULL;
++      if (WARN_ON(!handle->pending_async_ctrls))
++              return;
++      handle->pending_async_ctrls--;
++}
++
+ void uvc_ctrl_status_event(struct uvc_video_chain *chain,
+                          struct uvc_control *ctrl, const u8 *data)
+ {
+@@ -1542,7 +1576,8 @@ void uvc_ctrl_status_event(struct uvc_video_chain *chain,
+       mutex_lock(&chain->ctrl_mutex);
+       handle = ctrl->handle;
+-      ctrl->handle = NULL;
++      if (handle)
++              uvc_ctrl_set_handle(handle, ctrl, NULL);
+       list_for_each_entry(mapping, &ctrl->info.mappings, list) {
+               s32 value = __uvc_ctrl_get_value(mapping, data);
+@@ -1816,7 +1851,7 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
+               if (!rollback && handle &&
+                   ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)
+-                      ctrl->handle = handle;
++                      uvc_ctrl_set_handle(handle, ctrl, handle);
+       }
+       return 0;
+@@ -2754,6 +2789,26 @@ int uvc_ctrl_init_device(struct uvc_device *dev)
+       return 0;
+ }
++void uvc_ctrl_cleanup_fh(struct uvc_fh *handle)
++{
++      struct uvc_entity *entity;
++
++      guard(mutex)(&handle->chain->ctrl_mutex);
++
++      if (!handle->pending_async_ctrls)
++              return;
++
++      list_for_each_entry(entity, &handle->chain->dev->entities, list) {
++              for (unsigned int i = 0; i < entity->ncontrols; ++i) {
++                      if (entity->controls[i].handle != handle)
++                              continue;
++                      uvc_ctrl_set_handle(handle, &entity->controls[i], NULL);
++              }
++      }
++
++      WARN_ON(handle->pending_async_ctrls);
++}
++
+ /*
+  * Cleanup device controls.
+  */
+diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
+index f4988f03640ae..7bcd706281daf 100644
+--- a/drivers/media/usb/uvc/uvc_v4l2.c
++++ b/drivers/media/usb/uvc/uvc_v4l2.c
+@@ -659,6 +659,8 @@ static int uvc_v4l2_release(struct file *file)
+       uvc_dbg(stream->dev, CALLS, "%s\n", __func__);
++      uvc_ctrl_cleanup_fh(handle);
++
+       /* Only free resources if this is a privileged handle. */
+       if (uvc_has_privileges(handle))
+               uvc_queue_release(&stream->queue);
+diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
+index 30fd056b2aec9..e99bfaa622669 100644
+--- a/drivers/media/usb/uvc/uvcvideo.h
++++ b/drivers/media/usb/uvc/uvcvideo.h
+@@ -334,7 +334,11 @@ struct uvc_video_chain {
+       struct uvc_entity *processing;          /* Processing unit */
+       struct uvc_entity *selector;            /* Selector unit */
+-      struct mutex ctrl_mutex;                /* Protects ctrl.info */
++      struct mutex ctrl_mutex;                /*
++                                               * Protects ctrl.info,
++                                               * ctrl.handle and
++                                               * uvc_fh.pending_async_ctrls
++                                               */
+       struct v4l2_prio_state prio;            /* V4L2 priority state */
+       u32 caps;                               /* V4L2 chain-wide caps */
+@@ -609,6 +613,7 @@ struct uvc_fh {
+       struct uvc_video_chain *chain;
+       struct uvc_streaming *stream;
+       enum uvc_handle_state state;
++      unsigned int pending_async_ctrls;
+ };
+ struct uvc_driver {
+@@ -794,6 +799,8 @@ int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id,
+ int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
+                     struct uvc_xu_control_query *xqry);
++void uvc_ctrl_cleanup_fh(struct uvc_fh *handle);
++
+ /* Utility functions */
+ struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts,
+                                           u8 epaddr);
+-- 
+2.39.5
+
diff --git a/queue-6.6/memcg-fix-soft-lockup-in-the-oom-process.patch b/queue-6.6/memcg-fix-soft-lockup-in-the-oom-process.patch
new file mode 100644 (file)
index 0000000..efa592b
--- /dev/null
@@ -0,0 +1,128 @@
+From 3699e0eb6a675b9ce9f53afd78f07001d4dae1d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Dec 2024 02:52:38 +0000
+Subject: memcg: fix soft lockup in the OOM process
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Chen Ridong <chenridong@huawei.com>
+
+[ Upstream commit ade81479c7dda1ce3eedb215c78bc615bbd04f06 ]
+
+A soft lockup issue was found in the product with about 56,000 tasks were
+in the OOM cgroup, it was traversing them when the soft lockup was
+triggered.
+
+watchdog: BUG: soft lockup - CPU#2 stuck for 23s! [VM Thread:1503066]
+CPU: 2 PID: 1503066 Comm: VM Thread Kdump: loaded Tainted: G
+Hardware name: Huawei Cloud OpenStack Nova, BIOS
+RIP: 0010:console_unlock+0x343/0x540
+RSP: 0000:ffffb751447db9a0 EFLAGS: 00000247 ORIG_RAX: ffffffffffffff13
+RAX: 0000000000000001 RBX: 0000000000000000 RCX: 00000000ffffffff
+RDX: 0000000000000000 RSI: 0000000000000004 RDI: 0000000000000247
+RBP: ffffffffafc71f90 R08: 0000000000000000 R09: 0000000000000040
+R10: 0000000000000080 R11: 0000000000000000 R12: ffffffffafc74bd0
+R13: ffffffffaf60a220 R14: 0000000000000247 R15: 0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007f2fe6ad91f0 CR3: 00000004b2076003 CR4: 0000000000360ee0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ vprintk_emit+0x193/0x280
+ printk+0x52/0x6e
+ dump_task+0x114/0x130
+ mem_cgroup_scan_tasks+0x76/0x100
+ dump_header+0x1fe/0x210
+ oom_kill_process+0xd1/0x100
+ out_of_memory+0x125/0x570
+ mem_cgroup_out_of_memory+0xb5/0xd0
+ try_charge+0x720/0x770
+ mem_cgroup_try_charge+0x86/0x180
+ mem_cgroup_try_charge_delay+0x1c/0x40
+ do_anonymous_page+0xb5/0x390
+ handle_mm_fault+0xc4/0x1f0
+
+This is because thousands of processes are in the OOM cgroup, it takes a
+long time to traverse all of them.  As a result, this lead to soft lockup
+in the OOM process.
+
+To fix this issue, call 'cond_resched' in the 'mem_cgroup_scan_tasks'
+function per 1000 iterations.  For global OOM, call
+'touch_softlockup_watchdog' per 1000 iterations to avoid this issue.
+
+Link: https://lkml.kernel.org/r/20241224025238.3768787-1-chenridong@huaweicloud.com
+Fixes: 9cbb78bb3143 ("mm, memcg: introduce own oom handler to iterate only over its own threads")
+Signed-off-by: Chen Ridong <chenridong@huawei.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: Roman Gushchin <roman.gushchin@linux.dev>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Shakeel Butt <shakeelb@google.com>
+Cc: Muchun Song <songmuchun@bytedance.com>
+Cc: Michal Koutný <mkoutny@suse.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/memcontrol.c | 7 ++++++-
+ mm/oom_kill.c   | 8 +++++++-
+ 2 files changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/mm/memcontrol.c b/mm/memcontrol.c
+index d2ceadd11b100..9bf5a69e20d87 100644
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -1266,6 +1266,7 @@ void mem_cgroup_scan_tasks(struct mem_cgroup *memcg,
+ {
+       struct mem_cgroup *iter;
+       int ret = 0;
++      int i = 0;
+       BUG_ON(mem_cgroup_is_root(memcg));
+@@ -1274,8 +1275,12 @@ void mem_cgroup_scan_tasks(struct mem_cgroup *memcg,
+               struct task_struct *task;
+               css_task_iter_start(&iter->css, CSS_TASK_ITER_PROCS, &it);
+-              while (!ret && (task = css_task_iter_next(&it)))
++              while (!ret && (task = css_task_iter_next(&it))) {
++                      /* Avoid potential softlockup warning */
++                      if ((++i & 1023) == 0)
++                              cond_resched();
+                       ret = fn(task, arg);
++              }
+               css_task_iter_end(&it);
+               if (ret) {
+                       mem_cgroup_iter_break(memcg, iter);
+diff --git a/mm/oom_kill.c b/mm/oom_kill.c
+index 22b99f835c8c4..17a2ef9f93d3d 100644
+--- a/mm/oom_kill.c
++++ b/mm/oom_kill.c
+@@ -45,6 +45,7 @@
+ #include <linux/init.h>
+ #include <linux/mmu_notifier.h>
+ #include <linux/cred.h>
++#include <linux/nmi.h>
+ #include <asm/tlb.h>
+ #include "internal.h"
+@@ -430,10 +431,15 @@ static void dump_tasks(struct oom_control *oc)
+               mem_cgroup_scan_tasks(oc->memcg, dump_task, oc);
+       else {
+               struct task_struct *p;
++              int i = 0;
+               rcu_read_lock();
+-              for_each_process(p)
++              for_each_process(p) {
++                      /* Avoid potential softlockup warning */
++                      if ((++i & 1023) == 0)
++                              touch_softlockup_watchdog();
+                       dump_task(p, oc);
++              }
+               rcu_read_unlock();
+       }
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.6/mm-update-mark_victim-tracepoints-fields.patch b/queue-6.6/mm-update-mark_victim-tracepoints-fields.patch
new file mode 100644 (file)
index 0000000..13f76e0
--- /dev/null
@@ -0,0 +1,150 @@
+From b434aad3912b847e02ea9e82ee598e1a41820404 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Feb 2024 17:32:49 +0000
+Subject: mm: update mark_victim tracepoints fields
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Carlos Galo <carlosgalo@google.com>
+
+[ Upstream commit 72ba14deb40a9e9668ec5e66a341ed657e5215c2 ]
+
+The current implementation of the mark_victim tracepoint provides only the
+process ID (pid) of the victim process.  This limitation poses challenges
+for userspace tools requiring real-time OOM analysis and intervention.
+Although this information is available from the kernel logs, it’s not
+the appropriate format to provide OOM notifications.  In Android, BPF
+programs are used with the mark_victim trace events to notify userspace of
+an OOM kill.  For consistency, update the trace event to include the same
+information about the OOMed victim as the kernel logs.
+
+- UID
+   In Android each installed application has a unique UID. Including
+   the `uid` assists in correlating OOM events with specific apps.
+
+- Process Name (comm)
+   Enables identification of the affected process.
+
+- OOM Score
+  Will allow userspace to get additional insight of the relative kill
+  priority of the OOM victim. In Android, the oom_score_adj is used to
+  categorize app state (foreground, background, etc.), which aids in
+  analyzing user-perceptible impacts of OOM events [1].
+
+- Total VM, RSS Stats, and pgtables
+  Amount of memory used by the victim that will, potentially, be freed up
+  by killing it.
+
+[1] https://cs.android.com/android/platform/superproject/main/+/246dc8fc95b6d93afcba5c6d6c133307abb3ac2e:frameworks/base/services/core/java/com/android/server/am/ProcessList.java;l=188-283
+Signed-off-by: Carlos Galo <carlosgalo@google.com>
+Reviewed-by: Steven Rostedt <rostedt@goodmis.org>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: ade81479c7dd ("memcg: fix soft lockup in the OOM process")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/trace/events/oom.h | 36 ++++++++++++++++++++++++++++++++----
+ mm/oom_kill.c              |  6 +++++-
+ 2 files changed, 37 insertions(+), 5 deletions(-)
+
+diff --git a/include/trace/events/oom.h b/include/trace/events/oom.h
+index 26a11e4a2c361..b799f3bcba823 100644
+--- a/include/trace/events/oom.h
++++ b/include/trace/events/oom.h
+@@ -7,6 +7,8 @@
+ #include <linux/tracepoint.h>
+ #include <trace/events/mmflags.h>
++#define PG_COUNT_TO_KB(x) ((x) << (PAGE_SHIFT - 10))
++
+ TRACE_EVENT(oom_score_adj_update,
+       TP_PROTO(struct task_struct *task),
+@@ -72,19 +74,45 @@ TRACE_EVENT(reclaim_retry_zone,
+ );
+ TRACE_EVENT(mark_victim,
+-      TP_PROTO(int pid),
++      TP_PROTO(struct task_struct *task, uid_t uid),
+-      TP_ARGS(pid),
++      TP_ARGS(task, uid),
+       TP_STRUCT__entry(
+               __field(int, pid)
++              __string(comm, task->comm)
++              __field(unsigned long, total_vm)
++              __field(unsigned long, anon_rss)
++              __field(unsigned long, file_rss)
++              __field(unsigned long, shmem_rss)
++              __field(uid_t, uid)
++              __field(unsigned long, pgtables)
++              __field(short, oom_score_adj)
+       ),
+       TP_fast_assign(
+-              __entry->pid = pid;
++              __entry->pid = task->pid;
++              __assign_str(comm, task->comm);
++              __entry->total_vm = PG_COUNT_TO_KB(task->mm->total_vm);
++              __entry->anon_rss = PG_COUNT_TO_KB(get_mm_counter(task->mm, MM_ANONPAGES));
++              __entry->file_rss = PG_COUNT_TO_KB(get_mm_counter(task->mm, MM_FILEPAGES));
++              __entry->shmem_rss = PG_COUNT_TO_KB(get_mm_counter(task->mm, MM_SHMEMPAGES));
++              __entry->uid = uid;
++              __entry->pgtables = mm_pgtables_bytes(task->mm) >> 10;
++              __entry->oom_score_adj = task->signal->oom_score_adj;
+       ),
+-      TP_printk("pid=%d", __entry->pid)
++      TP_printk("pid=%d comm=%s total-vm=%lukB anon-rss=%lukB file-rss:%lukB shmem-rss:%lukB uid=%u pgtables=%lukB oom_score_adj=%hd",
++              __entry->pid,
++              __get_str(comm),
++              __entry->total_vm,
++              __entry->anon_rss,
++              __entry->file_rss,
++              __entry->shmem_rss,
++              __entry->uid,
++              __entry->pgtables,
++              __entry->oom_score_adj
++      )
+ );
+ TRACE_EVENT(wake_reaper,
+diff --git a/mm/oom_kill.c b/mm/oom_kill.c
+index 44bde56ecd025..22b99f835c8c4 100644
+--- a/mm/oom_kill.c
++++ b/mm/oom_kill.c
+@@ -44,6 +44,7 @@
+ #include <linux/kthread.h>
+ #include <linux/init.h>
+ #include <linux/mmu_notifier.h>
++#include <linux/cred.h>
+ #include <asm/tlb.h>
+ #include "internal.h"
+@@ -755,6 +756,7 @@ static inline void queue_oom_reaper(struct task_struct *tsk)
+  */
+ static void mark_oom_victim(struct task_struct *tsk)
+ {
++      const struct cred *cred;
+       struct mm_struct *mm = tsk->mm;
+       WARN_ON(oom_killer_disabled);
+@@ -774,7 +776,9 @@ static void mark_oom_victim(struct task_struct *tsk)
+        */
+       __thaw_task(tsk);
+       atomic_inc(&oom_victims);
+-      trace_mark_victim(tsk->pid);
++      cred = get_task_cred(tsk);
++      trace_mark_victim(tsk, cred->uid.val);
++      put_cred(cred);
+ }
+ /**
+-- 
+2.39.5
+
diff --git a/queue-6.6/net-add-non-rcu-dev_getbyhwaddr-helper.patch b/queue-6.6/net-add-non-rcu-dev_getbyhwaddr-helper.patch
new file mode 100644 (file)
index 0000000..db39e8e
--- /dev/null
@@ -0,0 +1,118 @@
+From 334b3bbd86ae4f6845e8b41dfa5b57a8106704d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Feb 2025 05:49:30 -0800
+Subject: net: Add non-RCU dev_getbyhwaddr() helper
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 4b5a28b38c4a0106c64416a1b2042405166b26ce ]
+
+Add dedicated helper for finding devices by hardware address when
+holding rtnl_lock, similar to existing dev_getbyhwaddr_rcu(). This prevents
+PROVE_LOCKING warnings when rtnl_lock is held but RCU read lock is not.
+
+Extract common address comparison logic into dev_addr_cmp().
+
+The context about this change could be found in the following
+discussion:
+
+Link: https://lore.kernel.org/all/20250206-scarlet-ermine-of-improvement-1fcac5@leitao/
+
+Cc: kuniyu@amazon.com
+Cc: ushankar@purestorage.com
+Suggested-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20250218-arm_fix_selftest-v5-1-d3d6892db9e1@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 4eae0ee0f1e6 ("arp: switch to dev_getbyhwaddr() in arp_req_set_public()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/netdevice.h |  2 ++
+ net/core/dev.c            | 37 ++++++++++++++++++++++++++++++++++---
+ 2 files changed, 36 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index 95ee88dfe0b9c..337a9d1c558f3 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -3072,6 +3072,8 @@ static inline struct net_device *first_net_device_rcu(struct net *net)
+ }
+ int netdev_boot_setup_check(struct net_device *dev);
++struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type,
++                                 const char *hwaddr);
+ struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type,
+                                      const char *hwaddr);
+ struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type);
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 479a3892f98c3..8c30cdcf05d4b 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -954,6 +954,12 @@ int netdev_get_name(struct net *net, char *name, int ifindex)
+       return ret;
+ }
++static bool dev_addr_cmp(struct net_device *dev, unsigned short type,
++                       const char *ha)
++{
++      return dev->type == type && !memcmp(dev->dev_addr, ha, dev->addr_len);
++}
++
+ /**
+  *    dev_getbyhwaddr_rcu - find a device by its hardware address
+  *    @net: the applicable net namespace
+@@ -962,7 +968,7 @@ int netdev_get_name(struct net *net, char *name, int ifindex)
+  *
+  *    Search for an interface by MAC address. Returns NULL if the device
+  *    is not found or a pointer to the device.
+- *    The caller must hold RCU or RTNL.
++ *    The caller must hold RCU.
+  *    The returned device has not had its ref count increased
+  *    and the caller must therefore be careful about locking
+  *
+@@ -974,14 +980,39 @@ struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type,
+       struct net_device *dev;
+       for_each_netdev_rcu(net, dev)
+-              if (dev->type == type &&
+-                  !memcmp(dev->dev_addr, ha, dev->addr_len))
++              if (dev_addr_cmp(dev, type, ha))
+                       return dev;
+       return NULL;
+ }
+ EXPORT_SYMBOL(dev_getbyhwaddr_rcu);
++/**
++ * dev_getbyhwaddr() - find a device by its hardware address
++ * @net: the applicable net namespace
++ * @type: media type of device
++ * @ha: hardware address
++ *
++ * Similar to dev_getbyhwaddr_rcu(), but the owner needs to hold
++ * rtnl_lock.
++ *
++ * Context: rtnl_lock() must be held.
++ * Return: pointer to the net_device, or NULL if not found
++ */
++struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type,
++                                 const char *ha)
++{
++      struct net_device *dev;
++
++      ASSERT_RTNL();
++      for_each_netdev(net, dev)
++              if (dev_addr_cmp(dev, type, ha))
++                      return dev;
++
++      return NULL;
++}
++EXPORT_SYMBOL(dev_getbyhwaddr);
++
+ struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type)
+ {
+       struct net_device *dev, *ret = NULL;
+-- 
+2.39.5
+
diff --git a/queue-6.6/net-axienet-set-mac_managed_pm.patch b/queue-6.6/net-axienet-set-mac_managed_pm.patch
new file mode 100644 (file)
index 0000000..998abd8
--- /dev/null
@@ -0,0 +1,43 @@
+From 78adb74b443acdb08610615257ce72f1b507fb16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 13:58:42 +0800
+Subject: net: axienet: Set mac_managed_pm
+
+From: Nick Hu <nick.hu@sifive.com>
+
+[ Upstream commit a370295367b55662a32a4be92565fe72a5aa79bb ]
+
+The external PHY will undergo a soft reset twice during the resume process
+when it wake up from suspend. The first reset occurs when the axienet
+driver calls phylink_of_phy_connect(), and the second occurs when
+mdio_bus_phy_resume() invokes phy_init_hw(). The second soft reset of the
+external PHY does not reinitialize the internal PHY, which causes issues
+with the internal PHY, resulting in the PHY link being down. To prevent
+this, setting the mac_managed_pm flag skips the mdio_bus_phy_resume()
+function.
+
+Fixes: a129b41fe0a8 ("Revert "net: phy: dp83867: perform soft reset and retain established link"")
+Signed-off-by: Nick Hu <nick.hu@sifive.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20250217055843.19799-1-nick.hu@sifive.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+index 02e11827440b5..3517a2275821f 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -2161,6 +2161,7 @@ static int axienet_probe(struct platform_device *pdev)
+       lp->phylink_config.dev = &ndev->dev;
+       lp->phylink_config.type = PHYLINK_NETDEV;
++      lp->phylink_config.mac_managed_pm = true;
+       lp->phylink_config.mac_capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE |
+               MAC_10FD | MAC_100FD | MAC_1000FD;
+-- 
+2.39.5
+
diff --git a/queue-6.6/net-sched-cls_api-fix-error-handling-causing-null-de.patch b/queue-6.6/net-sched-cls_api-fix-error-handling-causing-null-de.patch
new file mode 100644 (file)
index 0000000..4f6cb6a
--- /dev/null
@@ -0,0 +1,54 @@
+From fa576c563cd4c52013a5e10e6486cd9474c40fcd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Feb 2025 23:36:10 +0100
+Subject: net/sched: cls_api: fix error handling causing NULL dereference
+
+From: Pierre Riteau <pierre@stackhpc.com>
+
+[ Upstream commit 071ed42cff4fcdd89025d966d48eabef59913bf2 ]
+
+tcf_exts_miss_cookie_base_alloc() calls xa_alloc_cyclic() which can
+return 1 if the allocation succeeded after wrapping. This was treated as
+an error, with value 1 returned to caller tcf_exts_init_ex() which sets
+exts->actions to NULL and returns 1 to caller fl_change().
+
+fl_change() treats err == 1 as success, calling tcf_exts_validate_ex()
+which calls tcf_action_init() with exts->actions as argument, where it
+is dereferenced.
+
+Example trace:
+
+BUG: kernel NULL pointer dereference, address: 0000000000000000
+CPU: 114 PID: 16151 Comm: handler114 Kdump: loaded Not tainted 5.14.0-503.16.1.el9_5.x86_64 #1
+RIP: 0010:tcf_action_init+0x1f8/0x2c0
+Call Trace:
+ tcf_action_init+0x1f8/0x2c0
+ tcf_exts_validate_ex+0x175/0x190
+ fl_change+0x537/0x1120 [cls_flower]
+
+Fixes: 80cd22c35c90 ("net/sched: cls_api: Support hardware miss to tc action")
+Signed-off-by: Pierre Riteau <pierre@stackhpc.com>
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Link: https://patch.msgid.link/20250213223610.320278-1-pierre@stackhpc.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/cls_api.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
+index 84e18b5f72a30..96c39e9a873c7 100644
+--- a/net/sched/cls_api.c
++++ b/net/sched/cls_api.c
+@@ -97,7 +97,7 @@ tcf_exts_miss_cookie_base_alloc(struct tcf_exts *exts, struct tcf_proto *tp,
+       err = xa_alloc_cyclic(&tcf_exts_miss_cookies_xa, &n->miss_cookie_base,
+                             n, xa_limit_32b, &next, GFP_KERNEL);
+-      if (err)
++      if (err < 0)
+               goto err_xa_alloc;
+       exts->miss_cookie_node = n;
+-- 
+2.39.5
+
diff --git a/queue-6.6/nvmem-create-a-header-for-internal-sharing.patch b/queue-6.6/nvmem-create-a-header-for-internal-sharing.patch
new file mode 100644 (file)
index 0000000..98d760f
--- /dev/null
@@ -0,0 +1,105 @@
+From 65e58cb85610cd4b55f0abffd83ee044ee785114 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Dec 2023 11:15:29 +0000
+Subject: nvmem: Create a header for internal sharing
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+[ Upstream commit ec9c08a1cb8dc5e8e003f95f5f62de41dde235bb ]
+
+Before adding all the NVMEM layout bus infrastructure to the core, let's
+move the main nvmem_device structure in an internal header, only
+available to the core. This way all the additional code can be added in
+a dedicated file in order to keep the current core file tidy.
+
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20231215111536.316972-4-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 391b06ecb63e ("nvmem: imx-ocotp-ele: fix MAC address byte order")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvmem/core.c      | 24 +-----------------------
+ drivers/nvmem/internals.h | 35 +++++++++++++++++++++++++++++++++++
+ 2 files changed, 36 insertions(+), 23 deletions(-)
+ create mode 100644 drivers/nvmem/internals.h
+
+diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
+index fd11d3825cf85..ec35886e921a8 100644
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -19,29 +19,7 @@
+ #include <linux/of.h>
+ #include <linux/slab.h>
+-struct nvmem_device {
+-      struct module           *owner;
+-      struct device           dev;
+-      int                     stride;
+-      int                     word_size;
+-      int                     id;
+-      struct kref             refcnt;
+-      size_t                  size;
+-      bool                    read_only;
+-      bool                    root_only;
+-      int                     flags;
+-      enum nvmem_type         type;
+-      struct bin_attribute    eeprom;
+-      struct device           *base_dev;
+-      struct list_head        cells;
+-      const struct nvmem_keepout *keepout;
+-      unsigned int            nkeepout;
+-      nvmem_reg_read_t        reg_read;
+-      nvmem_reg_write_t       reg_write;
+-      struct gpio_desc        *wp_gpio;
+-      struct nvmem_layout     *layout;
+-      void *priv;
+-};
++#include "internals.h"
+ #define to_nvmem_device(d) container_of(d, struct nvmem_device, dev)
+diff --git a/drivers/nvmem/internals.h b/drivers/nvmem/internals.h
+new file mode 100644
+index 0000000000000..ce353831cd655
+--- /dev/null
++++ b/drivers/nvmem/internals.h
+@@ -0,0 +1,35 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++
++#ifndef _LINUX_NVMEM_INTERNALS_H
++#define _LINUX_NVMEM_INTERNALS_H
++
++#include <linux/device.h>
++#include <linux/nvmem-consumer.h>
++#include <linux/nvmem-provider.h>
++
++struct nvmem_device {
++      struct module           *owner;
++      struct device           dev;
++      struct list_head        node;
++      int                     stride;
++      int                     word_size;
++      int                     id;
++      struct kref             refcnt;
++      size_t                  size;
++      bool                    read_only;
++      bool                    root_only;
++      int                     flags;
++      enum nvmem_type         type;
++      struct bin_attribute    eeprom;
++      struct device           *base_dev;
++      struct list_head        cells;
++      const struct nvmem_keepout *keepout;
++      unsigned int            nkeepout;
++      nvmem_reg_read_t        reg_read;
++      nvmem_reg_write_t       reg_write;
++      struct gpio_desc        *wp_gpio;
++      struct nvmem_layout     *layout;
++      void *priv;
++};
++
++#endif  /* ifndef _LINUX_NVMEM_INTERNALS_H */
+-- 
+2.39.5
+
diff --git a/queue-6.6/nvmem-imx-ocotp-ele-fix-mac-address-byte-order.patch b/queue-6.6/nvmem-imx-ocotp-ele-fix-mac-address-byte-order.patch
new file mode 100644 (file)
index 0000000..5bf2028
--- /dev/null
@@ -0,0 +1,80 @@
+From 93f1413f9c6dcfb7728c8df89f42dfede86d75cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Dec 2024 14:18:58 +0000
+Subject: nvmem: imx-ocotp-ele: fix MAC address byte order
+
+From: Sascha Hauer <s.hauer@pengutronix.de>
+
+[ Upstream commit 391b06ecb63e6eacd054582cb4eb738dfbf5eb77 ]
+
+According to the i.MX93 Fusemap the two MAC addresses are stored in
+words 315 to 317 like this:
+
+315    MAC1_ADDR_31_0[31:0]
+316    MAC1_ADDR_47_32[47:32]
+       MAC2_ADDR_15_0[15:0]
+317    MAC2_ADDR_47_16[31:0]
+
+This means the MAC addresses are stored in reverse byte order. We have
+to swap the bytes before passing them to the upper layers. The storage
+format is consistent to the one used on i.MX6 using imx-ocotp driver
+which does the same byte swapping as introduced here.
+
+With this patch the MAC address on my i.MX93 TQ board correctly reads as
+00:d0:93:6b:27:b8 instead of b8:27:6b:93:d0:00.
+
+Fixes: 22e9e6fcfb50 ("nvmem: imx: support i.MX93 OCOTP")
+Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
+Cc: stable <stable@kernel.org>
+Reviewed-by: Peng Fan <peng.fan@nxp.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20241230141901.263976-4-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvmem/imx-ocotp-ele.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c
+index dfc925edfc83e..1356ec93bfd00 100644
+--- a/drivers/nvmem/imx-ocotp-ele.c
++++ b/drivers/nvmem/imx-ocotp-ele.c
+@@ -107,6 +107,26 @@ static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, siz
+       return 0;
+ };
++static int imx_ocotp_cell_pp(void *context, const char *id, int index,
++                           unsigned int offset, void *data, size_t bytes)
++{
++      u8 *buf = data;
++      int i;
++
++      /* Deal with some post processing of nvmem cell data */
++      if (id && !strcmp(id, "mac-address"))
++              for (i = 0; i < bytes / 2; i++)
++                      swap(buf[i], buf[bytes - i - 1]);
++
++      return 0;
++}
++
++static void imx_ocotp_fixup_dt_cell_info(struct nvmem_device *nvmem,
++                                       struct nvmem_cell_info *cell)
++{
++      cell->read_post_process = imx_ocotp_cell_pp;
++}
++
+ static int imx_ele_ocotp_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+@@ -133,6 +153,8 @@ static int imx_ele_ocotp_probe(struct platform_device *pdev)
+       priv->config.stride = 1;
+       priv->config.priv = priv;
+       priv->config.read_only = true;
++      priv->config.add_legacy_fixed_of_cells = true;
++      priv->config.fixup_dt_cell_info = imx_ocotp_fixup_dt_cell_info;
+       mutex_init(&priv->lock);
+       nvmem = devm_nvmem_register(dev, &priv->config);
+-- 
+2.39.5
+
diff --git a/queue-6.6/nvmem-move-and-rename-fixup_cell_info.patch b/queue-6.6/nvmem-move-and-rename-fixup_cell_info.patch
new file mode 100644 (file)
index 0000000..e80d98e
--- /dev/null
@@ -0,0 +1,188 @@
+From 29897786a6ff9cb457846a557609bdf5419e77f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Dec 2023 11:15:31 +0000
+Subject: nvmem: Move and rename ->fixup_cell_info()
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+[ Upstream commit 1172460e716784ac7e1049a537bdca8edbf97360 ]
+
+This hook is meant to be used by any provider and instantiating a layout
+just for this is useless. Let's instead move this hook to the nvmem
+device and add it to the config structure to be easily shared by the
+providers.
+
+While at moving this hook, rename it ->fixup_dt_cell_info() to clarify
+its main intended purpose.
+
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20231215111536.316972-6-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 391b06ecb63e ("nvmem: imx-ocotp-ele: fix MAC address byte order")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvmem/core.c           |  6 +++---
+ drivers/nvmem/imx-ocotp.c      | 11 +++--------
+ drivers/nvmem/internals.h      |  2 ++
+ drivers/nvmem/mtk-efuse.c      | 11 +++--------
+ include/linux/nvmem-provider.h |  9 ++++-----
+ 5 files changed, 15 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
+index ed8a1cba361e2..3ea94bc26e800 100644
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -674,7 +674,6 @@ static int nvmem_validate_keepouts(struct nvmem_device *nvmem)
+ static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
+ {
+-      struct nvmem_layout *layout = nvmem->layout;
+       struct device *dev = &nvmem->dev;
+       struct device_node *child;
+       const __be32 *addr;
+@@ -704,8 +703,8 @@ static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_nod
+               info.np = of_node_get(child);
+-              if (layout && layout->fixup_cell_info)
+-                      layout->fixup_cell_info(nvmem, layout, &info);
++              if (nvmem->fixup_dt_cell_info)
++                      nvmem->fixup_dt_cell_info(nvmem, &info);
+               ret = nvmem_add_one_cell(nvmem, &info);
+               kfree(info.name);
+@@ -902,6 +901,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
+       kref_init(&nvmem->refcnt);
+       INIT_LIST_HEAD(&nvmem->cells);
++      nvmem->fixup_dt_cell_info = config->fixup_dt_cell_info;
+       nvmem->owner = config->owner;
+       if (!nvmem->owner && config->dev->driver)
+diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c
+index f1e202efaa497..79dd4fda03295 100644
+--- a/drivers/nvmem/imx-ocotp.c
++++ b/drivers/nvmem/imx-ocotp.c
+@@ -583,17 +583,12 @@ static const struct of_device_id imx_ocotp_dt_ids[] = {
+ };
+ MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids);
+-static void imx_ocotp_fixup_cell_info(struct nvmem_device *nvmem,
+-                                    struct nvmem_layout *layout,
+-                                    struct nvmem_cell_info *cell)
++static void imx_ocotp_fixup_dt_cell_info(struct nvmem_device *nvmem,
++                                       struct nvmem_cell_info *cell)
+ {
+       cell->read_post_process = imx_ocotp_cell_pp;
+ }
+-static struct nvmem_layout imx_ocotp_layout = {
+-      .fixup_cell_info = imx_ocotp_fixup_cell_info,
+-};
+-
+ static int imx_ocotp_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+@@ -619,7 +614,7 @@ static int imx_ocotp_probe(struct platform_device *pdev)
+       imx_ocotp_nvmem_config.size = 4 * priv->params->nregs;
+       imx_ocotp_nvmem_config.dev = dev;
+       imx_ocotp_nvmem_config.priv = priv;
+-      imx_ocotp_nvmem_config.layout = &imx_ocotp_layout;
++      imx_ocotp_nvmem_config.fixup_dt_cell_info = &imx_ocotp_fixup_dt_cell_info;
+       priv->config = &imx_ocotp_nvmem_config;
+diff --git a/drivers/nvmem/internals.h b/drivers/nvmem/internals.h
+index ce353831cd655..893553fbdf51a 100644
+--- a/drivers/nvmem/internals.h
++++ b/drivers/nvmem/internals.h
+@@ -23,6 +23,8 @@ struct nvmem_device {
+       struct bin_attribute    eeprom;
+       struct device           *base_dev;
+       struct list_head        cells;
++      void (*fixup_dt_cell_info)(struct nvmem_device *nvmem,
++                                 struct nvmem_cell_info *cell);
+       const struct nvmem_keepout *keepout;
+       unsigned int            nkeepout;
+       nvmem_reg_read_t        reg_read;
+diff --git a/drivers/nvmem/mtk-efuse.c b/drivers/nvmem/mtk-efuse.c
+index 87c94686cfd21..84f05b40a4112 100644
+--- a/drivers/nvmem/mtk-efuse.c
++++ b/drivers/nvmem/mtk-efuse.c
+@@ -45,9 +45,8 @@ static int mtk_efuse_gpu_speedbin_pp(void *context, const char *id, int index,
+       return 0;
+ }
+-static void mtk_efuse_fixup_cell_info(struct nvmem_device *nvmem,
+-                                    struct nvmem_layout *layout,
+-                                    struct nvmem_cell_info *cell)
++static void mtk_efuse_fixup_dt_cell_info(struct nvmem_device *nvmem,
++                                       struct nvmem_cell_info *cell)
+ {
+       size_t sz = strlen(cell->name);
+@@ -61,10 +60,6 @@ static void mtk_efuse_fixup_cell_info(struct nvmem_device *nvmem,
+               cell->read_post_process = mtk_efuse_gpu_speedbin_pp;
+ }
+-static struct nvmem_layout mtk_efuse_layout = {
+-      .fixup_cell_info = mtk_efuse_fixup_cell_info,
+-};
+-
+ static int mtk_efuse_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+@@ -91,7 +86,7 @@ static int mtk_efuse_probe(struct platform_device *pdev)
+       econfig.priv = priv;
+       econfig.dev = dev;
+       if (pdata->uses_post_processing)
+-              econfig.layout = &mtk_efuse_layout;
++              econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info;
+       nvmem = devm_nvmem_register(dev, &econfig);
+       return PTR_ERR_OR_ZERO(nvmem);
+diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h
+index ecd580ee84db9..9a015e4d428cc 100644
+--- a/include/linux/nvmem-provider.h
++++ b/include/linux/nvmem-provider.h
+@@ -83,6 +83,8 @@ struct nvmem_cell_info {
+  * @cells:    Optional array of pre-defined NVMEM cells.
+  * @ncells:   Number of elements in cells.
+  * @add_legacy_fixed_of_cells:        Read fixed NVMEM cells from old OF syntax.
++ * @fixup_dt_cell_info: Will be called before a cell is added. Can be
++ *            used to modify the nvmem_cell_info.
+  * @keepout:  Optional array of keepout ranges (sorted ascending by start).
+  * @nkeepout: Number of elements in the keepout array.
+  * @type:     Type of the nvmem storage
+@@ -114,6 +116,8 @@ struct nvmem_config {
+       const struct nvmem_cell_info    *cells;
+       int                     ncells;
+       bool                    add_legacy_fixed_of_cells;
++      void (*fixup_dt_cell_info)(struct nvmem_device *nvmem,
++                                 struct nvmem_cell_info *cell);
+       const struct nvmem_keepout *keepout;
+       unsigned int            nkeepout;
+       enum nvmem_type         type;
+@@ -160,8 +164,6 @@ struct nvmem_cell_table {
+  * @of_match_table:   Open firmware match table.
+  * @add_cells:                Called to populate the layout using
+  *                    nvmem_add_one_cell().
+- * @fixup_cell_info:  Will be called before a cell is added. Can be
+- *                    used to modify the nvmem_cell_info.
+  * @owner:            Pointer to struct module.
+  * @node:             List node.
+  *
+@@ -174,9 +176,6 @@ struct nvmem_layout {
+       const char *name;
+       const struct of_device_id *of_match_table;
+       int (*add_cells)(struct device *dev, struct nvmem_device *nvmem);
+-      void (*fixup_cell_info)(struct nvmem_device *nvmem,
+-                              struct nvmem_layout *layout,
+-                              struct nvmem_cell_info *cell);
+       /* private */
+       struct module *owner;
+-- 
+2.39.5
+
diff --git a/queue-6.6/nvmem-simplify-the-add_cells-hook.patch b/queue-6.6/nvmem-simplify-the-add_cells-hook.patch
new file mode 100644 (file)
index 0000000..789bbdd
--- /dev/null
@@ -0,0 +1,96 @@
+From 273420e0ab0ef38134f4d41451f8f1b837164be3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Dec 2023 11:15:30 +0000
+Subject: nvmem: Simplify the ->add_cells() hook
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+[ Upstream commit 1b7c298a4ecbc28cc6ee94005734bff55eb83d22 ]
+
+The layout entry is not used and will anyway be made useless by the new
+layout bus infrastructure coming next, so drop it. While at it, clarify
+the kdoc entry.
+
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20231215111536.316972-5-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 391b06ecb63e ("nvmem: imx-ocotp-ele: fix MAC address byte order")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvmem/core.c             | 2 +-
+ drivers/nvmem/layouts/onie-tlv.c | 3 +--
+ drivers/nvmem/layouts/sl28vpd.c  | 3 +--
+ include/linux/nvmem-provider.h   | 8 +++-----
+ 4 files changed, 6 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
+index ec35886e921a8..ed8a1cba361e2 100644
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -815,7 +815,7 @@ static int nvmem_add_cells_from_layout(struct nvmem_device *nvmem)
+       int ret;
+       if (layout && layout->add_cells) {
+-              ret = layout->add_cells(&nvmem->dev, nvmem, layout);
++              ret = layout->add_cells(&nvmem->dev, nvmem);
+               if (ret)
+                       return ret;
+       }
+diff --git a/drivers/nvmem/layouts/onie-tlv.c b/drivers/nvmem/layouts/onie-tlv.c
+index 59fc87ccfcffe..defd42d4375cc 100644
+--- a/drivers/nvmem/layouts/onie-tlv.c
++++ b/drivers/nvmem/layouts/onie-tlv.c
+@@ -182,8 +182,7 @@ static bool onie_tlv_crc_is_valid(struct device *dev, size_t table_len, u8 *tabl
+       return true;
+ }
+-static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem,
+-                              struct nvmem_layout *layout)
++static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem)
+ {
+       struct onie_tlv_hdr hdr;
+       size_t table_len, data_len, hdr_len;
+diff --git a/drivers/nvmem/layouts/sl28vpd.c b/drivers/nvmem/layouts/sl28vpd.c
+index 05671371f6316..26c7cf21b5233 100644
+--- a/drivers/nvmem/layouts/sl28vpd.c
++++ b/drivers/nvmem/layouts/sl28vpd.c
+@@ -80,8 +80,7 @@ static int sl28vpd_v1_check_crc(struct device *dev, struct nvmem_device *nvmem)
+       return 0;
+ }
+-static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem,
+-                           struct nvmem_layout *layout)
++static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem)
+ {
+       const struct nvmem_cell_info *pinfo;
+       struct nvmem_cell_info info = {0};
+diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h
+index 1b81adebdb8be..ecd580ee84db9 100644
+--- a/include/linux/nvmem-provider.h
++++ b/include/linux/nvmem-provider.h
+@@ -158,9 +158,8 @@ struct nvmem_cell_table {
+  *
+  * @name:             Layout name.
+  * @of_match_table:   Open firmware match table.
+- * @add_cells:                Will be called if a nvmem device is found which
+- *                    has this layout. The function will add layout
+- *                    specific cells with nvmem_add_one_cell().
++ * @add_cells:                Called to populate the layout using
++ *                    nvmem_add_one_cell().
+  * @fixup_cell_info:  Will be called before a cell is added. Can be
+  *                    used to modify the nvmem_cell_info.
+  * @owner:            Pointer to struct module.
+@@ -174,8 +173,7 @@ struct nvmem_cell_table {
+ struct nvmem_layout {
+       const char *name;
+       const struct of_device_id *of_match_table;
+-      int (*add_cells)(struct device *dev, struct nvmem_device *nvmem,
+-                       struct nvmem_layout *layout);
++      int (*add_cells)(struct device *dev, struct nvmem_device *nvmem);
+       void (*fixup_cell_info)(struct nvmem_device *nvmem,
+                               struct nvmem_layout *layout,
+                               struct nvmem_cell_info *cell);
+-- 
+2.39.5
+
diff --git a/queue-6.6/powerpc-64s-mm-move-__real_pte-stubs-into-hash-4k.h.patch b/queue-6.6/powerpc-64s-mm-move-__real_pte-stubs-into-hash-4k.h.patch
new file mode 100644 (file)
index 0000000..3b4c5c5
--- /dev/null
@@ -0,0 +1,92 @@
+From dbcf5c99dc5c42daeaad35fa81f635746c9d5513 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Aug 2024 18:07:29 +1000
+Subject: powerpc/64s/mm: Move __real_pte stubs into hash-4k.h
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit 8ae4f16f7d7b59cca55aeca6db7c9636ffe7fbaa ]
+
+The stub versions of __real_pte() etc are only used with HPT & 4K pages,
+so move them into the hash-4k.h header.
+
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20240821080729.872034-1-mpe@ellerman.id.au
+Stable-dep-of: 61bcc752d1b8 ("powerpc/64s: Rewrite __real_pte() and __rpte_to_hidx() as static inline")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/book3s/64/hash-4k.h | 20 +++++++++++++++
+ arch/powerpc/include/asm/book3s/64/pgtable.h | 26 --------------------
+ 2 files changed, 20 insertions(+), 26 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h
+index 6472b08fa1b0c..57ebbacf1709c 100644
+--- a/arch/powerpc/include/asm/book3s/64/hash-4k.h
++++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h
+@@ -89,6 +89,26 @@ static inline int hash__hugepd_ok(hugepd_t hpd)
+ }
+ #endif
++/*
++ * With 4K page size the real_pte machinery is all nops.
++ */
++#define __real_pte(e, p, o)           ((real_pte_t){(e)})
++#define __rpte_to_pte(r)      ((r).pte)
++#define __rpte_to_hidx(r,index)       (pte_val(__rpte_to_pte(r)) >> H_PAGE_F_GIX_SHIFT)
++
++#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift)       \
++      do {                                                             \
++              index = 0;                                               \
++              shift = mmu_psize_defs[psize].shift;                     \
++
++#define pte_iterate_hashed_end() } while(0)
++
++/*
++ * We expect this to be called only for user addresses or kernel virtual
++ * addresses other than the linear mapping.
++ */
++#define pte_pagesize_index(mm, addr, pte)     MMU_PAGE_4K
++
+ /*
+  * 4K PTE format is different from 64K PTE format. Saving the hash_slot is just
+  * a matter of returning the PTE bits that need to be modified. On 64K PTE,
+diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
+index 5c497c862d757..8a6e6b6daa906 100644
+--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
++++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
+@@ -319,32 +319,6 @@ extern unsigned long pci_io_base;
+ #ifndef __ASSEMBLY__
+-/*
+- * This is the default implementation of various PTE accessors, it's
+- * used in all cases except Book3S with 64K pages where we have a
+- * concept of sub-pages
+- */
+-#ifndef __real_pte
+-
+-#define __real_pte(e, p, o)           ((real_pte_t){(e)})
+-#define __rpte_to_pte(r)      ((r).pte)
+-#define __rpte_to_hidx(r,index)       (pte_val(__rpte_to_pte(r)) >> H_PAGE_F_GIX_SHIFT)
+-
+-#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift)       \
+-      do {                                                             \
+-              index = 0;                                               \
+-              shift = mmu_psize_defs[psize].shift;                     \
+-
+-#define pte_iterate_hashed_end() } while(0)
+-
+-/*
+- * We expect this to be called only for user addresses or kernel virtual
+- * addresses other than the linear mapping.
+- */
+-#define pte_pagesize_index(mm, addr, pte)     MMU_PAGE_4K
+-
+-#endif /* __real_pte */
+-
+ static inline unsigned long pte_update(struct mm_struct *mm, unsigned long addr,
+                                      pte_t *ptep, unsigned long clr,
+                                      unsigned long set, int huge)
+-- 
+2.39.5
+
diff --git a/queue-6.6/powerpc-64s-rewrite-__real_pte-and-__rpte_to_hidx-as.patch b/queue-6.6/powerpc-64s-rewrite-__real_pte-and-__rpte_to_hidx-as.patch
new file mode 100644 (file)
index 0000000..073f1d5
--- /dev/null
@@ -0,0 +1,64 @@
+From b1b68eb31f40ec076e383b942af5b83e901ddbee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jan 2025 19:24:46 +0100
+Subject: powerpc/64s: Rewrite __real_pte() and __rpte_to_hidx() as static
+ inline
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 61bcc752d1b81fde3cae454ff20c1d3c359df500 ]
+
+Rewrite __real_pte() and __rpte_to_hidx() as static inline in order to
+avoid following warnings/errors when building with 4k page size:
+
+         CC      arch/powerpc/mm/book3s64/hash_tlb.o
+       arch/powerpc/mm/book3s64/hash_tlb.c: In function 'hpte_need_flush':
+       arch/powerpc/mm/book3s64/hash_tlb.c:49:16: error: variable 'offset' set but not used [-Werror=unused-but-set-variable]
+          49 |         int i, offset;
+             |                ^~~~~~
+
+         CC      arch/powerpc/mm/book3s64/hash_native.o
+       arch/powerpc/mm/book3s64/hash_native.c: In function 'native_flush_hash_range':
+       arch/powerpc/mm/book3s64/hash_native.c:782:29: error: variable 'index' set but not used [-Werror=unused-but-set-variable]
+         782 |         unsigned long hash, index, hidx, shift, slot;
+             |                             ^~~~~
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202501081741.AYFwybsq-lkp@intel.com/
+Fixes: ff31e105464d ("powerpc/mm/hash64: Store the slot information at the right offset for hugetlb")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/e0d340a5b7bd478ecbf245d826e6ab2778b74e06.1736706263.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/book3s/64/hash-4k.h | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h
+index 57ebbacf1709c..2a2649e0f91df 100644
+--- a/arch/powerpc/include/asm/book3s/64/hash-4k.h
++++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h
+@@ -92,9 +92,17 @@ static inline int hash__hugepd_ok(hugepd_t hpd)
+ /*
+  * With 4K page size the real_pte machinery is all nops.
+  */
+-#define __real_pte(e, p, o)           ((real_pte_t){(e)})
++static inline real_pte_t __real_pte(pte_t pte, pte_t *ptep, int offset)
++{
++      return (real_pte_t){pte};
++}
++
+ #define __rpte_to_pte(r)      ((r).pte)
+-#define __rpte_to_hidx(r,index)       (pte_val(__rpte_to_pte(r)) >> H_PAGE_F_GIX_SHIFT)
++
++static inline unsigned long __rpte_to_hidx(real_pte_t rpte, unsigned long index)
++{
++      return pte_val(__rpte_to_pte(rpte)) >> H_PAGE_F_GIX_SHIFT;
++}
+ #define pte_iterate_hashed_subpages(rpte, psize, va, index, shift)       \
+       do {                                                             \
+-- 
+2.39.5
+
diff --git a/queue-6.6/powerpc-code-patching-fix-kasan-hit-by-not-flagging-.patch b/queue-6.6/powerpc-code-patching-fix-kasan-hit-by-not-flagging-.patch
new file mode 100644 (file)
index 0000000..fe97ac1
--- /dev/null
@@ -0,0 +1,112 @@
+From ffdbe671157768b5b690772f89f2cf54045aa0a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Feb 2025 07:46:28 +0100
+Subject: powerpc/code-patching: Fix KASAN hit by not flagging text patching
+ area as VM_ALLOC
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit d262a192d38e527faa5984629aabda2e0d1c4f54 ]
+
+Erhard reported the following KASAN hit while booting his PowerMac G4
+with a KASAN-enabled kernel 6.13-rc6:
+
+  BUG: KASAN: vmalloc-out-of-bounds in copy_to_kernel_nofault+0xd8/0x1c8
+  Write of size 8 at addr f1000000 by task chronyd/1293
+
+  CPU: 0 UID: 123 PID: 1293 Comm: chronyd Tainted: G        W          6.13.0-rc6-PMacG4 #2
+  Tainted: [W]=WARN
+  Hardware name: PowerMac3,6 7455 0x80010303 PowerMac
+  Call Trace:
+  [c2437590] [c1631a84] dump_stack_lvl+0x70/0x8c (unreliable)
+  [c24375b0] [c0504998] print_report+0xdc/0x504
+  [c2437610] [c050475c] kasan_report+0xf8/0x108
+  [c2437690] [c0505a3c] kasan_check_range+0x24/0x18c
+  [c24376a0] [c03fb5e4] copy_to_kernel_nofault+0xd8/0x1c8
+  [c24376c0] [c004c014] patch_instructions+0x15c/0x16c
+  [c2437710] [c00731a8] bpf_arch_text_copy+0x60/0x7c
+  [c2437730] [c0281168] bpf_jit_binary_pack_finalize+0x50/0xac
+  [c2437750] [c0073cf4] bpf_int_jit_compile+0xb30/0xdec
+  [c2437880] [c0280394] bpf_prog_select_runtime+0x15c/0x478
+  [c24378d0] [c1263428] bpf_prepare_filter+0xbf8/0xc14
+  [c2437990] [c12677ec] bpf_prog_create_from_user+0x258/0x2b4
+  [c24379d0] [c027111c] do_seccomp+0x3dc/0x1890
+  [c2437ac0] [c001d8e0] system_call_exception+0x2dc/0x420
+  [c2437f30] [c00281ac] ret_from_syscall+0x0/0x2c
+  --- interrupt: c00 at 0x5a1274
+  NIP:  005a1274 LR: 006a3b3c CTR: 005296c8
+  REGS: c2437f40 TRAP: 0c00   Tainted: G        W           (6.13.0-rc6-PMacG4)
+  MSR:  0200f932 <VEC,EE,PR,FP,ME,IR,DR,RI>  CR: 24004422  XER: 00000000
+
+  GPR00: 00000166 af8f3fa0 a7ee3540 00000001 00000000 013b6500 005a5858 0200f932
+  GPR08: 00000000 00001fe9 013d5fc8 005296c8 2822244c 00b2fcd8 00000000 af8f4b57
+  GPR16: 00000000 00000001 00000000 00000000 00000000 00000001 00000000 00000002
+  GPR24: 00afdbb0 00000000 00000000 00000000 006e0004 013ce060 006e7c1c 00000001
+  NIP [005a1274] 0x5a1274
+  LR [006a3b3c] 0x6a3b3c
+  --- interrupt: c00
+
+  The buggy address belongs to the virtual mapping at
+   [f1000000, f1002000) created by:
+   text_area_cpu_up+0x20/0x190
+
+  The buggy address belongs to the physical page:
+  page: refcount:1 mapcount:0 mapping:00000000 index:0x0 pfn:0x76e30
+  flags: 0x80000000(zone=2)
+  raw: 80000000 00000000 00000122 00000000 00000000 00000000 ffffffff 00000001
+  raw: 00000000
+  page dumped because: kasan: bad access detected
+
+  Memory state around the buggy address:
+   f0ffff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+   f0ffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+  >f1000000: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
+             ^
+   f1000080: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
+   f1000100: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
+  ==================================================================
+
+f8 corresponds to KASAN_VMALLOC_INVALID which means the area is not
+initialised hence not supposed to be used yet.
+
+Powerpc text patching infrastructure allocates a virtual memory area
+using get_vm_area() and flags it as VM_ALLOC. But that flag is meant
+to be used for vmalloc() and vmalloc() allocated memory is not
+supposed to be used before a call to __vmalloc_node_range() which is
+never called for that area.
+
+That went undetected until commit e4137f08816b ("mm, kasan, kmsan:
+instrument copy_from/to_kernel_nofault")
+
+The area allocated by text_area_cpu_up() is not vmalloc memory, it is
+mapped directly on demand when needed by map_kernel_page(). There is
+no VM flag corresponding to such usage, so just pass no flag. That way
+the area will be unpoisonned and usable immediately.
+
+Reported-by: Erhard Furtner <erhard_f@mailbox.org>
+Closes: https://lore.kernel.org/all/20250112135832.57c92322@yea/
+Fixes: 37bc3e5fd764 ("powerpc/lib/code-patching: Use alternate map for patch_instruction()")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/06621423da339b374f48c0886e3a5db18e896be8.1739342693.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/lib/code-patching.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
+index b00112d7ad467..4426a77c8f063 100644
+--- a/arch/powerpc/lib/code-patching.c
++++ b/arch/powerpc/lib/code-patching.c
+@@ -105,7 +105,7 @@ static int text_area_cpu_up(unsigned int cpu)
+       unsigned long addr;
+       int err;
+-      area = get_vm_area(PAGE_SIZE, VM_ALLOC);
++      area = get_vm_area(PAGE_SIZE, 0);
+       if (!area) {
+               WARN_ONCE(1, "Failed to create text area for cpu %d\n",
+                       cpu);
+-- 
+2.39.5
+
diff --git a/queue-6.6/s390-ism-add-release-function-for-struct-device.patch b/queue-6.6/s390-ism-add-release-function-for-struct-device.patch
new file mode 100644 (file)
index 0000000..06fcfb4
--- /dev/null
@@ -0,0 +1,81 @@
+From 9826d8b5681ea6eed03dab09277bb4d158ff1657 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Feb 2025 13:01:37 +0100
+Subject: s390/ism: add release function for struct device
+
+From: Julian Ruess <julianr@linux.ibm.com>
+
+[ Upstream commit 915e34d5ad35a6a9e56113f852ade4a730fb88f0 ]
+
+According to device_release() in /drivers/base/core.c,
+a device without a release function is a broken device
+and must be fixed.
+
+The current code directly frees the device after calling device_add()
+without waiting for other kernel parts to release their references.
+Thus, a reference could still be held to a struct device,
+e.g., by sysfs, leading to potential use-after-free
+issues if a proper release function is not set.
+
+Fixes: 8c81ba20349d ("net/smc: De-tangle ism and smc device initialization")
+Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
+Reviewed-by: Wenjia Zhang <wenjia@linux.ibm.com>
+Signed-off-by: Julian Ruess <julianr@linux.ibm.com>
+Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250214120137.563409-1-wintera@linux.ibm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/net/ism_drv.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c
+index f6a0626a6b3ec..af0d90beba638 100644
+--- a/drivers/s390/net/ism_drv.c
++++ b/drivers/s390/net/ism_drv.c
+@@ -611,6 +611,15 @@ static int ism_dev_init(struct ism_dev *ism)
+       return ret;
+ }
++static void ism_dev_release(struct device *dev)
++{
++      struct ism_dev *ism;
++
++      ism = container_of(dev, struct ism_dev, dev);
++
++      kfree(ism);
++}
++
+ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ {
+       struct ism_dev *ism;
+@@ -624,6 +633,7 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+       dev_set_drvdata(&pdev->dev, ism);
+       ism->pdev = pdev;
+       ism->dev.parent = &pdev->dev;
++      ism->dev.release = ism_dev_release;
+       device_initialize(&ism->dev);
+       dev_set_name(&ism->dev, dev_name(&pdev->dev));
+       ret = device_add(&ism->dev);
+@@ -660,7 +670,7 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+       device_del(&ism->dev);
+ err_dev:
+       dev_set_drvdata(&pdev->dev, NULL);
+-      kfree(ism);
++      put_device(&ism->dev);
+       return ret;
+ }
+@@ -706,7 +716,7 @@ static void ism_remove(struct pci_dev *pdev)
+       pci_disable_device(pdev);
+       device_del(&ism->dev);
+       dev_set_drvdata(&pdev->dev, NULL);
+-      kfree(ism);
++      put_device(&ism->dev);
+ }
+ static struct pci_driver ism_driver = {
+-- 
+2.39.5
+
diff --git a/queue-6.6/scsi-core-do-not-retry-i-os-during-depopulation.patch b/queue-6.6/scsi-core-do-not-retry-i-os-during-depopulation.patch
new file mode 100644 (file)
index 0000000..5631670
--- /dev/null
@@ -0,0 +1,60 @@
+From 2c343401e457db93757d4d8fa2faede8344026ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jan 2025 10:44:07 -0800
+Subject: scsi: core: Do not retry I/Os during depopulation
+
+From: Igor Pylypiv <ipylypiv@google.com>
+
+[ Upstream commit 9ff7c383b8ac0c482a1da7989f703406d78445c6 ]
+
+Fail I/Os instead of retry to prevent user space processes from being
+blocked on the I/O completion for several minutes.
+
+Retrying I/Os during "depopulation in progress" or "depopulation restore in
+progress" results in a continuous retry loop until the depopulation
+completes or until the I/O retry loop is aborted due to a timeout by the
+scsi_cmd_runtime_exceeced().
+
+Depopulation is slow and can take 24+ hours to complete on 20+ TB HDDs.
+Most I/Os in the depopulation retry loop end up taking several minutes
+before returning the failure to user space.
+
+Cc: stable@vger.kernel.org # 4.18.x: 2bbeb8d scsi: core: Handle depopulation and restoration in progress
+Cc: stable@vger.kernel.org # 4.18.x
+Fixes: e37c7d9a0341 ("scsi: core: sanitize++ in progress")
+Signed-off-by: Igor Pylypiv <ipylypiv@google.com>
+Link: https://lore.kernel.org/r/20250131184408.859579-1-ipylypiv@google.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_lib.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index 2f54e1a853099..f026377f1cf1c 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -774,13 +774,18 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result)
+                               case 0x1a: /* start stop unit in progress */
+                               case 0x1b: /* sanitize in progress */
+                               case 0x1d: /* configuration in progress */
+-                              case 0x24: /* depopulation in progress */
+-                              case 0x25: /* depopulation restore in progress */
+                                       action = ACTION_DELAYED_RETRY;
+                                       break;
+                               case 0x0a: /* ALUA state transition */
+                                       action = ACTION_DELAYED_REPREP;
+                                       break;
++                              /*
++                               * Depopulation might take many hours,
++                               * thus it is not worthwhile to retry.
++                               */
++                              case 0x24: /* depopulation in progress */
++                              case 0x25: /* depopulation restore in progress */
++                                      fallthrough;
+                               default:
+                                       action = ACTION_FAIL;
+                                       break;
+-- 
+2.39.5
+
diff --git a/queue-6.6/scsi-core-handle-depopulation-and-restoration-in-pro.patch b/queue-6.6/scsi-core-handle-depopulation-and-restoration-in-pro.patch
new file mode 100644 (file)
index 0000000..b82cfbb
--- /dev/null
@@ -0,0 +1,63 @@
+From 00f7976414d36f3e642accd439f39ea6e44b0bab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 Oct 2023 01:06:50 -0400
+Subject: scsi: core: Handle depopulation and restoration in progress
+
+From: Douglas Gilbert <dgilbert@interlog.com>
+
+[ Upstream commit 2bbeb8d12404cf0603f513fc33269ef9abfbb396 ]
+
+The default handling of the NOT READY sense key is to wait for the device
+to become ready. The "wait" is assumed to be relatively short. However
+there is a sub-class of NOT READY that have the "... in progress" phrase in
+their additional sense code and these can take much longer.  Following on
+from commit 505aa4b6a883 ("scsi: sd: Defer spinning up drive while SANITIZE
+is in progress") we now have element depopulation and restoration that can
+take a long time.  For example, over 24 hours for a 20 TB, 7200 rpm hard
+disk to depopulate 1 of its 20 elements.
+
+Add handling of ASC/ASCQ: 0x4,0x24 (depopulation in progress)
+and ASC/ASCQ: 0x4,0x25 (depopulation restoration in progress)
+to sd.c . The scsi_lib.c has incomplete handling of these
+two messages, so complete it.
+
+Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
+Link: https://lore.kernel.org/r/20231015050650.131145-1-dgilbert@interlog.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Stable-dep-of: 9ff7c383b8ac ("scsi: core: Do not retry I/Os during depopulation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_lib.c | 1 +
+ drivers/scsi/sd.c       | 4 ++++
+ 2 files changed, 5 insertions(+)
+
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index 97def2619ecf2..2f54e1a853099 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -775,6 +775,7 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result)
+                               case 0x1b: /* sanitize in progress */
+                               case 0x1d: /* configuration in progress */
+                               case 0x24: /* depopulation in progress */
++                              case 0x25: /* depopulation restore in progress */
+                                       action = ACTION_DELAYED_RETRY;
+                                       break;
+                               case 0x0a: /* ALUA state transition */
+diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
+index 2c627deedc1fa..fe694fec16b51 100644
+--- a/drivers/scsi/sd.c
++++ b/drivers/scsi/sd.c
+@@ -2309,6 +2309,10 @@ sd_spinup_disk(struct scsi_disk *sdkp)
+                               break;  /* unavailable */
+                       if (sshdr.asc == 4 && sshdr.ascq == 0x1b)
+                               break;  /* sanitize in progress */
++                      if (sshdr.asc == 4 && sshdr.ascq == 0x24)
++                              break;  /* depopulation in progress */
++                      if (sshdr.asc == 4 && sshdr.ascq == 0x25)
++                              break;  /* depopulation restoration in progress */
+                       /*
+                        * Issue command to spin up drive when not ready
+                        */
+-- 
+2.39.5
+
index 414dd126c579ff5ca26435009f103fca16de7108..5d7f50c6da3227987719d473941023f5d04351cd 100644 (file)
@@ -23,3 +23,69 @@ xfs-update-the-pag-for-the-last-ag-at-recovery-time.patch
 xfs-reduce-unnecessary-searches-when-searching-for-the-best-extents.patch
 xfs-streamline-xfs_filestream_pick_ag.patch
 xfs-check-for-delayed-allocations-before-setting-extsize.patch
+xfs-report-realtime-block-quota-limits-on-realtime-d.patch
+xfs-don-t-over-report-free-space-or-inodes-in-statvf.patch
+md-use-separate-work_struct-for-md_start_sync.patch
+md-factor-out-a-helper-from-mddev_put.patch
+md-simplify-md_seq_ops.patch
+md-md-bitmap-replace-md_bitmap_status-with-a-new-hel.patch
+md-md-cluster-fix-spares-warnings-for-__le64.patch
+md-md-bitmap-add-sync_size-into-struct-md_bitmap_sta.patch
+md-md-bitmap-synchronize-bitmap_get_stats-with-bitma.patch
+mm-update-mark_victim-tracepoints-fields.patch
+memcg-fix-soft-lockup-in-the-oom-process.patch
+cpufreq-dt-platdev-add-missing-module_description-ma.patch
+cpufreq-fix-using-cpufreq-dt-as-module.patch
+bluetooth-qca-support-downloading-board-id-specific-.patch
+bluetooth-qca-update-firmware-name-to-support-board-.patch
+bluetooth-qca-fix-poor-rf-performance-for-wcn6855.patch
+input-serio-define-serio_pause_rx-guard-to-pause-and.patch
+input-synaptics-fix-crash-when-enabling-pass-through.patch
+asoc-renesas-rz-ssi-add-a-check-for-negative-sample_.patch
+firmware-qcom-scm-fix-missing-read-barrier-in-qcom_s.patch
+scsi-core-handle-depopulation-and-restoration-in-pro.patch
+scsi-core-do-not-retry-i-os-during-depopulation.patch
+arm64-dts-mediatek-mt8183-pumpkin-add-hdmi-support.patch
+arm64-dts-mediatek-mt8183-disable-dsi-display-output.patch
+arm64-dts-qcom-sm8450-add-missing-qcom-non-secure-do.patch
+arm64-dts-qcom-sm8450-fix-adsp-memory-base-and-lengt.patch
+arm64-dts-qcom-sm8550-add-dma-coherent-property.patch
+arm64-dts-qcom-sm8550-add-missing-qcom-non-secure-do.patch
+arm64-dts-qcom-sm8550-fix-adsp-memory-base-and-lengt.patch
+soc-mediatek-mtk-devapc-convert-to-platform-remove-c.patch
+soc-mediatek-mtk-devapc-fix-leaking-io-map-on-driver.patch
+media-uvcvideo-refactor-iterators.patch
+media-uvcvideo-only-save-async-fh-if-success.patch
+media-uvcvideo-remove-dangling-pointers.patch
+nvmem-create-a-header-for-internal-sharing.patch
+nvmem-simplify-the-add_cells-hook.patch
+nvmem-move-and-rename-fixup_cell_info.patch
+nvmem-imx-ocotp-ele-fix-mac-address-byte-order.patch
+usb-gadget-core-create-sysfs-link-between-udc-and-ga.patch
+usb-gadget-core-flush-gadget-workqueue-after-device-.patch
+usb-gadget-f_midi-f_midi_complete-to-call-queue_work.patch
+asoc-rockchip-i2s-tdm-fix-shift-config-for-snd_soc_d.patch
+powerpc-64s-mm-move-__real_pte-stubs-into-hash-4k.h.patch
+powerpc-64s-rewrite-__real_pte-and-__rpte_to_hidx-as.patch
+alsa-hda-realtek-fixup-alc225-depop-procedure.patch
+powerpc-code-patching-fix-kasan-hit-by-not-flagging-.patch
+geneve-fix-use-after-free-in-geneve_find_dev.patch
+alsa-hda-cirrus-correct-the-full-scale-volume-set-lo.patch
+net-sched-cls_api-fix-error-handling-causing-null-de.patch
+alsa-seq-drop-ump-events-when-no-ump-conversion-is-s.patch
+s390-ism-add-release-function-for-struct-device.patch
+ibmvnic-return-error-code-on-tx-scrq-flush-fail.patch
+ibmvnic-introduce-send-sub-crq-direct.patch
+ibmvnic-add-stat-for-tx-direct-vs-tx-batched.patch
+ibmvnic-don-t-reference-skb-after-sending-to-vios.patch
+sockmap-vsock-for-connectible-sockets-allow-only-con.patch
+vsock-bpf-warn-on-socket-without-transport.patch
+tcp-adjust-rcvq_space-after-updating-scaling-ratio.patch
+gtp-suppress-list-corruption-splat-in-gtp_net_exit_b.patch
+geneve-suppress-list-corruption-splat-in-geneve_dest.patch
+flow_dissector-fix-handling-of-mixed-port-and-port-r.patch
+flow_dissector-fix-port-range-key-handling-in-bpf-co.patch
+net-add-non-rcu-dev_getbyhwaddr-helper.patch
+arp-switch-to-dev_getbyhwaddr-in-arp_req_set_public.patch
+net-axienet-set-mac_managed_pm.patch
+tcp-drop-secpath-at-the-same-time-as-we-currently-dr.patch
diff --git a/queue-6.6/soc-mediatek-mtk-devapc-convert-to-platform-remove-c.patch b/queue-6.6/soc-mediatek-mtk-devapc-convert-to-platform-remove-c.patch
new file mode 100644 (file)
index 0000000..cf84810
--- /dev/null
@@ -0,0 +1,62 @@
+From cb934574784c95a716d1403d21a7e1833ab69a9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Sep 2023 11:55:05 +0200
+Subject: soc/mediatek: mtk-devapc: Convert to platform remove callback
+ returning void
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit a129ac3555c0dca6f04ae404dc0f0790656587fb ]
+
+The .remove() callback for a platform driver returns an int which makes
+many driver authors wrongly assume it's possible to do error handling by
+returning an error code. However the value returned is ignored (apart
+from emitting a warning) and this typically results in resource leaks.
+To improve here there is a quest to make the remove callback return
+void. In the first step of this quest all drivers are converted to
+.remove_new() which already returns void. Eventually after all drivers
+are converted, .remove_new() will be renamed to .remove().
+
+Trivially convert this driver from always returning zero in the remove
+callback to the void returning variant.
+
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20230925095532.1984344-15-u.kleine-koenig@pengutronix.de
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Stable-dep-of: c9c0036c1990 ("soc: mediatek: mtk-devapc: Fix leaking IO map on driver remove")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/mediatek/mtk-devapc.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c
+index 0dfc1da9471cb..eb8f92f585882 100644
+--- a/drivers/soc/mediatek/mtk-devapc.c
++++ b/drivers/soc/mediatek/mtk-devapc.c
+@@ -300,18 +300,16 @@ static int mtk_devapc_probe(struct platform_device *pdev)
+       return ret;
+ }
+-static int mtk_devapc_remove(struct platform_device *pdev)
++static void mtk_devapc_remove(struct platform_device *pdev)
+ {
+       struct mtk_devapc_context *ctx = platform_get_drvdata(pdev);
+       stop_devapc(ctx);
+-
+-      return 0;
+ }
+ static struct platform_driver mtk_devapc_driver = {
+       .probe = mtk_devapc_probe,
+-      .remove = mtk_devapc_remove,
++      .remove_new = mtk_devapc_remove,
+       .driver = {
+               .name = "mtk-devapc",
+               .of_match_table = mtk_devapc_dt_match,
+-- 
+2.39.5
+
diff --git a/queue-6.6/soc-mediatek-mtk-devapc-fix-leaking-io-map-on-driver.patch b/queue-6.6/soc-mediatek-mtk-devapc-fix-leaking-io-map-on-driver.patch
new file mode 100644 (file)
index 0000000..fa05a85
--- /dev/null
@@ -0,0 +1,36 @@
+From f818acea5248afef9fe9ff8ab02407dda77c1f9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Jan 2025 15:20:12 +0100
+Subject: soc: mediatek: mtk-devapc: Fix leaking IO map on driver remove
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit c9c0036c1990da8d2dd33563e327e05a775fcf10 ]
+
+Driver removal should fully clean up - unmap the memory.
+
+Fixes: 0890beb22618 ("soc: mediatek: add mt6779 devapc driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20250104142012.115974-2-krzysztof.kozlowski@linaro.org
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/mediatek/mtk-devapc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c
+index eb8f92f585882..d83a46334adbb 100644
+--- a/drivers/soc/mediatek/mtk-devapc.c
++++ b/drivers/soc/mediatek/mtk-devapc.c
+@@ -305,6 +305,7 @@ static void mtk_devapc_remove(struct platform_device *pdev)
+       struct mtk_devapc_context *ctx = platform_get_drvdata(pdev);
+       stop_devapc(ctx);
++      iounmap(ctx->infra_base);
+ }
+ static struct platform_driver mtk_devapc_driver = {
+-- 
+2.39.5
+
diff --git a/queue-6.6/sockmap-vsock-for-connectible-sockets-allow-only-con.patch b/queue-6.6/sockmap-vsock-for-connectible-sockets-allow-only-con.patch
new file mode 100644 (file)
index 0000000..b65154b
--- /dev/null
@@ -0,0 +1,65 @@
+From 3cb4906146fb44e7b1a0af27020795d9b5b8246f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Feb 2025 12:58:49 +0100
+Subject: sockmap, vsock: For connectible sockets allow only connected
+
+From: Michal Luczaj <mhal@rbox.co>
+
+[ Upstream commit 8fb5bb169d17cdd12c2dcc2e96830ed487d77a0f ]
+
+sockmap expects all vsocks to have a transport assigned, which is expressed
+in vsock_proto::psock_update_sk_prot(). However, there is an edge case
+where an unconnected (connectible) socket may lose its previously assigned
+transport. This is handled with a NULL check in the vsock/BPF recv path.
+
+Another design detail is that listening vsocks are not supposed to have any
+transport assigned at all. Which implies they are not supported by the
+sockmap. But this is complicated by the fact that a socket, before
+switching to TCP_LISTEN, may have had some transport assigned during a
+failed connect() attempt. Hence, we may end up with a listening vsock in a
+sockmap, which blows up quickly:
+
+KASAN: null-ptr-deref in range [0x0000000000000120-0x0000000000000127]
+CPU: 7 UID: 0 PID: 56 Comm: kworker/7:0 Not tainted 6.14.0-rc1+
+Workqueue: vsock-loopback vsock_loopback_work
+RIP: 0010:vsock_read_skb+0x4b/0x90
+Call Trace:
+ sk_psock_verdict_data_ready+0xa4/0x2e0
+ virtio_transport_recv_pkt+0x1ca8/0x2acc
+ vsock_loopback_work+0x27d/0x3f0
+ process_one_work+0x846/0x1420
+ worker_thread+0x5b3/0xf80
+ kthread+0x35a/0x700
+ ret_from_fork+0x2d/0x70
+ ret_from_fork_asm+0x1a/0x30
+
+For connectible sockets, instead of relying solely on the state of
+vsk->transport, tell sockmap to only allow those representing established
+connections. This aligns with the behaviour for AF_INET and AF_UNIX.
+
+Fixes: 634f1a7110b4 ("vsock: support sockmap")
+Signed-off-by: Michal Luczaj <mhal@rbox.co>
+Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock_map.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/core/sock_map.c b/net/core/sock_map.c
+index f37a26efdd8ab..dcc0f31a17a8d 100644
+--- a/net/core/sock_map.c
++++ b/net/core/sock_map.c
+@@ -538,6 +538,9 @@ static bool sock_map_sk_state_allowed(const struct sock *sk)
+               return (1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_LISTEN);
+       if (sk_is_stream_unix(sk))
+               return (1 << sk->sk_state) & TCPF_ESTABLISHED;
++      if (sk_is_vsock(sk) &&
++          (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET))
++              return (1 << sk->sk_state) & TCPF_ESTABLISHED;
+       return true;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.6/tcp-adjust-rcvq_space-after-updating-scaling-ratio.patch b/queue-6.6/tcp-adjust-rcvq_space-after-updating-scaling-ratio.patch
new file mode 100644 (file)
index 0000000..d95150e
--- /dev/null
@@ -0,0 +1,67 @@
+From 752fff80c76ea32af9555c5b2b24caedd8168971 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 15:29:05 -0800
+Subject: tcp: adjust rcvq_space after updating scaling ratio
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit f5da7c45188eea71394bf445655cae2df88a7788 ]
+
+Since commit under Fixes we set the window clamp in accordance
+to newly measured rcvbuf scaling_ratio. If the scaling_ratio
+decreased significantly we may put ourselves in a situation
+where windows become smaller than rcvq_space, preventing
+tcp_rcv_space_adjust() from increasing rcvbuf.
+
+The significant decrease of scaling_ratio is far more likely
+since commit 697a6c8cec03 ("tcp: increase the default TCP scaling ratio"),
+which increased the "default" scaling ratio from ~30% to 50%.
+
+Hitting the bad condition depends a lot on TCP tuning, and
+drivers at play. One of Meta's workloads hits it reliably
+under following conditions:
+ - default rcvbuf of 125k
+ - sender MTU 1500, receiver MTU 5000
+ - driver settles on scaling_ratio of 78 for the config above.
+Initial rcvq_space gets calculated as TCP_INIT_CWND * tp->advmss
+(10 * 5k = 50k). Once we find out the true scaling ratio and
+MSS we clamp the windows to 38k. Triggering the condition also
+depends on the message sequence of this workload. I can't repro
+the problem with simple iperf or TCP_RR-style tests.
+
+Fixes: a2cbb1603943 ("tcp: Update window clamping condition")
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Neal Cardwell <ncardwell@google.com>
+Link: https://patch.msgid.link/20250217232905.3162187-1-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_input.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index f6a213bae5ccc..6074b4c3ab940 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -248,9 +248,15 @@ static void tcp_measure_rcv_mss(struct sock *sk, const struct sk_buff *skb)
+                       do_div(val, skb->truesize);
+                       tcp_sk(sk)->scaling_ratio = val ? val : 1;
+-                      if (old_ratio != tcp_sk(sk)->scaling_ratio)
+-                              WRITE_ONCE(tcp_sk(sk)->window_clamp,
+-                                         tcp_win_from_space(sk, sk->sk_rcvbuf));
++                      if (old_ratio != tcp_sk(sk)->scaling_ratio) {
++                              struct tcp_sock *tp = tcp_sk(sk);
++
++                              val = tcp_win_from_space(sk, sk->sk_rcvbuf);
++                              tcp_set_window_clamp(sk, val);
++
++                              if (tp->window_clamp < tp->rcvq_space.space)
++                                      tp->rcvq_space.space = tp->window_clamp;
++                      }
+               }
+               icsk->icsk_ack.rcv_mss = min_t(unsigned int, len,
+                                              tcp_sk(sk)->advmss);
+-- 
+2.39.5
+
diff --git a/queue-6.6/tcp-drop-secpath-at-the-same-time-as-we-currently-dr.patch b/queue-6.6/tcp-drop-secpath-at-the-same-time-as-we-currently-dr.patch
new file mode 100644 (file)
index 0000000..eba9bb8
--- /dev/null
@@ -0,0 +1,158 @@
+From f50795547ecb9b7becca71013e32edf2c729bdca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 11:23:35 +0100
+Subject: tcp: drop secpath at the same time as we currently drop dst
+
+From: Sabrina Dubroca <sd@queasysnail.net>
+
+[ Upstream commit 9b6412e6979f6f9e0632075f8f008937b5cd4efd ]
+
+Xiumei reported hitting the WARN in xfrm6_tunnel_net_exit while
+running tests that boil down to:
+ - create a pair of netns
+ - run a basic TCP test over ipcomp6
+ - delete the pair of netns
+
+The xfrm_state found on spi_byaddr was not deleted at the time we
+delete the netns, because we still have a reference on it. This
+lingering reference comes from a secpath (which holds a ref on the
+xfrm_state), which is still attached to an skb. This skb is not
+leaked, it ends up on sk_receive_queue and then gets defer-free'd by
+skb_attempt_defer_free.
+
+The problem happens when we defer freeing an skb (push it on one CPU's
+defer_list), and don't flush that list before the netns is deleted. In
+that case, we still have a reference on the xfrm_state that we don't
+expect at this point.
+
+We already drop the skb's dst in the TCP receive path when it's no
+longer needed, so let's also drop the secpath. At this point,
+tcp_filter has already called into the LSM hooks that may require the
+secpath, so it should not be needed anymore. However, in some of those
+places, the MPTCP extension has just been attached to the skb, so we
+cannot simply drop all extensions.
+
+Fixes: 68822bdf76f1 ("net: generalize skb freeing deferral to per-cpu lists")
+Reported-by: Xiumei Mu <xmu@redhat.com>
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/5055ba8f8f72bdcb602faa299faca73c280b7735.1739743613.git.sd@queasysnail.net
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/tcp.h       | 14 ++++++++++++++
+ net/ipv4/tcp_fastopen.c |  4 ++--
+ net/ipv4/tcp_input.c    |  8 ++++----
+ net/ipv4/tcp_ipv4.c     |  2 +-
+ 4 files changed, 21 insertions(+), 7 deletions(-)
+
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index b3917af309e0f..78c755414fa87 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -40,6 +40,7 @@
+ #include <net/inet_ecn.h>
+ #include <net/dst.h>
+ #include <net/mptcp.h>
++#include <net/xfrm.h>
+ #include <linux/seq_file.h>
+ #include <linux/memcontrol.h>
+@@ -630,6 +631,19 @@ void tcp_fin(struct sock *sk);
+ void tcp_check_space(struct sock *sk);
+ void tcp_sack_compress_send_ack(struct sock *sk);
++static inline void tcp_cleanup_skb(struct sk_buff *skb)
++{
++      skb_dst_drop(skb);
++      secpath_reset(skb);
++}
++
++static inline void tcp_add_receive_queue(struct sock *sk, struct sk_buff *skb)
++{
++      DEBUG_NET_WARN_ON_ONCE(skb_dst(skb));
++      DEBUG_NET_WARN_ON_ONCE(secpath_exists(skb));
++      __skb_queue_tail(&sk->sk_receive_queue, skb);
++}
++
+ /* tcp_timer.c */
+ void tcp_init_xmit_timers(struct sock *);
+ static inline void tcp_clear_xmit_timers(struct sock *sk)
+diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
+index 0f523cbfe329e..32b28fc21b63c 100644
+--- a/net/ipv4/tcp_fastopen.c
++++ b/net/ipv4/tcp_fastopen.c
+@@ -178,7 +178,7 @@ void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb)
+       if (!skb)
+               return;
+-      skb_dst_drop(skb);
++      tcp_cleanup_skb(skb);
+       /* segs_in has been initialized to 1 in tcp_create_openreq_child().
+        * Hence, reset segs_in to 0 before calling tcp_segs_in()
+        * to avoid double counting.  Also, tcp_segs_in() expects
+@@ -195,7 +195,7 @@ void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb)
+       TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_SYN;
+       tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
+-      __skb_queue_tail(&sk->sk_receive_queue, skb);
++      tcp_add_receive_queue(sk, skb);
+       tp->syn_data_acked = 1;
+       /* u64_stats_update_begin(&tp->syncp) not needed here,
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index 6074b4c3ab940..10d38ec0ff5ac 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -4874,7 +4874,7 @@ static void tcp_ofo_queue(struct sock *sk)
+               tcp_rcv_nxt_update(tp, TCP_SKB_CB(skb)->end_seq);
+               fin = TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN;
+               if (!eaten)
+-                      __skb_queue_tail(&sk->sk_receive_queue, skb);
++                      tcp_add_receive_queue(sk, skb);
+               else
+                       kfree_skb_partial(skb, fragstolen);
+@@ -5065,7 +5065,7 @@ static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb,
+                                 skb, fragstolen)) ? 1 : 0;
+       tcp_rcv_nxt_update(tcp_sk(sk), TCP_SKB_CB(skb)->end_seq);
+       if (!eaten) {
+-              __skb_queue_tail(&sk->sk_receive_queue, skb);
++              tcp_add_receive_queue(sk, skb);
+               skb_set_owner_r(skb, sk);
+       }
+       return eaten;
+@@ -5148,7 +5148,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
+               __kfree_skb(skb);
+               return;
+       }
+-      skb_dst_drop(skb);
++      tcp_cleanup_skb(skb);
+       __skb_pull(skb, tcp_hdr(skb)->doff * 4);
+       reason = SKB_DROP_REASON_NOT_SPECIFIED;
+@@ -6098,7 +6098,7 @@ void tcp_rcv_established(struct sock *sk, struct sk_buff *skb)
+                       NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPHPHITS);
+                       /* Bulk data transfer: receiver */
+-                      skb_dst_drop(skb);
++                      tcp_cleanup_skb(skb);
+                       __skb_pull(skb, tcp_header_len);
+                       eaten = tcp_queue_rcv(sk, skb, &fragstolen);
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index 705320f160ac8..2f49a504c9d3e 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -1842,7 +1842,7 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb,
+        */
+       skb_condense(skb);
+-      skb_dst_drop(skb);
++      tcp_cleanup_skb(skb);
+       if (unlikely(tcp_checksum_complete(skb))) {
+               bh_unlock_sock(sk);
+-- 
+2.39.5
+
diff --git a/queue-6.6/usb-gadget-core-create-sysfs-link-between-udc-and-ga.patch b/queue-6.6/usb-gadget-core-create-sysfs-link-between-udc-and-ga.patch
new file mode 100644 (file)
index 0000000..a9d16fe
--- /dev/null
@@ -0,0 +1,60 @@
+From 29dff33d6c0d595ebf400e58c6b912b36a4855b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 03:09:22 +0000
+Subject: USB: gadget: core: create sysfs link between udc and gadget
+
+From: Roy Luo <royluo@google.com>
+
+[ Upstream commit 0ef40f399aa2be8c04aee9b7430705612c104ce5 ]
+
+udc device and gadget device are tightly coupled, yet there's no good
+way to corelate the two. Add a sysfs link in udc that points to the
+corresponding gadget device.
+An example use case: userspace configures a f_midi configfs driver and
+bind the udc device, then it tries to locate the corresponding midi
+device, which is a child device of the gadget device. The gadget device
+that's associated to the udc device has to be identified in order to
+index the midi device. Having a sysfs link would make things much
+easier.
+
+Signed-off-by: Roy Luo <royluo@google.com>
+Link: https://lore.kernel.org/r/20240307030922.3573161-1-royluo@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 399a45e5237c ("usb: gadget: core: flush gadget workqueue after device removal")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/core.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
+index 33979f61dc4dd..1d58adc597a7e 100644
+--- a/drivers/usb/gadget/udc/core.c
++++ b/drivers/usb/gadget/udc/core.c
+@@ -1419,8 +1419,16 @@ int usb_add_gadget(struct usb_gadget *gadget)
+       if (ret)
+               goto err_free_id;
++      ret = sysfs_create_link(&udc->dev.kobj,
++                              &gadget->dev.kobj, "gadget");
++      if (ret)
++              goto err_del_gadget;
++
+       return 0;
++ err_del_gadget:
++      device_del(&gadget->dev);
++
+  err_free_id:
+       ida_free(&gadget_id_numbers, gadget->id_number);
+@@ -1529,6 +1537,7 @@ void usb_del_gadget(struct usb_gadget *gadget)
+       mutex_unlock(&udc_lock);
+       kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE);
++      sysfs_remove_link(&udc->dev.kobj, "gadget");
+       flush_work(&gadget->work);
+       device_del(&gadget->dev);
+       ida_free(&gadget_id_numbers, gadget->id_number);
+-- 
+2.39.5
+
diff --git a/queue-6.6/usb-gadget-core-flush-gadget-workqueue-after-device-.patch b/queue-6.6/usb-gadget-core-flush-gadget-workqueue-after-device-.patch
new file mode 100644 (file)
index 0000000..5711ce3
--- /dev/null
@@ -0,0 +1,52 @@
+From 21c317101fd7537c2d24930480ae0f575af4627d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Feb 2025 23:36:42 +0000
+Subject: usb: gadget: core: flush gadget workqueue after device removal
+
+From: Roy Luo <royluo@google.com>
+
+[ Upstream commit 399a45e5237ca14037120b1b895bd38a3b4492ea ]
+
+device_del() can lead to new work being scheduled in gadget->work
+workqueue. This is observed, for example, with the dwc3 driver with the
+following call stack:
+  device_del()
+    gadget_unbind_driver()
+      usb_gadget_disconnect_locked()
+        dwc3_gadget_pullup()
+         dwc3_gadget_soft_disconnect()
+           usb_gadget_set_state()
+             schedule_work(&gadget->work)
+
+Move flush_work() after device_del() to ensure the workqueue is cleaned
+up.
+
+Fixes: 5702f75375aa9 ("usb: gadget: udc-core: move sysfs_notify() to a workqueue")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Roy Luo <royluo@google.com>
+Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
+Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/20250204233642.666991-1-royluo@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
+index 1d58adc597a7e..a4120a25428e5 100644
+--- a/drivers/usb/gadget/udc/core.c
++++ b/drivers/usb/gadget/udc/core.c
+@@ -1538,8 +1538,8 @@ void usb_del_gadget(struct usb_gadget *gadget)
+       kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE);
+       sysfs_remove_link(&udc->dev.kobj, "gadget");
+-      flush_work(&gadget->work);
+       device_del(&gadget->dev);
++      flush_work(&gadget->work);
+       ida_free(&gadget_id_numbers, gadget->id_number);
+       cancel_work_sync(&udc->vbus_work);
+       device_unregister(&udc->dev);
+-- 
+2.39.5
+
diff --git a/queue-6.6/usb-gadget-f_midi-f_midi_complete-to-call-queue_work.patch b/queue-6.6/usb-gadget-f_midi-f_midi_complete-to-call-queue_work.patch
new file mode 100644 (file)
index 0000000..1213094
--- /dev/null
@@ -0,0 +1,42 @@
+From a98d12d8b9f685d102ac335ccdb23a14b5527551 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Feb 2025 10:48:05 -0700
+Subject: USB: gadget: f_midi: f_midi_complete to call queue_work
+
+From: Jill Donahue <jilliandonahue58@gmail.com>
+
+[ Upstream commit 4ab37fcb42832cdd3e9d5e50653285ca84d6686f ]
+
+When using USB MIDI, a lock is attempted to be acquired twice through a
+re-entrant call to f_midi_transmit, causing a deadlock.
+
+Fix it by using queue_work() to schedule the inner f_midi_transmit() via
+a high priority work queue from the completion handler.
+
+Link: https://lore.kernel.org/all/CAArt=LjxU0fUZOj06X+5tkeGT+6RbXzpWg1h4t4Fwa_KGVAX6g@mail.gmail.com/
+Fixes: d5daf49b58661 ("USB: gadget: midi: add midi function driver")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Jill Donahue <jilliandonahue58@gmail.com>
+Link: https://lore.kernel.org/r/20250211174805.1369265-1-jdonahue@fender.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/f_midi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c
+index 49946af11a905..6d91d7d7a23f8 100644
+--- a/drivers/usb/gadget/function/f_midi.c
++++ b/drivers/usb/gadget/function/f_midi.c
+@@ -282,7 +282,7 @@ f_midi_complete(struct usb_ep *ep, struct usb_request *req)
+                       /* Our transmit completed. See if there's more to go.
+                        * f_midi_transmit eats req, don't queue it again. */
+                       req->length = 0;
+-                      f_midi_transmit(midi);
++                      queue_work(system_highpri_wq, &midi->work);
+                       return;
+               }
+               break;
+-- 
+2.39.5
+
diff --git a/queue-6.6/vsock-bpf-warn-on-socket-without-transport.patch b/queue-6.6/vsock-bpf-warn-on-socket-without-transport.patch
new file mode 100644 (file)
index 0000000..9db84d9
--- /dev/null
@@ -0,0 +1,53 @@
+From 138910f94064601f4d07ca85ae58ff28a1131a5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Feb 2025 12:58:50 +0100
+Subject: vsock/bpf: Warn on socket without transport
+
+From: Michal Luczaj <mhal@rbox.co>
+
+[ Upstream commit 857ae05549ee2542317e7084ecaa5f8536634dd9 ]
+
+In the spirit of commit 91751e248256 ("vsock: prevent null-ptr-deref in
+vsock_*[has_data|has_space]"), armorize the "impossible" cases with a
+warning.
+
+Fixes: 634f1a7110b4 ("vsock: support sockmap")
+Signed-off-by: Michal Luczaj <mhal@rbox.co>
+Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/vmw_vsock/af_vsock.c  | 3 +++
+ net/vmw_vsock/vsock_bpf.c | 2 +-
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
+index 618b18e80cea0..622875a6f787c 100644
+--- a/net/vmw_vsock/af_vsock.c
++++ b/net/vmw_vsock/af_vsock.c
+@@ -1185,6 +1185,9 @@ static int vsock_read_skb(struct sock *sk, skb_read_actor_t read_actor)
+ {
+       struct vsock_sock *vsk = vsock_sk(sk);
++      if (WARN_ON_ONCE(!vsk->transport))
++              return -ENODEV;
++
+       return vsk->transport->read_skb(vsk, read_actor);
+ }
+diff --git a/net/vmw_vsock/vsock_bpf.c b/net/vmw_vsock/vsock_bpf.c
+index f201d9eca1df2..07b96d56f3a57 100644
+--- a/net/vmw_vsock/vsock_bpf.c
++++ b/net/vmw_vsock/vsock_bpf.c
+@@ -87,7 +87,7 @@ static int vsock_bpf_recvmsg(struct sock *sk, struct msghdr *msg,
+       lock_sock(sk);
+       vsk = vsock_sk(sk);
+-      if (!vsk->transport) {
++      if (WARN_ON_ONCE(!vsk->transport)) {
+               copied = -ENODEV;
+               goto out;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.6/xfs-don-t-over-report-free-space-or-inodes-in-statvf.patch b/queue-6.6/xfs-don-t-over-report-free-space-or-inodes-in-statvf.patch
new file mode 100644 (file)
index 0000000..df1c897
--- /dev/null
@@ -0,0 +1,85 @@
+From b9547623798157fc6bd39157784099cfba9c14ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Dec 2024 14:37:56 -0800
+Subject: xfs: don't over-report free space or inodes in statvfs
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+[ Upstream commit 4b8d867ca6e2fc6d152f629fdaf027053b81765a ]
+
+Emmanual Florac reports a strange occurrence when project quota limits
+are enabled, free space is lower than the remaining quota, and someone
+runs statvfs:
+
+  # mkfs.xfs -f /dev/sda
+  # mount /dev/sda /mnt -o prjquota
+  # xfs_quota  -x -c 'limit -p bhard=2G 55' /mnt
+  # mkdir /mnt/dir
+  # xfs_io -c 'chproj 55' -c 'chattr +P' -c 'stat -vvvv' /mnt/dir
+  # fallocate -l 19g /mnt/a
+  # df /mnt /mnt/dir
+  Filesystem      Size  Used Avail Use% Mounted on
+  /dev/sda         20G   20G  345M  99% /mnt
+  /dev/sda        2.0G     0  2.0G   0% /mnt
+
+I think the bug here is that xfs_fill_statvfs_from_dquot unconditionally
+assigns to f_bfree without checking that the filesystem has enough free
+space to fill the remaining project quota.  However, this is a
+longstanding behavior of xfs so it's unclear what to do here.
+
+Cc: <stable@vger.kernel.org> # v2.6.18
+Fixes: 932f2c323196c2 ("[XFS] statvfs component of directory/project quota support, code originally by Glen.")
+Reported-by: Emmanuel Florac <eflorac@intellique.com>
+Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/xfs/xfs_qm_bhv.c | 27 +++++++++++++++++----------
+ 1 file changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c
+index 268a07218c777..26b2c449f3c66 100644
+--- a/fs/xfs/xfs_qm_bhv.c
++++ b/fs/xfs/xfs_qm_bhv.c
+@@ -32,21 +32,28 @@ xfs_fill_statvfs_from_dquot(
+       limit = blkres->softlimit ?
+               blkres->softlimit :
+               blkres->hardlimit;
+-      if (limit && statp->f_blocks > limit) {
+-              statp->f_blocks = limit;
+-              statp->f_bfree = statp->f_bavail =
+-                      (statp->f_blocks > blkres->reserved) ?
+-                       (statp->f_blocks - blkres->reserved) : 0;
++      if (limit) {
++              uint64_t        remaining = 0;
++
++              if (limit > blkres->reserved)
++                      remaining = limit - blkres->reserved;
++
++              statp->f_blocks = min(statp->f_blocks, limit);
++              statp->f_bfree = min(statp->f_bfree, remaining);
++              statp->f_bavail = min(statp->f_bavail, remaining);
+       }
+       limit = dqp->q_ino.softlimit ?
+               dqp->q_ino.softlimit :
+               dqp->q_ino.hardlimit;
+-      if (limit && statp->f_files > limit) {
+-              statp->f_files = limit;
+-              statp->f_ffree =
+-                      (statp->f_files > dqp->q_ino.reserved) ?
+-                       (statp->f_files - dqp->q_ino.reserved) : 0;
++      if (limit) {
++              uint64_t        remaining = 0;
++
++              if (limit > dqp->q_ino.reserved)
++                      remaining = limit - dqp->q_ino.reserved;
++
++              statp->f_files = min(statp->f_files, limit);
++              statp->f_ffree = min(statp->f_ffree, remaining);
+       }
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.6/xfs-report-realtime-block-quota-limits-on-realtime-d.patch b/queue-6.6/xfs-report-realtime-block-quota-limits-on-realtime-d.patch
new file mode 100644 (file)
index 0000000..e08391a
--- /dev/null
@@ -0,0 +1,98 @@
+From ee2165c9dda9c04943b6e7d15556e1f60863f178 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Nov 2024 20:19:40 -0800
+Subject: xfs: report realtime block quota limits on realtime directories
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+[ Upstream commit 9a17ebfea9d0c7e0bb7409dcf655bf982a5d6e52 ]
+
+On the data device, calling statvfs on a projinherit directory results
+in the block and avail counts being curtailed to the project quota block
+limits, if any are set.  Do the same for realtime files or directories,
+only use the project quota rt block limits.
+
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Stable-dep-of: 4b8d867ca6e2 ("xfs: don't over-report free space or inodes in statvfs")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/xfs/xfs_qm_bhv.c | 18 ++++++++++++------
+ fs/xfs/xfs_super.c  | 11 +++++------
+ 2 files changed, 17 insertions(+), 12 deletions(-)
+
+diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c
+index b77673dd05581..268a07218c777 100644
+--- a/fs/xfs/xfs_qm_bhv.c
++++ b/fs/xfs/xfs_qm_bhv.c
+@@ -19,18 +19,24 @@
+ STATIC void
+ xfs_fill_statvfs_from_dquot(
+       struct kstatfs          *statp,
++      struct xfs_inode        *ip,
+       struct xfs_dquot        *dqp)
+ {
++      struct xfs_dquot_res    *blkres = &dqp->q_blk;
+       uint64_t                limit;
+-      limit = dqp->q_blk.softlimit ?
+-              dqp->q_blk.softlimit :
+-              dqp->q_blk.hardlimit;
++      if (XFS_IS_REALTIME_MOUNT(ip->i_mount) &&
++          (ip->i_diflags & (XFS_DIFLAG_RTINHERIT | XFS_DIFLAG_REALTIME)))
++              blkres = &dqp->q_rtb;
++
++      limit = blkres->softlimit ?
++              blkres->softlimit :
++              blkres->hardlimit;
+       if (limit && statp->f_blocks > limit) {
+               statp->f_blocks = limit;
+               statp->f_bfree = statp->f_bavail =
+-                      (statp->f_blocks > dqp->q_blk.reserved) ?
+-                       (statp->f_blocks - dqp->q_blk.reserved) : 0;
++                      (statp->f_blocks > blkres->reserved) ?
++                       (statp->f_blocks - blkres->reserved) : 0;
+       }
+       limit = dqp->q_ino.softlimit ?
+@@ -61,7 +67,7 @@ xfs_qm_statvfs(
+       struct xfs_dquot        *dqp;
+       if (!xfs_qm_dqget(mp, ip->i_projid, XFS_DQTYPE_PROJ, false, &dqp)) {
+-              xfs_fill_statvfs_from_dquot(statp, dqp);
++              xfs_fill_statvfs_from_dquot(statp, ip, dqp);
+               xfs_qm_dqput(dqp);
+       }
+ }
+diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
+index 13007b6bc9f33..a726fbba49e40 100644
+--- a/fs/xfs/xfs_super.c
++++ b/fs/xfs/xfs_super.c
+@@ -878,12 +878,6 @@ xfs_fs_statfs(
+       ffree = statp->f_files - (icount - ifree);
+       statp->f_ffree = max_t(int64_t, ffree, 0);
+-
+-      if ((ip->i_diflags & XFS_DIFLAG_PROJINHERIT) &&
+-          ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD))) ==
+-                            (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD))
+-              xfs_qm_statvfs(ip, statp);
+-
+       if (XFS_IS_REALTIME_MOUNT(mp) &&
+           (ip->i_diflags & (XFS_DIFLAG_RTINHERIT | XFS_DIFLAG_REALTIME))) {
+               s64     freertx;
+@@ -893,6 +887,11 @@ xfs_fs_statfs(
+               statp->f_bavail = statp->f_bfree = freertx * sbp->sb_rextsize;
+       }
++      if ((ip->i_diflags & XFS_DIFLAG_PROJINHERIT) &&
++          ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD))) ==
++                            (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD))
++              xfs_qm_statvfs(ip, statp);
++
+       return 0;
+ }
+-- 
+2.39.5
+