From c9f3faed643b822d351eb09f944b26bfc536244f Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Fri, 21 Feb 2025 11:51:11 -0500 Subject: [PATCH] Fixes for 6.6 Signed-off-by: Sasha Levin --- ...correct-the-full-scale-volume-set-lo.patch | 121 +++++++ ...realtek-fixup-alc225-depop-procedure.patch | 36 ++ ...p-events-when-no-ump-conversion-is-s.patch | 57 ++++ ...ek-mt8183-disable-dsi-display-output.patch | 61 ++++ ...atek-mt8183-pumpkin-add-hdmi-support.patch | 184 ++++++++++ ...m8450-add-missing-qcom-non-secure-do.patch | 53 +++ ...m8450-fix-adsp-memory-base-and-lengt.patch | 265 +++++++++++++++ ...com-sm8550-add-dma-coherent-property.patch | 133 ++++++++ ...m8550-add-missing-qcom-non-secure-do.patch | 45 +++ ...m8550-fix-adsp-memory-base-and-lengt.patch | 318 ++++++++++++++++++ ...ev_getbyhwaddr-in-arp_req_set_public.patch | 47 +++ ...ssi-add-a-check-for-negative-sample_.patch | 45 +++ ...s-tdm-fix-shift-config-for-snd_soc_d.patch | 46 +++ ...-fix-poor-rf-performance-for-wcn6855.patch | 48 +++ ...pport-downloading-board-id-specific-.patch | 66 ++++ ...date-firmware-name-to-support-board-.patch | 202 +++++++++++ ...ev-add-missing-module_description-ma.patch | 35 ++ ...ufreq-fix-using-cpufreq-dt-as-module.patch | 67 ++++ ...m-fix-missing-read-barrier-in-qcom_s.patch | 71 ++++ ...ix-handling-of-mixed-port-and-port-r.patch | 94 ++++++ ...ix-port-range-key-handling-in-bpf-co.patch | 76 +++++ ...ix-use-after-free-in-geneve_find_dev.patch | 200 +++++++++++ ...list-corruption-splat-in-geneve_dest.patch | 50 +++ ...t-corruption-splat-in-gtp_net_exit_b.patch | 121 +++++++ ...add-stat-for-tx-direct-vs-tx-batched.patch | 127 +++++++ ...-reference-skb-after-sending-to-vios.patch | 85 +++++ ...bmvnic-introduce-send-sub-crq-direct.patch | 170 ++++++++++ ...urn-error-code-on-tx-scrq-flush-fail.patch | 82 +++++ ...ne-serio_pause_rx-guard-to-pause-and.patch | 52 +++ ...fix-crash-when-enabling-pass-through.patch | 138 ++++++++ ...d-factor-out-a-helper-from-mddev_put.patch | 69 ++++ ...-sync_size-into-struct-md_bitmap_sta.patch | 130 +++++++ ...lace-md_bitmap_status-with-a-new-hel.patch | 144 ++++++++ ...chronize-bitmap_get_stats-with-bitma.patch | 88 +++++ ...uster-fix-spares-warnings-for-__le64.patch | 55 +++ queue-6.6/md-simplify-md_seq_ops.patch | 181 ++++++++++ ...parate-work_struct-for-md_start_sync.patch | 90 +++++ ...cvideo-only-save-async-fh-if-success.patch | 90 +++++ .../media-uvcvideo-refactor-iterators.patch | 87 +++++ ...ia-uvcvideo-remove-dangling-pointers.patch | 179 ++++++++++ ...g-fix-soft-lockup-in-the-oom-process.patch | 128 +++++++ ...pdate-mark_victim-tracepoints-fields.patch | 150 +++++++++ ...t-add-non-rcu-dev_getbyhwaddr-helper.patch | 118 +++++++ .../net-axienet-set-mac_managed_pm.patch | 43 +++ ...i-fix-error-handling-causing-null-de.patch | 54 +++ ...create-a-header-for-internal-sharing.patch | 105 ++++++ ...ocotp-ele-fix-mac-address-byte-order.patch | 80 +++++ ...vmem-move-and-rename-fixup_cell_info.patch | 188 +++++++++++ .../nvmem-simplify-the-add_cells-hook.patch | 96 ++++++ ...move-__real_pte-stubs-into-hash-4k.h.patch | 92 +++++ ...ite-__real_pte-and-__rpte_to_hidx-as.patch | 64 ++++ ...ching-fix-kasan-hit-by-not-flagging-.patch | 112 ++++++ ...d-release-function-for-struct-device.patch | 81 +++++ ...o-not-retry-i-os-during-depopulation.patch | 60 ++++ ...-depopulation-and-restoration-in-pro.patch | 63 ++++ queue-6.6/series | 66 ++++ ...-devapc-convert-to-platform-remove-c.patch | 62 ++++ ...-devapc-fix-leaking-io-map-on-driver.patch | 36 ++ ...r-connectible-sockets-allow-only-con.patch | 65 ++++ ...q_space-after-updating-scaling-ratio.patch | 67 ++++ ...-at-the-same-time-as-we-currently-dr.patch | 158 +++++++++ ...create-sysfs-link-between-udc-and-ga.patch | 60 ++++ ...flush-gadget-workqueue-after-device-.patch | 52 +++ ...i-f_midi_complete-to-call-queue_work.patch | 42 +++ ...bpf-warn-on-socket-without-transport.patch | 53 +++ ...eport-free-space-or-inodes-in-statvf.patch | 85 +++++ ...ime-block-quota-limits-on-realtime-d.patch | 98 ++++++ 67 files changed, 6486 insertions(+) create mode 100644 queue-6.6/alsa-hda-cirrus-correct-the-full-scale-volume-set-lo.patch create mode 100644 queue-6.6/alsa-hda-realtek-fixup-alc225-depop-procedure.patch create mode 100644 queue-6.6/alsa-seq-drop-ump-events-when-no-ump-conversion-is-s.patch create mode 100644 queue-6.6/arm64-dts-mediatek-mt8183-disable-dsi-display-output.patch create mode 100644 queue-6.6/arm64-dts-mediatek-mt8183-pumpkin-add-hdmi-support.patch create mode 100644 queue-6.6/arm64-dts-qcom-sm8450-add-missing-qcom-non-secure-do.patch create mode 100644 queue-6.6/arm64-dts-qcom-sm8450-fix-adsp-memory-base-and-lengt.patch create mode 100644 queue-6.6/arm64-dts-qcom-sm8550-add-dma-coherent-property.patch create mode 100644 queue-6.6/arm64-dts-qcom-sm8550-add-missing-qcom-non-secure-do.patch create mode 100644 queue-6.6/arm64-dts-qcom-sm8550-fix-adsp-memory-base-and-lengt.patch create mode 100644 queue-6.6/arp-switch-to-dev_getbyhwaddr-in-arp_req_set_public.patch create mode 100644 queue-6.6/asoc-renesas-rz-ssi-add-a-check-for-negative-sample_.patch create mode 100644 queue-6.6/asoc-rockchip-i2s-tdm-fix-shift-config-for-snd_soc_d.patch create mode 100644 queue-6.6/bluetooth-qca-fix-poor-rf-performance-for-wcn6855.patch create mode 100644 queue-6.6/bluetooth-qca-support-downloading-board-id-specific-.patch create mode 100644 queue-6.6/bluetooth-qca-update-firmware-name-to-support-board-.patch create mode 100644 queue-6.6/cpufreq-dt-platdev-add-missing-module_description-ma.patch create mode 100644 queue-6.6/cpufreq-fix-using-cpufreq-dt-as-module.patch create mode 100644 queue-6.6/firmware-qcom-scm-fix-missing-read-barrier-in-qcom_s.patch create mode 100644 queue-6.6/flow_dissector-fix-handling-of-mixed-port-and-port-r.patch create mode 100644 queue-6.6/flow_dissector-fix-port-range-key-handling-in-bpf-co.patch create mode 100644 queue-6.6/geneve-fix-use-after-free-in-geneve_find_dev.patch create mode 100644 queue-6.6/geneve-suppress-list-corruption-splat-in-geneve_dest.patch create mode 100644 queue-6.6/gtp-suppress-list-corruption-splat-in-gtp_net_exit_b.patch create mode 100644 queue-6.6/ibmvnic-add-stat-for-tx-direct-vs-tx-batched.patch create mode 100644 queue-6.6/ibmvnic-don-t-reference-skb-after-sending-to-vios.patch create mode 100644 queue-6.6/ibmvnic-introduce-send-sub-crq-direct.patch create mode 100644 queue-6.6/ibmvnic-return-error-code-on-tx-scrq-flush-fail.patch create mode 100644 queue-6.6/input-serio-define-serio_pause_rx-guard-to-pause-and.patch create mode 100644 queue-6.6/input-synaptics-fix-crash-when-enabling-pass-through.patch create mode 100644 queue-6.6/md-factor-out-a-helper-from-mddev_put.patch create mode 100644 queue-6.6/md-md-bitmap-add-sync_size-into-struct-md_bitmap_sta.patch create mode 100644 queue-6.6/md-md-bitmap-replace-md_bitmap_status-with-a-new-hel.patch create mode 100644 queue-6.6/md-md-bitmap-synchronize-bitmap_get_stats-with-bitma.patch create mode 100644 queue-6.6/md-md-cluster-fix-spares-warnings-for-__le64.patch create mode 100644 queue-6.6/md-simplify-md_seq_ops.patch create mode 100644 queue-6.6/md-use-separate-work_struct-for-md_start_sync.patch create mode 100644 queue-6.6/media-uvcvideo-only-save-async-fh-if-success.patch create mode 100644 queue-6.6/media-uvcvideo-refactor-iterators.patch create mode 100644 queue-6.6/media-uvcvideo-remove-dangling-pointers.patch create mode 100644 queue-6.6/memcg-fix-soft-lockup-in-the-oom-process.patch create mode 100644 queue-6.6/mm-update-mark_victim-tracepoints-fields.patch create mode 100644 queue-6.6/net-add-non-rcu-dev_getbyhwaddr-helper.patch create mode 100644 queue-6.6/net-axienet-set-mac_managed_pm.patch create mode 100644 queue-6.6/net-sched-cls_api-fix-error-handling-causing-null-de.patch create mode 100644 queue-6.6/nvmem-create-a-header-for-internal-sharing.patch create mode 100644 queue-6.6/nvmem-imx-ocotp-ele-fix-mac-address-byte-order.patch create mode 100644 queue-6.6/nvmem-move-and-rename-fixup_cell_info.patch create mode 100644 queue-6.6/nvmem-simplify-the-add_cells-hook.patch create mode 100644 queue-6.6/powerpc-64s-mm-move-__real_pte-stubs-into-hash-4k.h.patch create mode 100644 queue-6.6/powerpc-64s-rewrite-__real_pte-and-__rpte_to_hidx-as.patch create mode 100644 queue-6.6/powerpc-code-patching-fix-kasan-hit-by-not-flagging-.patch create mode 100644 queue-6.6/s390-ism-add-release-function-for-struct-device.patch create mode 100644 queue-6.6/scsi-core-do-not-retry-i-os-during-depopulation.patch create mode 100644 queue-6.6/scsi-core-handle-depopulation-and-restoration-in-pro.patch create mode 100644 queue-6.6/soc-mediatek-mtk-devapc-convert-to-platform-remove-c.patch create mode 100644 queue-6.6/soc-mediatek-mtk-devapc-fix-leaking-io-map-on-driver.patch create mode 100644 queue-6.6/sockmap-vsock-for-connectible-sockets-allow-only-con.patch create mode 100644 queue-6.6/tcp-adjust-rcvq_space-after-updating-scaling-ratio.patch create mode 100644 queue-6.6/tcp-drop-secpath-at-the-same-time-as-we-currently-dr.patch create mode 100644 queue-6.6/usb-gadget-core-create-sysfs-link-between-udc-and-ga.patch create mode 100644 queue-6.6/usb-gadget-core-flush-gadget-workqueue-after-device-.patch create mode 100644 queue-6.6/usb-gadget-f_midi-f_midi_complete-to-call-queue_work.patch create mode 100644 queue-6.6/vsock-bpf-warn-on-socket-without-transport.patch create mode 100644 queue-6.6/xfs-don-t-over-report-free-space-or-inodes-in-statvf.patch create mode 100644 queue-6.6/xfs-report-realtime-block-quota-limits-on-realtime-d.patch 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 index 0000000000..78950b7ae8 --- /dev/null +++ b/queue-6.6/alsa-hda-cirrus-correct-the-full-scale-volume-set-lo.patch @@ -0,0 +1,121 @@ +From 8fe5f5b2970a8e609c98c29dc2122f5faa951f5b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Feb 2025 21:07:28 +0000 +Subject: ALSA: hda/cirrus: Correct the full scale volume set logic + +From: Vitaly Rodionov + +[ 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 +Link: https://patch.msgid.link/20250214210736.30814-1-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..60f5d6e5d1 --- /dev/null +++ b/queue-6.6/alsa-hda-realtek-fixup-alc225-depop-procedure.patch @@ -0,0 +1,36 @@ +From b6d241d387b34cb59018daa47feba5b3c8c5766f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Feb 2025 14:40:46 +0800 +Subject: ALSA: hda/realtek: Fixup ALC225 depop procedure + +From: Kailang Yang + +[ 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 +Link: https://lore.kernel.org/0474a095ab0044d0939ec4bf4362423d@realtek.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 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 index 0000000000..e8dcc50c3d --- /dev/null +++ b/queue-6.6/alsa-seq-drop-ump-events-when-no-ump-conversion-is-s.patch @@ -0,0 +1,57 @@ +From 79efb5b59b14eb0ea1167ef00115198d1a26d616 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Feb 2025 18:00:30 +0100 +Subject: ALSA: seq: Drop UMP events when no UMP-conversion is set + +From: Takashi Iwai + +[ 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 +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..adce8d0b41 --- /dev/null +++ b/queue-6.6/arm64-dts-mediatek-mt8183-disable-dsi-display-output.patch @@ -0,0 +1,61 @@ +From c63c74776e36f2386af8cef549aae9dba64af4e5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Oct 2024 15:56:28 +0800 +Subject: arm64: dts: mediatek: mt8183: Disable DSI display output by default + +From: Chen-Yu Tsai + +[ 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 +Reviewed-by: Fei Shao +Link: https://lore.kernel.org/r/20241025075630.3917458-2-wenst@chromium.org +Signed-off-by: AngeloGioacchino Del Regno +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..ec30643c9b --- /dev/null +++ b/queue-6.6/arm64-dts-mediatek-mt8183-pumpkin-add-hdmi-support.patch @@ -0,0 +1,184 @@ +From 97ec9ef530c7bd3554acee79c276b8582075c785 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Co-developed-by: Pin-yen Lin +Signed-off-by: Pin-yen Lin +Reviewed-by: Nícolas F. R. A. Prado +Link: https://lore.kernel.org/r/20240919094212.1902073-1-treapking@chromium.org +Signed-off-by: AngeloGioacchino Del Regno +Stable-dep-of: 26f6e91fa29a ("arm64: dts: mediatek: mt8183: Disable DSI display output by default") +Signed-off-by: Sasha Levin +--- + .../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 = ; ++ input-enable; ++ bias-pull-up; ++ }; ++ ++ pins-rst { ++ pinmux = ; ++ output-high; ++ }; ++ }; ++ ++ dpi_func_pins: dpi-func-pins { ++ pins-dpi { ++ pinmux = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++ }; ++ ++ dpi_idle_pins: dpi-idle-pins { ++ pins-idle { ++ pinmux = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++ }; + }; + + &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 index 0000000000..0874ebb92e --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-sm8450-add-missing-qcom-non-secure-do.patch @@ -0,0 +1,53 @@ +From 4cc31e49a9d7ca94264ba8a6556b5e886301b02a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Feb 2024 13:53:04 +0100 +Subject: arm64: dts: qcom: sm8450: add missing qcom,non-secure-domain property + +From: Neil Armstrong + +[ 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 +Link: https://lore.kernel.org/r/20240227-topic-sm8x50-upstream-fastrpc-non-secure-domain-v1-1-15c4c864310f@linaro.org +Signed-off-by: Bjorn Andersson +Stable-dep-of: 13c96bee5d5e ("arm64: dts: qcom: sm8450: Fix ADSP memory base and length") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..492fe6c0bb --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-sm8450-fix-adsp-memory-base-and-lengt.patch @@ -0,0 +1,265 @@ +From 5a3c9ee21fcc82e9ba9722f0fd8fabc55e848d7a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Dec 2024 15:53:53 +0100 +Subject: arm64: dts: qcom: sm8450: Fix ADSP memory base and length + +From: Krzysztof Kozlowski + +[ 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 +Signed-off-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20241213-dts-qcom-cdsp-mpss-base-address-v3-4-2e0036fccd8d@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + 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 = ; ++ qcom,intents = <512 20>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ q6apm: service@1 { ++ compatible = "qcom,q6apm"; ++ reg = ; ++ #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 = ; ++ 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 = ; +- qcom,intents = <512 20>; +- #address-cells = <1>; +- #size-cells = <0>; +- +- q6apm: service@1 { +- compatible = "qcom,q6apm"; +- reg = ; +- #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 = ; +- 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 index 0000000000..030b8a6f80 --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-sm8550-add-dma-coherent-property.patch @@ -0,0 +1,133 @@ +From 5511a73a9225f329eda072646d942bb2d673ebae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Jan 2024 15:54:12 +0530 +Subject: arm64: dts: qcom: sm8550: Add dma-coherent property + +From: Ling Xu + +[ 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 +Link: https://lore.kernel.org/r/20240125102413.3016-2-quic_lxu5@quicinc.com +Signed-off-by: Bjorn Andersson +Stable-dep-of: a6a8f54bc2af ("arm64: dts: qcom: sm8550: Fix ADSP memory base and length") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..a7edd2772b --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-sm8550-add-missing-qcom-non-secure-do.patch @@ -0,0 +1,45 @@ +From 5365e7c2c02a7013abfc0318c0e1677f4417cafe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Feb 2024 13:53:05 +0100 +Subject: arm64: dts: qcom: sm8550: add missing qcom,non-secure-domain property + +From: Neil Armstrong + +[ 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 +Link: https://lore.kernel.org/r/20240227-topic-sm8x50-upstream-fastrpc-non-secure-domain-v1-2-15c4c864310f@linaro.org +Signed-off-by: Bjorn Andersson +Stable-dep-of: a6a8f54bc2af ("arm64: dts: qcom: sm8550: Fix ADSP memory base and length") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..94a61da229 --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-sm8550-fix-adsp-memory-base-and-lengt.patch @@ -0,0 +1,318 @@ +From 0c7b4e920f31620058fdea31fb4f85e4bdfcf506 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Dec 2024 15:53:56 +0100 +Subject: arm64: dts: qcom: sm8550: Fix ADSP memory base and length + +From: Krzysztof Kozlowski + +[ 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 +Reviewed-by: Konrad Dybcio +Signed-off-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20241213-dts-qcom-cdsp-mpss-base-address-v3-7-2e0036fccd8d@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + 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 = ; ++ qcom,intents = <512 20>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ q6apm: service@1 { ++ compatible = "qcom,q6apm"; ++ reg = ; ++ #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 = ; ++ 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 = ; + }; + +- 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 = ; +- qcom,intents = <512 20>; +- #address-cells = <1>; +- #size-cells = <0>; +- +- q6apm: service@1 { +- compatible = "qcom,q6apm"; +- reg = ; +- #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 = ; +- 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 index 0000000000..dc55af906b --- /dev/null +++ b/queue-6.6/arp-switch-to-dev_getbyhwaddr-in-arp_req_set_public.patch @@ -0,0 +1,47 @@ +From 7158cb2f448f124c0dffac0dbeb559dea3560bba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Feb 2025 05:49:31 -0800 +Subject: arp: switch to dev_getbyhwaddr() in arp_req_set_public() + +From: Breno Leitao + +[ 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 +Reviewed-by: Kuniyuki Iwashima +Signed-off-by: Breno Leitao +Link: https://patch.msgid.link/20250218-arm_fix_selftest-v5-2-d3d6892db9e1@debian.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..d104777714 --- /dev/null +++ b/queue-6.6/asoc-renesas-rz-ssi-add-a-check-for-negative-sample_.patch @@ -0,0 +1,45 @@ +From e40008cd6d01ccf7975bc0d0cd801ba800b2326b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Jan 2025 12:28:46 +0300 +Subject: ASoC: renesas: rz-ssi: Add a check for negative sample_space + +From: Dan Carpenter + +[ 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 +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/e07c3dc5-d885-4b04-a742-71f42243f4fd@stanley.mountain +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..87f391286b --- /dev/null +++ b/queue-6.6/asoc-rockchip-i2s-tdm-fix-shift-config-for-snd_soc_d.patch @@ -0,0 +1,46 @@ +From d962718b649e8880a57daea401b002473006c9c0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://patch.msgid.link/20250204161311.2117240-1-jkeeping@inmusicbrands.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..9b3cbd0690 --- /dev/null +++ b/queue-6.6/bluetooth-qca-fix-poor-rf-performance-for-wcn6855.patch @@ -0,0 +1,48 @@ +From 2e5d6e22149a5c3076dd5438b6b57bd878b7c1bf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Jan 2025 22:43:23 +0800 +Subject: Bluetooth: qca: Fix poor RF performance for WCN6855 + +From: Zijun Hu + +[ 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 +Tested-by: Johan Hovold +Reviewed-by: Johan Hovold +Tested-by: Steev Klimaszewski #Thinkpad X13s +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..4b87e4bf43 --- /dev/null +++ b/queue-6.6/bluetooth-qca-support-downloading-board-id-specific-.patch @@ -0,0 +1,66 @@ +From 43c4baefd3cd32782be7882dd8631ee7d25d23b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 Apr 2024 15:49:34 +0800 +Subject: Bluetooth: qca: Support downloading board id specific NVM for WCN7850 + +From: Zijun Hu + +[ Upstream commit e41137d8bd1a8e8bab8dcbfe3ec056418db3df18 ] + +Download board id specific NVM instead of default for WCN7850 if board id +is available. + +Signed-off-by: Zijun Hu +Signed-off-by: Luiz Augusto von Dentz +Stable-dep-of: a2fad248947d ("Bluetooth: qca: Fix poor RF performance for WCN6855") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..8aa22d99a3 --- /dev/null +++ b/queue-6.6/bluetooth-qca-update-firmware-name-to-support-board-.patch @@ -0,0 +1,202 @@ +From 0b91e6fda0be5a9f47fe69281c88dc11592e8ace Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Jan 2025 17:26:49 +0800 +Subject: Bluetooth: qca: Update firmware-name to support board specific nvm + +From: Cheng Jiang + +[ 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 +Signed-off-by: Luiz Augusto von Dentz +Stable-dep-of: a2fad248947d ("Bluetooth: qca: Fix poor RF performance for WCN6855") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..fa664ae3fc --- /dev/null +++ b/queue-6.6/cpufreq-dt-platdev-add-missing-module_description-ma.patch @@ -0,0 +1,35 @@ +From 049303b8b0223c93d891450bdd9ac547679e5d47 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 2 Jun 2024 15:14:00 -0700 +Subject: cpufreq: dt-platdev: add missing MODULE_DESCRIPTION() macro + +From: Jeff Johnson + +[ 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 +Signed-off-by: Viresh Kumar +Stable-dep-of: f1f010c9d9c6 ("cpufreq: fix using cpufreq-dt as module") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..c2eba7e1b9 --- /dev/null +++ b/queue-6.6/cpufreq-fix-using-cpufreq-dt-as-module.patch @@ -0,0 +1,67 @@ +From 059d6f9c5da44dfa4d60abb52d69aa56b7de81f3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 3 Nov 2024 22:02:51 +0100 +Subject: cpufreq: fix using cpufreq-dt as module + +From: Andreas Kemnade + +[ 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 +Reported-by: Radu Rendec +Reported-by: Javier Martinez Canillas +[ Viresh: Picked commit log from Javier, updated tags ] +Signed-off-by: Viresh Kumar +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..c4067d428a --- /dev/null +++ b/queue-6.6/firmware-qcom-scm-fix-missing-read-barrier-in-qcom_s.patch @@ -0,0 +1,71 @@ +From 3299012631064cb83587e5113d6a97c5c426f119 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Krzysztof Kozlowski +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 +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..865df0d3ea --- /dev/null +++ b/queue-6.6/flow_dissector-fix-handling-of-mixed-port-and-port-r.patch @@ -0,0 +1,94 @@ +From 567811550ccbfd43d388faa52630b8ac7ff7789b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Feb 2025 20:32:07 -0800 +Subject: flow_dissector: Fix handling of mixed port and port-range keys + +From: Cong Wang + +[ 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 +Closes: https://lore.kernel.org/netdev/CAPx+-5uvFxkhkz4=j_Xuwkezjn9U6kzKTD5jz4tZ9msSJ0fOJA@mail.gmail.com/ +Cc: Yoshiki Komachi +Cc: Jamal Hadi Salim +Cc: Jiri Pirko +Signed-off-by: Cong Wang +Reviewed-by: Ido Schimmel +Link: https://patch.msgid.link/20250218043210.732959-2-xiyou.wangcong@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..af155cdc3f --- /dev/null +++ b/queue-6.6/flow_dissector-fix-port-range-key-handling-in-bpf-co.patch @@ -0,0 +1,76 @@ +From 299b599ee3fcf1fc072e14505cbf59ffeb6b01e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Feb 2025 20:32:09 -0800 +Subject: flow_dissector: Fix port range key handling in BPF conversion + +From: Cong Wang + +[ 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 +Closes: https://lore.kernel.org/netdev/CAPx+-5uvFxkhkz4=j_Xuwkezjn9U6kzKTD5jz4tZ9msSJ0fOJA@mail.gmail.com/ +Cc: Yoshiki Komachi +Cc: Jamal Hadi Salim +Cc: Jiri Pirko +Signed-off-by: Cong Wang +Link: https://patch.msgid.link/20250218043210.732959-4-xiyou.wangcong@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..fcf2f9cfc7 --- /dev/null +++ b/queue-6.6/geneve-fix-use-after-free-in-geneve_find_dev.patch @@ -0,0 +1,200 @@ +From f8e727b85c174ba5c295a9b1fd9aa73fced4c5c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Feb 2025 13:33:54 +0900 +Subject: geneve: Fix use-after-free in geneve_find_dev(). + +From: Kuniyuki Iwashima + +[ 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 +Signed-off-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20250213043354.91368-1-kuniyu@amazon.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..6551aacaf1 --- /dev/null +++ b/queue-6.6/geneve-suppress-list-corruption-splat-in-geneve_dest.patch @@ -0,0 +1,50 @@ +From c7148408e5f0552bd4c5cd444b45823bc5c92a80 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Feb 2025 12:37:05 -0800 +Subject: geneve: Suppress list corruption splat in geneve_destroy_tunnels(). + +From: Kuniyuki Iwashima + +[ 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 +Link: https://patch.msgid.link/20250217203705.40342-3-kuniyu@amazon.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..cfa7da7508 --- /dev/null +++ b/queue-6.6/gtp-suppress-list-corruption-splat-in-gtp_net_exit_b.patch @@ -0,0 +1,121 @@ +From 863141e4608c723c030afd25c73cf78bf37ae7de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Feb 2025 12:37:04 -0800 +Subject: gtp: Suppress list corruption splat in gtp_net_exit_batch_rtnl(). + +From: Kuniyuki Iwashima + +[ 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:[] __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: + + [] __list_del_entry_valid include/linux/list.h:131 [inline] fffffe8040b4fc28 + [] __list_del_entry include/linux/list.h:248 [inline] fffffe8040b4fc28 + [] list_del include/linux/list.h:262 [inline] fffffe8040b4fc28 + [] gtp_dellink+0x16d/0x360 drivers/net/gtp.c:1557 fffffe8040b4fc28 + [] gtp_net_exit_batch_rtnl+0x124/0x2c0 drivers/net/gtp.c:2495 fffffe8040b4fc88 + [] cleanup_net+0x5a4/0xbe0 net/core/net_namespace.c:635 fffffe8040b4fcd0 + [] process_one_work+0xbd7/0x2160 kernel/workqueue.c:3326 fffffe8040b4fd88 + [] process_scheduled_works kernel/workqueue.c:3407 [inline] fffffe8040b4fec0 + [] worker_thread+0x6b5/0xfa0 kernel/workqueue.c:3488 fffffe8040b4fec0 + [] kthread+0x360/0x4c0 kernel/kthread.c:397 fffffe8040b4ff78 + [] ret_from_fork+0x74/0xe0 arch/x86/kernel/process.c:172 fffffe8040b4ffb8 + [] ret_from_fork_asm+0x29/0xc0 arch/x86/entry/entry_64.S:399 fffffe8040b4ffe8 + +Modules linked in: + +Fixes: eb28fd76c0a0 ("gtp: Destroy device along with udp socket's netns dismantle.") +Reported-by: Brad Spengler +Signed-off-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20250217203705.40342-2-kuniyu@amazon.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 == >p_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 index 0000000000..0ff0bfeb08 --- /dev/null +++ b/queue-6.6/ibmvnic-add-stat-for-tx-direct-vs-tx-batched.patch @@ -0,0 +1,127 @@ +From cbeebd53e54f7e37837331e317166a3d2e86b0aa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Oct 2024 11:35:31 -0500 +Subject: ibmvnic: Add stat for tx direct vs tx batched + +From: Nick Child + +[ Upstream commit 2ee73c54a615b74d2e7ee6f20844fd3ba63fc485 ] + +Allow tracking of packets sent with send_subcrq direct vs +indirect. `ethtool -S ` 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 +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20241001163531.1803152-1-nnac123@linux.ibm.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: bdf5d13aa05e ("ibmvnic: Don't reference skb after sending to VIOS") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..dfd0540333 --- /dev/null +++ b/queue-6.6/ibmvnic-don-t-reference-skb-after-sending-to-vios.patch @@ -0,0 +1,85 @@ +From 80da7f18ac58a97bb2d25870f7fe8c13ff8ac8c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Feb 2025 09:52:33 -0600 +Subject: ibmvnic: Don't reference skb after sending to VIOS + +From: Nick Child + +[ 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 +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250214155233.235559-1-nnac123@linux.ibm.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..e4c95429f7 --- /dev/null +++ b/queue-6.6/ibmvnic-introduce-send-sub-crq-direct.patch @@ -0,0 +1,170 @@ +From 9605faea97bbc7b0457f6459c7e4771e0b65671c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Aug 2024 16:18:07 -0500 +Subject: ibmvnic: Introduce send sub-crq direct + +From: Nick Child + +[ 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 +Link: https://patch.msgid.link/20240807211809.1259563-6-nnac123@linux.ibm.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: bdf5d13aa05e ("ibmvnic: Don't reference skb after sending to VIOS") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..4db87dae75 --- /dev/null +++ b/queue-6.6/ibmvnic-return-error-code-on-tx-scrq-flush-fail.patch @@ -0,0 +1,82 @@ +From ff41b80ef86322f6b7cba4174b3bea0b8c9a4c79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Apr 2024 11:41:28 -0500 +Subject: ibmvnic: Return error code on TX scrq flush fail + +From: Nick Child + +[ 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 +Link: https://lore.kernel.org/r/20240416164128.387920-1-nnac123@linux.ibm.com +Signed-off-by: Paolo Abeni +Stable-dep-of: bdf5d13aa05e ("ibmvnic: Don't reference skb after sending to VIOS") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..2be95bd848 --- /dev/null +++ b/queue-6.6/input-serio-define-serio_pause_rx-guard-to-pause-and.patch @@ -0,0 +1,52 @@ +From f38e56cee2b4fcd0445075dbcc043b94bc30d740 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Stable-dep-of: 08bd5b7c9a24 ("Input: synaptics - fix crash when enabling pass-through port") +Signed-off-by: Sasha Levin +--- + 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 + #include + #include + #include +@@ -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 index 0000000000..0be9f87864 --- /dev/null +++ b/queue-6.6/input-synaptics-fix-crash-when-enabling-pass-through.patch @@ -0,0 +1,138 @@ +From 01acf412d2e4c8732bbf2f0943fe5d11e4681a47 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Jan 2025 09:23:40 -0800 +Subject: Input: synaptics - fix crash when enabling pass-through port + +From: Dmitry Torokhov + +[ 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 +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 +Link: https://lore.kernel.org/r/Z4qSHORvPn7EU2j1@google.com +Signed-off-by: Dmitry Torokhov +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..23d4b9ff50 --- /dev/null +++ b/queue-6.6/md-factor-out-a-helper-from-mddev_put.patch @@ -0,0 +1,69 @@ +From 1e6244068d989889c500ad7139e2fa5c0137658c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Sep 2023 14:12:40 +0800 +Subject: md: factor out a helper from mddev_put() + +From: Yu Kuai + +[ Upstream commit 3d8d32873c7b6d9cec5b40c2ddb8c7c55961694f ] + +There are no functional changes, prepare to simplify md_seq_ops in next +patch. + +Signed-off-by: Yu Kuai +Signed-off-by: Song Liu +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 +--- + 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 index 0000000000..39cc5af946 --- /dev/null +++ b/queue-6.6/md-md-bitmap-add-sync_size-into-struct-md_bitmap_sta.patch @@ -0,0 +1,130 @@ +From de123127a63e00066cff40f19425b6ff3db07b08 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Aug 2024 15:44:16 +0800 +Subject: md/md-bitmap: add 'sync_size' into struct md_bitmap_stats + +From: Yu Kuai + +[ 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 +Link: https://lore.kernel.org/r/20240826074452.1490072-7-yukuai1@huaweicloud.com +Signed-off-by: Song Liu +Stable-dep-of: 8d28d0ddb986 ("md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..41cf91a262 --- /dev/null +++ b/queue-6.6/md-md-bitmap-replace-md_bitmap_status-with-a-new-hel.patch @@ -0,0 +1,144 @@ +From 0774b740b6c6d955ea82931e22db0a7c216aafaa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20240826074452.1490072-3-yukuai1@huaweicloud.com +Signed-off-by: Song Liu +Stable-dep-of: 8d28d0ddb986 ("md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..cc61efd4a0 --- /dev/null +++ b/queue-6.6/md-md-bitmap-synchronize-bitmap_get_stats-with-bitma.patch @@ -0,0 +1,88 @@ +From f41040c9cfcd2ca71a95fabf83b861188d8118c7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Jan 2025 17:20:55 +0800 +Subject: md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime + +From: Yu Kuai + +[ 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: + + 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 +Closes: https://lore.kernel.org/linux-raid/ca3a91a2-50ae-4f68-b317-abd9889f3907@oracle.com/T/#m6e5086c95201135e4941fe38f9efa76daf9666c5 +Signed-off-by: Yu Kuai +Link: https://lore.kernel.org/r/20250124092055.4050195-1-yukuai1@huaweicloud.com +Signed-off-by: Song Liu +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..345d444cea --- /dev/null +++ b/queue-6.6/md-md-cluster-fix-spares-warnings-for-__le64.patch @@ -0,0 +1,55 @@ +From 3c1283e04955d0949edc50fb7de53a1bbc197675 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Aug 2024 15:44:15 +0800 +Subject: md/md-cluster: fix spares warnings for __le64 + +From: Yu Kuai + +[ 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 +Link: https://lore.kernel.org/r/20240826074452.1490072-6-yukuai1@huaweicloud.com +Signed-off-by: Song Liu +Stable-dep-of: 8d28d0ddb986 ("md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..36355710de --- /dev/null +++ b/queue-6.6/md-simplify-md_seq_ops.patch @@ -0,0 +1,181 @@ +From a49017c061f1439948f224c7e0fa5e1ae3337b46 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Sep 2023 14:12:41 +0800 +Subject: md: simplify md_seq_ops + +From: Yu Kuai + +[ 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 +Signed-off-by: Song Liu +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 +--- + 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 index 0000000000..dec85b3463 --- /dev/null +++ b/queue-6.6/md-use-separate-work_struct-for-md_start_sync.patch @@ -0,0 +1,90 @@ +From a7ba22e00cf1205f5cb4ae22f9a8780dd2330f96 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Aug 2023 11:16:16 +0800 +Subject: md: use separate work_struct for md_start_sync() + +From: Yu Kuai + +[ 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 +Reviewed-by: Xiao Ni +Signed-off-by: Song Liu +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 +--- + 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 index 0000000000..9e47bde2bb --- /dev/null +++ b/queue-6.6/media-uvcvideo-only-save-async-fh-if-success.patch @@ -0,0 +1,90 @@ +From bdbd431462fb9f9ac6e30fe18e91e528193f64ff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Dec 2024 21:20:08 +0000 +Subject: media: uvcvideo: Only save async fh if success + +From: Ricardo Ribalda + +[ 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 +Reviewed-by: Hans de Goede +Reviewed-by: Laurent Pinchart +Signed-off-by: Ricardo Ribalda +Link: https://lore.kernel.org/r/20241203-uvc-fix-async-v6-1-26c867231118@chromium.org +Signed-off-by: Laurent Pinchart +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..c15e80d6fe --- /dev/null +++ b/queue-6.6/media-uvcvideo-refactor-iterators.patch @@ -0,0 +1,87 @@ +From 7480d2c9c6e75b5b7464fe59c3c77cbb363a0a89 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Apr 2024 15:04:42 +0000 +Subject: media: uvcvideo: Refactor iterators + +From: Ricardo Ribalda + +[ 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 +Reviewed-by: Laurent Pinchart +Signed-off-by: Ricardo Ribalda +Signed-off-by: Hans Verkuil +Stable-dep-of: d9fecd096f67 ("media: uvcvideo: Only save async fh if success") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..afa9b65b93 --- /dev/null +++ b/queue-6.6/media-uvcvideo-remove-dangling-pointers.patch @@ -0,0 +1,179 @@ +From 129293d5f759d938d6568e015995a1b6172e8667 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Dec 2024 21:20:10 +0000 +Subject: media: uvcvideo: Remove dangling pointers + +From: Ricardo Ribalda + +[ 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 +Signed-off-by: Ricardo Ribalda +Reviewed-by: Laurent Pinchart +Link: https://lore.kernel.org/r/20241203-uvc-fix-async-v6-3-26c867231118@chromium.org +Signed-off-by: Laurent Pinchart +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..efa592b853 --- /dev/null +++ b/queue-6.6/memcg-fix-soft-lockup-in-the-oom-process.patch @@ -0,0 +1,128 @@ +From 3699e0eb6a675b9ce9f53afd78f07001d4dae1d0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Acked-by: Michal Hocko +Cc: Roman Gushchin +Cc: Johannes Weiner +Cc: Shakeel Butt +Cc: Muchun Song +Cc: Michal Koutný +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + 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 + #include + #include ++#include + + #include + #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 index 0000000000..13f76e0993 --- /dev/null +++ b/queue-6.6/mm-update-mark_victim-tracepoints-fields.patch @@ -0,0 +1,150 @@ +From b434aad3912b847e02ea9e82ee598e1a41820404 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Steven Rostedt +Cc: Suren Baghdasaryan +Cc: Michal Hocko +Cc: "Masami Hiramatsu (Google)" +Cc: Mathieu Desnoyers +Signed-off-by: Andrew Morton +Stable-dep-of: ade81479c7dd ("memcg: fix soft lockup in the OOM process") +Signed-off-by: Sasha Levin +--- + 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 + #include + ++#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 + #include + #include ++#include + + #include + #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 index 0000000000..db39e8e6f0 --- /dev/null +++ b/queue-6.6/net-add-non-rcu-dev_getbyhwaddr-helper.patch @@ -0,0 +1,118 @@ +From 334b3bbd86ae4f6845e8b41dfa5b57a8106704d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Feb 2025 05:49:30 -0800 +Subject: net: Add non-RCU dev_getbyhwaddr() helper + +From: Breno Leitao + +[ 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 +Signed-off-by: Breno Leitao +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20250218-arm_fix_selftest-v5-1-d3d6892db9e1@debian.org +Signed-off-by: Jakub Kicinski +Stable-dep-of: 4eae0ee0f1e6 ("arp: switch to dev_getbyhwaddr() in arp_req_set_public()") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..998abd8fb1 --- /dev/null +++ b/queue-6.6/net-axienet-set-mac_managed_pm.patch @@ -0,0 +1,43 @@ +From 78adb74b443acdb08610615257ce72f1b507fb16 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Feb 2025 13:58:42 +0800 +Subject: net: axienet: Set mac_managed_pm + +From: Nick Hu + +[ 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 +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20250217055843.19799-1-nick.hu@sifive.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..4f6cb6a719 --- /dev/null +++ b/queue-6.6/net-sched-cls_api-fix-error-handling-causing-null-de.patch @@ -0,0 +1,54 @@ +From fa576c563cd4c52013a5e10e6486cd9474c40fcd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Feb 2025 23:36:10 +0100 +Subject: net/sched: cls_api: fix error handling causing NULL dereference + +From: Pierre Riteau + +[ 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 +Reviewed-by: Michal Swiatkowski +Link: https://patch.msgid.link/20250213223610.320278-1-pierre@stackhpc.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..98d760fe92 --- /dev/null +++ b/queue-6.6/nvmem-create-a-header-for-internal-sharing.patch @@ -0,0 +1,105 @@ +From 65e58cb85610cd4b55f0abffd83ee044ee785114 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Dec 2023 11:15:29 +0000 +Subject: nvmem: Create a header for internal sharing + +From: Miquel Raynal + +[ 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 +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20231215111536.316972-4-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 391b06ecb63e ("nvmem: imx-ocotp-ele: fix MAC address byte order") +Signed-off-by: Sasha Levin +--- + 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 + #include + +-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 ++#include ++#include ++ ++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 index 0000000000..5bf202864f --- /dev/null +++ b/queue-6.6/nvmem-imx-ocotp-ele-fix-mac-address-byte-order.patch @@ -0,0 +1,80 @@ +From 93f1413f9c6dcfb7728c8df89f42dfede86d75cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Dec 2024 14:18:58 +0000 +Subject: nvmem: imx-ocotp-ele: fix MAC address byte order + +From: Sascha Hauer + +[ 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 +Cc: stable +Reviewed-by: Peng Fan +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20241230141901.263976-4-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..e80d98e0bf --- /dev/null +++ b/queue-6.6/nvmem-move-and-rename-fixup_cell_info.patch @@ -0,0 +1,188 @@ +From 29897786a6ff9cb457846a557609bdf5419e77f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Dec 2023 11:15:31 +0000 +Subject: nvmem: Move and rename ->fixup_cell_info() + +From: Miquel Raynal + +[ 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 +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20231215111536.316972-6-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 391b06ecb63e ("nvmem: imx-ocotp-ele: fix MAC address byte order") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..789bbdd114 --- /dev/null +++ b/queue-6.6/nvmem-simplify-the-add_cells-hook.patch @@ -0,0 +1,96 @@ +From 273420e0ab0ef38134f4d41451f8f1b837164be3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Dec 2023 11:15:30 +0000 +Subject: nvmem: Simplify the ->add_cells() hook + +From: Miquel Raynal + +[ 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 +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20231215111536.316972-5-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 391b06ecb63e ("nvmem: imx-ocotp-ele: fix MAC address byte order") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..3b4c5c59f1 --- /dev/null +++ b/queue-6.6/powerpc-64s-mm-move-__real_pte-stubs-into-hash-4k.h.patch @@ -0,0 +1,92 @@ +From dbcf5c99dc5c42daeaad35fa81f635746c9d5513 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Aug 2024 18:07:29 +1000 +Subject: powerpc/64s/mm: Move __real_pte stubs into hash-4k.h + +From: Michael Ellerman + +[ 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 +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 +--- + 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 index 0000000000..073f1d5ffc --- /dev/null +++ b/queue-6.6/powerpc-64s-rewrite-__real_pte-and-__rpte_to_hidx-as.patch @@ -0,0 +1,64 @@ +From b1b68eb31f40ec076e383b942af5b83e901ddbee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +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 +Reviewed-by: Ritesh Harjani (IBM) +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/e0d340a5b7bd478ecbf245d826e6ab2778b74e06.1736706263.git.christophe.leroy@csgroup.eu +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..fe97ac1df7 --- /dev/null +++ b/queue-6.6/powerpc-code-patching-fix-kasan-hit-by-not-flagging-.patch @@ -0,0 +1,112 @@ +From ffdbe671157768b5b690772f89f2cf54045aa0a9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 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 +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 +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/06621423da339b374f48c0886e3a5db18e896be8.1739342693.git.christophe.leroy@csgroup.eu +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..06fcfb466d --- /dev/null +++ b/queue-6.6/s390-ism-add-release-function-for-struct-device.patch @@ -0,0 +1,81 @@ +From 9826d8b5681ea6eed03dab09277bb4d158ff1657 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Feb 2025 13:01:37 +0100 +Subject: s390/ism: add release function for struct device + +From: Julian Ruess + +[ 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 +Reviewed-by: Wenjia Zhang +Signed-off-by: Julian Ruess +Signed-off-by: Alexandra Winter +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250214120137.563409-1-wintera@linux.ibm.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..5631670aff --- /dev/null +++ b/queue-6.6/scsi-core-do-not-retry-i-os-during-depopulation.patch @@ -0,0 +1,60 @@ +From 2c343401e457db93757d4d8fa2faede8344026ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Jan 2025 10:44:07 -0800 +Subject: scsi: core: Do not retry I/Os during depopulation + +From: Igor Pylypiv + +[ 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 +Link: https://lore.kernel.org/r/20250131184408.859579-1-ipylypiv@google.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..b82cfbbdb8 --- /dev/null +++ b/queue-6.6/scsi-core-handle-depopulation-and-restoration-in-pro.patch @@ -0,0 +1,63 @@ +From 00f7976414d36f3e642accd439f39ea6e44b0bab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 15 Oct 2023 01:06:50 -0400 +Subject: scsi: core: Handle depopulation and restoration in progress + +From: Douglas Gilbert + +[ 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 +Link: https://lore.kernel.org/r/20231015050650.131145-1-dgilbert@interlog.com +Signed-off-by: Martin K. Petersen +Stable-dep-of: 9ff7c383b8ac ("scsi: core: Do not retry I/Os during depopulation") +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.6/series b/queue-6.6/series index 414dd126c5..5d7f50c6da 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -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 index 0000000000..cf848104cf --- /dev/null +++ b/queue-6.6/soc-mediatek-mtk-devapc-convert-to-platform-remove-c.patch @@ -0,0 +1,62 @@ +From cb934574784c95a716d1403d21a7e1833ab69a9e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20230925095532.1984344-15-u.kleine-koenig@pengutronix.de +Signed-off-by: Uwe Kleine-König +Stable-dep-of: c9c0036c1990 ("soc: mediatek: mtk-devapc: Fix leaking IO map on driver remove") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..fa05a8501f --- /dev/null +++ b/queue-6.6/soc-mediatek-mtk-devapc-fix-leaking-io-map-on-driver.patch @@ -0,0 +1,36 @@ +From f818acea5248afef9fe9ff8ab02407dda77c1f9c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 4 Jan 2025 15:20:12 +0100 +Subject: soc: mediatek: mtk-devapc: Fix leaking IO map on driver remove + +From: Krzysztof Kozlowski + +[ 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 +Link: https://lore.kernel.org/r/20250104142012.115974-2-krzysztof.kozlowski@linaro.org +Signed-off-by: AngeloGioacchino Del Regno +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..b65154b62f --- /dev/null +++ b/queue-6.6/sockmap-vsock-for-connectible-sockets-allow-only-con.patch @@ -0,0 +1,65 @@ +From 3cb4906146fb44e7b1a0af27020795d9b5b8246f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Feb 2025 12:58:49 +0100 +Subject: sockmap, vsock: For connectible sockets allow only connected + +From: Michal Luczaj + +[ 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 +Acked-by: Stefano Garzarella +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..d95150e02f --- /dev/null +++ b/queue-6.6/tcp-adjust-rcvq_space-after-updating-scaling-ratio.patch @@ -0,0 +1,67 @@ +From 752fff80c76ea32af9555c5b2b24caedd8168971 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Feb 2025 15:29:05 -0800 +Subject: tcp: adjust rcvq_space after updating scaling ratio + +From: Jakub Kicinski + +[ 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 +Reviewed-by: Neal Cardwell +Link: https://patch.msgid.link/20250217232905.3162187-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..eba9bb8d2a --- /dev/null +++ b/queue-6.6/tcp-drop-secpath-at-the-same-time-as-we-currently-dr.patch @@ -0,0 +1,158 @@ +From f50795547ecb9b7becca71013e32edf2c729bdca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Sabrina Dubroca +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/5055ba8f8f72bdcb602faa299faca73c280b7735.1739743613.git.sd@queasysnail.net +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + 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 + #include + #include ++#include + + #include + #include +@@ -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 index 0000000000..a9d16fe315 --- /dev/null +++ b/queue-6.6/usb-gadget-core-create-sysfs-link-between-udc-and-ga.patch @@ -0,0 +1,60 @@ +From 29dff33d6c0d595ebf400e58c6b912b36a4855b3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Mar 2024 03:09:22 +0000 +Subject: USB: gadget: core: create sysfs link between udc and gadget + +From: Roy Luo + +[ 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 +Link: https://lore.kernel.org/r/20240307030922.3573161-1-royluo@google.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 399a45e5237c ("usb: gadget: core: flush gadget workqueue after device removal") +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..5711ce382e --- /dev/null +++ b/queue-6.6/usb-gadget-core-flush-gadget-workqueue-after-device-.patch @@ -0,0 +1,52 @@ +From 21c317101fd7537c2d24930480ae0f575af4627d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Feb 2025 23:36:42 +0000 +Subject: usb: gadget: core: flush gadget workqueue after device removal + +From: Roy Luo + +[ 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 +Signed-off-by: Roy Luo +Reviewed-by: Alan Stern +Reviewed-by: Thinh Nguyen +Link: https://lore.kernel.org/r/20250204233642.666991-1-royluo@google.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..1213094707 --- /dev/null +++ b/queue-6.6/usb-gadget-f_midi-f_midi_complete-to-call-queue_work.patch @@ -0,0 +1,42 @@ +From a98d12d8b9f685d102ac335ccdb23a14b5527551 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Feb 2025 10:48:05 -0700 +Subject: USB: gadget: f_midi: f_midi_complete to call queue_work + +From: Jill Donahue + +[ 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 +Signed-off-by: Jill Donahue +Link: https://lore.kernel.org/r/20250211174805.1369265-1-jdonahue@fender.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..9db84d95ee --- /dev/null +++ b/queue-6.6/vsock-bpf-warn-on-socket-without-transport.patch @@ -0,0 +1,53 @@ +From 138910f94064601f4d07ca85ae58ff28a1131a5f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Feb 2025 12:58:50 +0100 +Subject: vsock/bpf: Warn on socket without transport + +From: Michal Luczaj + +[ 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 +Reviewed-by: Stefano Garzarella +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..df1c89708e --- /dev/null +++ b/queue-6.6/xfs-don-t-over-report-free-space-or-inodes-in-statvf.patch @@ -0,0 +1,85 @@ +From b9547623798157fc6bd39157784099cfba9c14ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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: # v2.6.18 +Fixes: 932f2c323196c2 ("[XFS] statvfs component of directory/project quota support, code originally by Glen.") +Reported-by: Emmanuel Florac +Signed-off-by: "Darrick J. Wong" +Reviewed-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..e08391a7a0 --- /dev/null +++ b/queue-6.6/xfs-report-realtime-block-quota-limits-on-realtime-d.patch @@ -0,0 +1,98 @@ +From ee2165c9dda9c04943b6e7d15556e1f60863f178 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 3 Nov 2024 20:19:40 -0800 +Subject: xfs: report realtime block quota limits on realtime directories + +From: Darrick J. Wong + +[ 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 +Reviewed-by: Christoph Hellwig +Stable-dep-of: 4b8d867ca6e2 ("xfs: don't over-report free space or inodes in statvfs") +Signed-off-by: Sasha Levin +--- + 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 + -- 2.47.2