]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.6
authorSasha Levin <sashal@kernel.org>
Fri, 3 Jan 2025 00:40:45 +0000 (19:40 -0500)
committerSasha Levin <sashal@kernel.org>
Fri, 3 Jan 2025 00:40:45 +0000 (19:40 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
114 files changed:
queue-6.6/acpi-iort-add-pmcg-platform-information-for-hisilico.patch [new file with mode: 0644]
queue-6.6/acpi-iort-add-pmcg-platform-information-for-hisilico.patch-10390 [new file with mode: 0644]
queue-6.6/acpi-pcc-add-pcc-shared-memory-region-command-and-st.patch [new file with mode: 0644]
queue-6.6/alsa-ump-don-t-open-legacy-substream-for-an-inactive.patch [new file with mode: 0644]
queue-6.6/alsa-ump-indicate-the-inactive-group-in-legacy-subst.patch [new file with mode: 0644]
queue-6.6/alsa-ump-shut-up-truncated-string-warning.patch [new file with mode: 0644]
queue-6.6/alsa-ump-update-legacy-substream-names-upon-fb-info-.patch [new file with mode: 0644]
queue-6.6/alsa-ump-use-guard-for-locking.patch [new file with mode: 0644]
queue-6.6/bluetooth-add-support-ittim-pe50-m75c.patch [new file with mode: 0644]
queue-6.6/bluetooth-btusb-add-callback-function-in-btusb-suspe.patch [new file with mode: 0644]
queue-6.6/bluetooth-btusb-add-new-vid-pid-0489-e111-for-mt7925.patch [new file with mode: 0644]
queue-6.6/bluetooth-btusb-add-new-vid-pid-13d3-3602-for-mt7925.patch [new file with mode: 0644]
queue-6.6/bluetooth-btusb-add-usb-hw-ids-for-mt7921-mt7922-mt7.patch [new file with mode: 0644]
queue-6.6/bluetooth-btusb-mediatek-add-callback-function-in-bt.patch [new file with mode: 0644]
queue-6.6/bluetooth-hci_conn-reduce-hci_conn_drop-calls-in-two.patch [new file with mode: 0644]
queue-6.6/btrfs-fix-use-after-free-when-cowing-tree-bock-and-t.patch [new file with mode: 0644]
queue-6.6/btrfs-rename-and-export-__btrfs_cow_block.patch [new file with mode: 0644]
queue-6.6/cleanup-add-conditional-guard-support.patch [new file with mode: 0644]
queue-6.6/cleanup-adjust-scoped_guard-macros-to-avoid-potentia.patch [new file with mode: 0644]
queue-6.6/cleanup-remove-address-space-of-returned-pointer.patch [new file with mode: 0644]
queue-6.6/clk-qcom-clk-alpha-pll-add-nss-huayra-alpha-pll-supp.patch [new file with mode: 0644]
queue-6.6/clk-qcom-clk-alpha-pll-add-support-for-zonda-ole-pll.patch [new file with mode: 0644]
queue-6.6/crypto-ecc-prevent-ecc_digits_from_bytes-from-readin.patch [new file with mode: 0644]
queue-6.6/crypto-ecdsa-avoid-signed-integer-overflow-on-signat.patch [new file with mode: 0644]
queue-6.6/crypto-ecdsa-convert-byte-arrays-with-key-coordinate.patch [new file with mode: 0644]
queue-6.6/crypto-ecdsa-rename-keylen-to-bufsize-where-necessar.patch [new file with mode: 0644]
queue-6.6/crypto-ecdsa-use-ecc_digits_from_bytes-to-convert-si.patch [new file with mode: 0644]
queue-6.6/docs-media-update-location-of-the-media-patches.patch [new file with mode: 0644]
queue-6.6/drm-amd-display-fix-dsc-re-computing.patch [new file with mode: 0644]
queue-6.6/drm-amd-display-fix-incorrect-dsc-recompute-trigger.patch [new file with mode: 0644]
queue-6.6/drm-radeon-delay-connector-detecting-when-hpd-singal.patch [new file with mode: 0644]
queue-6.6/ext4-convert-to-new-timestamp-accessors.patch [new file with mode: 0644]
queue-6.6/ext4-partial-zero-eof-block-on-unaligned-inode-size-.patch [new file with mode: 0644]
queue-6.6/fs-ntfs3-fix-warning-in-ni_fiemap.patch [new file with mode: 0644]
queue-6.6/fs-ntfs3-implement-fallocate-for-compressed-files.patch [new file with mode: 0644]
queue-6.6/fs-smb-client-implement-chmod-for-smb3-posix-extensi.patch [new file with mode: 0644]
queue-6.6/i2c-i801-add-support-for-intel-arrow-lake-h.patch [new file with mode: 0644]
queue-6.6/i2c-i801-add-support-for-intel-panther-lake.patch [new file with mode: 0644]
queue-6.6/iio-adc-ad7192-convert-from-of-specific-to-fwnode-pr.patch [new file with mode: 0644]
queue-6.6/iio-adc-ad7192-properly-check-spi_get_device_match_d.patch [new file with mode: 0644]
queue-6.6/mailbox-pcc-add-support-for-platform-notification-ha.patch [new file with mode: 0644]
queue-6.6/mailbox-pcc-check-before-sending-mctp-pcc-response-a.patch [new file with mode: 0644]
queue-6.6/mailbox-pcc-support-shared-interrupt-for-multiple-su.patch [new file with mode: 0644]
queue-6.6/media-uvcvideo-force-uvc-version-to-1.0a-for-0408-40.patch [new file with mode: 0644]
queue-6.6/media-uvcvideo-force-uvc-version-to-1.0a-for-0408-40.patch-10342 [new file with mode: 0644]
queue-6.6/memblock-allow-zero-threshold-in-validate_numa_conve.patch [new file with mode: 0644]
queue-6.6/memblock-make-memblock_set_node-also-warn-about-use-.patch [new file with mode: 0644]
queue-6.6/net-mlx5-unique-names-for-per-device-caches.patch [new file with mode: 0644]
queue-6.6/net-renesas-rswitch-fix-possible-early-skb-release.patch [new file with mode: 0644]
queue-6.6/numa-optimize-detection-of-memory-with-no-node-id-as.patch [new file with mode: 0644]
queue-6.6/nvme-use-helper-nvme_ctrl_state-in-nvme_keep_alive_f.patch [new file with mode: 0644]
queue-6.6/of-address-preserve-the-flags-portion-on-1-1-dma-ran.patch [new file with mode: 0644]
queue-6.6/of-address-remove-duplicated-functions.patch [new file with mode: 0644]
queue-6.6/of-address-store-number-of-bus-flag-cells-rather-tha.patch [new file with mode: 0644]
queue-6.6/platform-x86-mlx-platform-call-pci_dev_put-to-balanc.patch [new file with mode: 0644]
queue-6.6/remoteproc-qcom-pas-add-sc7180-adsp.patch [new file with mode: 0644]
queue-6.6/remoteproc-qcom-pas-add-support-for-sa8775p-adsp-cds.patch [new file with mode: 0644]
queue-6.6/remoteproc-qcom-pas-enable-sar2130p-audio-dsp-suppor.patch [new file with mode: 0644]
queue-6.6/revert-drm-radeon-delay-connector-detecting-when-hpd.patch [new file with mode: 0644]
queue-6.6/revert-nvme-make-keep-alive-synchronous-operation.patch [new file with mode: 0644]
queue-6.6/revert-watchdog-s3c2410_wdt-use-exynos_get_pmu_regma.patch [new file with mode: 0644]
queue-6.6/rust-allow-clippy-needless_lifetimes.patch [new file with mode: 0644]
queue-6.6/rust-relax-most-deny-level-lints-to-warnings.patch [new file with mode: 0644]
queue-6.6/sched-initialize-idle-tasks-only-once.patch [new file with mode: 0644]
queue-6.6/scsi-hisi_sas-allocate-dfx-memory-during-dump-trigge.patch [new file with mode: 0644]
queue-6.6/scsi-hisi_sas-create-all-dump-files-during-debugfs-i.patch [new file with mode: 0644]
queue-6.6/scsi-hisi_sas-directly-call-register-snapshot-instea.patch [new file with mode: 0644]
queue-6.6/scsi-hisi_sas-fix-a-deadlock-issue-related-to-automa.patch [new file with mode: 0644]
queue-6.6/scsi-mpi3mr-start-controller-indexing-from-0.patch [new file with mode: 0644]
queue-6.6/scsi-mpi3mr-use-ida-to-manage-mrioc-id.patch [new file with mode: 0644]
queue-6.6/series [new file with mode: 0644]
queue-6.6/smb-client-fix-use-after-free-of-signing-key.patch [new file with mode: 0644]
queue-6.6/smb-client-rename-cifs_ace-to-smb_ace.patch [new file with mode: 0644]
queue-6.6/smb-client-rename-cifs_acl-to-smb_acl.patch [new file with mode: 0644]
queue-6.6/smb-client-rename-cifs_ntsd-to-smb_ntsd.patch [new file with mode: 0644]
queue-6.6/smb-client-rename-cifs_sid-to-smb_sid.patch [new file with mode: 0644]
queue-6.6/smb-client-stop-flooding-dmesg-in-smb2_calc_signatur.patch [new file with mode: 0644]
queue-6.6/softirq-allow-raising-sched_softirq-from-smp-call-fu.patch [new file with mode: 0644]
queue-6.6/thunderbolt-add-support-for-intel-lunar-lake.patch [new file with mode: 0644]
queue-6.6/thunderbolt-add-support-for-intel-panther-lake-m-p.patch [new file with mode: 0644]
queue-6.6/thunderbolt-don-t-display-nvm_version-unless-upgrade.patch [new file with mode: 0644]
queue-6.6/udf-verify-inode-link-counts-before-performing-renam.patch [new file with mode: 0644]
queue-6.6/udf_rename-only-access-the-child-content-on-cross-di.patch [new file with mode: 0644]
queue-6.6/usb-chipidea-add-ci_hdrc_force_vbus_active_always-fl.patch [new file with mode: 0644]
queue-6.6/usb-chipidea-add-ci_hdrc_has_short_pkt_limit-flag.patch [new file with mode: 0644]
queue-6.6/usb-chipidea-udc-limit-usb-request-length-to-max-16k.patch [new file with mode: 0644]
queue-6.6/usb-dwc3-gadget-add-missing-check-for-single-port-ra.patch [new file with mode: 0644]
queue-6.6/usb-typec-ucsi-add-callback-for-connector-status-upd.patch [new file with mode: 0644]
queue-6.6/usb-typec-ucsi-add-update_connector-callback.patch [new file with mode: 0644]
queue-6.6/usb-typec-ucsi-glink-be-more-precise-on-orientation-.patch [new file with mode: 0644]
queue-6.6/usb-typec-ucsi-glink-fix-off-by-one-in-connector_sta.patch [new file with mode: 0644]
queue-6.6/usb-typec-ucsi-glink-move-gpio-reading-into-connecto.patch [new file with mode: 0644]
queue-6.6/usb-typec-ucsi-glink-set-orientation-aware-if-suppor.patch [new file with mode: 0644]
queue-6.6/usb-xhci-avoid-queuing-redundant-stop-endpoint-comma.patch [new file with mode: 0644]
queue-6.6/usb-xhci-limit-stop-endpoint-retries.patch [new file with mode: 0644]
queue-6.6/watchdog-rzg2l_wdt-power-on-the-watchdog-domain-in-t.patch [new file with mode: 0644]
queue-6.6/watchdog-rzg2l_wdt-rely-on-the-reset-driver-for-doin.patch [new file with mode: 0644]
queue-6.6/watchdog-rzg2l_wdt-remove-reset-de-assert-from-probe.patch [new file with mode: 0644]
queue-6.6/watchdog-s3c2410_wdt-use-exynos_get_pmu_regmap_by_ph.patch [new file with mode: 0644]
queue-6.6/wifi-ath10k-avoid-null-pointer-error-during-sdio-rem.patch [new file with mode: 0644]
queue-6.6/wifi-ath10k-update-qualcomm-innovation-center-inc.-c.patch [new file with mode: 0644]
queue-6.6/wifi-ath12k-fix-atomic-calls-in-ath12k_mac_op_set_bi.patch [new file with mode: 0644]
queue-6.6/wifi-ath12k-optimize-the-mac80211-hw-data-access.patch [new file with mode: 0644]
queue-6.6/wifi-mac80211-add-non-atomic-station-iterator.patch [new file with mode: 0644]
queue-6.6/wifi-mac80211-export-ieee80211_purge_tx_queue-for-dr.patch [new file with mode: 0644]
queue-6.6/wifi-rtw88-use-ieee80211_purge_tx_queue-to-purge-tx-.patch [new file with mode: 0644]
queue-6.6/x86-crash-wrap-crash-dumping-code-into-crash-related.patch [new file with mode: 0644]
queue-6.6/x86-fred-clear-wfe-in-missing-endbranch-cps.patch [new file with mode: 0644]
queue-6.6/x86-hyperv-fix-hv-tsc-page-based-sched_clock-for-hib.patch [new file with mode: 0644]
queue-6.6/x86-mm-carve-out-invlpg-inline-asm-for-use-by-others.patch [new file with mode: 0644]
queue-6.6/x86-ptrace-add-fred-additional-information-to-the-pt.patch [new file with mode: 0644]
queue-6.6/x86-ptrace-cleanup-the-definition-of-the-pt_regs-str.patch [new file with mode: 0644]
queue-6.6/xhci-retry-stop-endpoint-on-buggy-nec-controllers.patch [new file with mode: 0644]
queue-6.6/xhci-turn-nec-specific-quirk-for-handling-stop-endpo.patch [new file with mode: 0644]

diff --git a/queue-6.6/acpi-iort-add-pmcg-platform-information-for-hisilico.patch b/queue-6.6/acpi-iort-add-pmcg-platform-information-for-hisilico.patch
new file mode 100644 (file)
index 0000000..13209b0
--- /dev/null
@@ -0,0 +1,61 @@
+From f722ad002a20ec14ae8d61938daa7e7eec0db911 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jul 2024 17:26:58 +0800
+Subject: ACPI/IORT: Add PMCG platform information for HiSilicon HIP10/11
+
+From: Yicong Yang <yangyicong@hisilicon.com>
+
+[ Upstream commit f3b78b470f28bb2a3a40e88bdf5c6de6a35a9b76 ]
+
+HiSilicon HIP10/11 platforms using the same SMMU PMCG with HIP09
+and thus suffers the same erratum. List them in the PMCG platform
+information list without introducing a new SMMU PMCG Model.
+
+Update the silicon-errata.rst as well.
+
+Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
+Link: https://lore.kernel.org/r/20240731092658.11012-1-yangyicong@huawei.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Stable-dep-of: c2b46ae02270 ("ACPI/IORT: Add PMCG platform information for HiSilicon HIP09A")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/arch/arm64/silicon-errata.rst | 4 ++--
+ drivers/acpi/arm64/iort.c                   | 7 +++++++
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
+index 3cf806733083..f4e6afd59630 100644
+--- a/Documentation/arch/arm64/silicon-errata.rst
++++ b/Documentation/arch/arm64/silicon-errata.rst
+@@ -244,8 +244,8 @@ stable kernels.
+ +----------------+-----------------+-----------------+-----------------------------+
+ | Hisilicon      | Hip08 SMMU PMCG | #162001800      | N/A                         |
+ +----------------+-----------------+-----------------+-----------------------------+
+-| Hisilicon      | Hip08 SMMU PMCG | #162001900      | N/A                         |
+-|                | Hip09 SMMU PMCG |                 |                             |
++| Hisilicon      | Hip{08,09,10,10C| #162001900      | N/A                         |
++|                | ,11} SMMU PMCG  |                 |                             |
+ +----------------+-----------------+-----------------+-----------------------------+
+ +----------------+-----------------+-----------------+-----------------------------+
+ | Qualcomm Tech. | Kryo/Falkor v1  | E1003           | QCOM_FALKOR_ERRATUM_1003    |
+diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
+index 6496ff5a6ba2..b1f483845bc0 100644
+--- a/drivers/acpi/arm64/iort.c
++++ b/drivers/acpi/arm64/iort.c
+@@ -1712,6 +1712,13 @@ static struct acpi_platform_list pmcg_plat_info[] __initdata = {
+       /* HiSilicon Hip09 Platform */
+       {"HISI  ", "HIP09   ", 0, ACPI_SIG_IORT, greater_than_or_equal,
+        "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
++      /* HiSilicon Hip10/11 Platform uses the same SMMU IP with Hip09 */
++      {"HISI  ", "HIP10   ", 0, ACPI_SIG_IORT, greater_than_or_equal,
++       "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
++      {"HISI  ", "HIP10C  ", 0, ACPI_SIG_IORT, greater_than_or_equal,
++       "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
++      {"HISI  ", "HIP11   ", 0, ACPI_SIG_IORT, greater_than_or_equal,
++       "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
+       { }
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.6/acpi-iort-add-pmcg-platform-information-for-hisilico.patch-10390 b/queue-6.6/acpi-iort-add-pmcg-platform-information-for-hisilico.patch-10390
new file mode 100644 (file)
index 0000000..02bdb87
--- /dev/null
@@ -0,0 +1,58 @@
+From 219e4ff0f335a4c1ca2acb07031a441597094b69 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Dec 2024 09:33:31 +0800
+Subject: ACPI/IORT: Add PMCG platform information for HiSilicon HIP09A
+
+From: Qinxin Xia <xiaqinxin@huawei.com>
+
+[ Upstream commit c2b46ae022704a2d845e59461fa24431ad627022 ]
+
+HiSilicon HIP09A platforms using the same SMMU PMCG with HIP09
+and thus suffers the same erratum. List them in the PMCG platform
+information list without introducing a new SMMU PMCG Model.
+
+Update the silicon-errata.rst as well.
+
+Reviewed-by: Yicong Yang <yangyicong@hisilicon.com>
+Acked-by: Hanjun Guo <guohanjun@huawei.com>
+Signed-off-by: Qinxin Xia <xiaqinxin@huawei.com>
+Link: https://lore.kernel.org/r/20241205013331.1484017-1-xiaqinxin@huawei.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/arch/arm64/silicon-errata.rst | 5 +++--
+ drivers/acpi/arm64/iort.c                   | 2 ++
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
+index f4e6afd59630..8209c7a7c397 100644
+--- a/Documentation/arch/arm64/silicon-errata.rst
++++ b/Documentation/arch/arm64/silicon-errata.rst
+@@ -244,8 +244,9 @@ stable kernels.
+ +----------------+-----------------+-----------------+-----------------------------+
+ | Hisilicon      | Hip08 SMMU PMCG | #162001800      | N/A                         |
+ +----------------+-----------------+-----------------+-----------------------------+
+-| Hisilicon      | Hip{08,09,10,10C| #162001900      | N/A                         |
+-|                | ,11} SMMU PMCG  |                 |                             |
++| Hisilicon      | Hip{08,09,09A,10| #162001900      | N/A                         |
++|                | ,10C,11}        |                 |                             |
++|                | SMMU PMCG       |                 |                             |
+ +----------------+-----------------+-----------------+-----------------------------+
+ +----------------+-----------------+-----------------+-----------------------------+
+ | Qualcomm Tech. | Kryo/Falkor v1  | E1003           | QCOM_FALKOR_ERRATUM_1003    |
+diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
+index b1f483845bc0..1a31106a14e4 100644
+--- a/drivers/acpi/arm64/iort.c
++++ b/drivers/acpi/arm64/iort.c
+@@ -1712,6 +1712,8 @@ static struct acpi_platform_list pmcg_plat_info[] __initdata = {
+       /* HiSilicon Hip09 Platform */
+       {"HISI  ", "HIP09   ", 0, ACPI_SIG_IORT, greater_than_or_equal,
+        "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
++      {"HISI  ", "HIP09A  ", 0, ACPI_SIG_IORT, greater_than_or_equal,
++       "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
+       /* HiSilicon Hip10/11 Platform uses the same SMMU IP with Hip09 */
+       {"HISI  ", "HIP10   ", 0, ACPI_SIG_IORT, greater_than_or_equal,
+        "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
+-- 
+2.39.5
+
diff --git a/queue-6.6/acpi-pcc-add-pcc-shared-memory-region-command-and-st.patch b/queue-6.6/acpi-pcc-add-pcc-shared-memory-region-command-and-st.patch
new file mode 100644 (file)
index 0000000..2e75b48
--- /dev/null
@@ -0,0 +1,53 @@
+From 1e4eaa4ab92e9c9b056cc896f4733608baaa67c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Sep 2023 17:26:10 +0100
+Subject: ACPI: PCC: Add PCC shared memory region command and status bitfields
+
+From: Sudeep Holla <sudeep.holla@arm.com>
+
+[ Upstream commit 55d235ebb684b993b3247740c1c8e273f8af4a54 ]
+
+Define the common macros to use when referring to various bitfields in
+the PCC generic communications channel command and status fields.
+
+Currently different drivers that need to use these bitfields have defined
+these locally. This common macro is intended to consolidate and replace
+those.
+
+Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+Link: https://lore.kernel.org/r/20230927-pcc_defines-v2-1-0b8ffeaef2e5@arm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Stable-dep-of: 7f9e19f207be ("mailbox: pcc: Check before sending MCTP PCC response ACK")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/acpi/pcc.h | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/include/acpi/pcc.h b/include/acpi/pcc.h
+index 73e806fe7ce7..9b373d172a77 100644
+--- a/include/acpi/pcc.h
++++ b/include/acpi/pcc.h
+@@ -18,7 +18,20 @@ struct pcc_mbox_chan {
+       u16 min_turnaround_time;
+ };
++/* Generic Communications Channel Shared Memory Region */
++#define PCC_SIGNATURE                 0x50434300
++/* Generic Communications Channel Command Field */
++#define PCC_CMD_GENERATE_DB_INTR      BIT(15)
++/* Generic Communications Channel Status Field */
++#define PCC_STATUS_CMD_COMPLETE               BIT(0)
++#define PCC_STATUS_SCI_DOORBELL               BIT(1)
++#define PCC_STATUS_ERROR              BIT(2)
++#define PCC_STATUS_PLATFORM_NOTIFY    BIT(3)
++/* Initiator Responder Communications Channel Flags */
++#define PCC_CMD_COMPLETION_NOTIFY     BIT(0)
++
+ #define MAX_PCC_SUBSPACES     256
++
+ #ifdef CONFIG_PCC
+ extern struct pcc_mbox_chan *
+ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id);
+-- 
+2.39.5
+
diff --git a/queue-6.6/alsa-ump-don-t-open-legacy-substream-for-an-inactive.patch b/queue-6.6/alsa-ump-don-t-open-legacy-substream-for-an-inactive.patch
new file mode 100644 (file)
index 0000000..a5bd16c
--- /dev/null
@@ -0,0 +1,36 @@
+From d430bff8d1ad1c55b9a166d2f135161b1856a410 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Nov 2024 10:45:42 +0100
+Subject: ALSA: ump: Don't open legacy substream for an inactive group
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 3978d53df7236f0a517c2abeb43ddf6ac162cdd8 ]
+
+When a UMP Group is inactive, we shouldn't allow users to access it
+via the legacy MIDI access.  Add the group active flag check and
+return -ENODEV if it's inactive.
+
+Link: https://patch.msgid.link/20241129094546.32119-2-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/core/ump.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/core/ump.c b/sound/core/ump.c
+index ada2625ce78f..5a4a7d0b7cca 100644
+--- a/sound/core/ump.c
++++ b/sound/core/ump.c
+@@ -1081,6 +1081,8 @@ static int snd_ump_legacy_open(struct snd_rawmidi_substream *substream)
+       guard(mutex)(&ump->open_mutex);
+       if (ump->legacy_substreams[dir][group])
+               return -EBUSY;
++      if (!ump->groups[group].active)
++              return -ENODEV;
+       if (dir == SNDRV_RAWMIDI_STREAM_OUTPUT) {
+               if (!ump->legacy_out_opens) {
+                       err = snd_rawmidi_kernel_open(&ump->core, 0,
+-- 
+2.39.5
+
diff --git a/queue-6.6/alsa-ump-indicate-the-inactive-group-in-legacy-subst.patch b/queue-6.6/alsa-ump-indicate-the-inactive-group-in-legacy-subst.patch
new file mode 100644 (file)
index 0000000..b460a5e
--- /dev/null
@@ -0,0 +1,39 @@
+From 975842b3cc61445f192b393fb47d43772a8ad954 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Nov 2024 10:45:43 +0100
+Subject: ALSA: ump: Indicate the inactive group in legacy substream names
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit e29e504e7890b9ee438ca6370d0180d607c473f9 ]
+
+Since the legacy rawmidi has no proper way to know the inactive group,
+indicate it in the rawmidi substream names with "[Inactive]" suffix
+when the corresponding UMP group is inactive.
+
+Link: https://patch.msgid.link/20241129094546.32119-3-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/core/ump.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/sound/core/ump.c b/sound/core/ump.c
+index 5a4a7d0b7cca..bb94f119869a 100644
+--- a/sound/core/ump.c
++++ b/sound/core/ump.c
+@@ -1245,8 +1245,9 @@ static void fill_substream_names(struct snd_ump_endpoint *ump,
+               name = ump->groups[idx].name;
+               if (!*name)
+                       name = ump->info.name;
+-              snprintf(s->name, sizeof(s->name), "Group %d (%.16s)",
+-                       idx + 1, name);
++              snprintf(s->name, sizeof(s->name), "Group %d (%.16s)%s",
++                       idx + 1, name,
++                       ump->groups[idx].active ? "" : " [Inactive]");
+       }
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.6/alsa-ump-shut-up-truncated-string-warning.patch b/queue-6.6/alsa-ump-shut-up-truncated-string-warning.patch
new file mode 100644 (file)
index 0000000..fca16cc
--- /dev/null
@@ -0,0 +1,44 @@
+From 43291c3b4ed4e1a1b0cdfdad881faada94da2d8a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 Nov 2024 10:00:08 +0100
+Subject: ALSA: ump: Shut up truncated string warning
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit ed990c07af70d286f5736021c6e25d8df6f2f7b0 ]
+
+The recent change for the legacy substream name update brought a
+compile warning for some compilers due to the nature of snprintf().
+Use scnprintf() to shut up the warning since the truncation is
+intentional.
+
+Fixes: e29e504e7890 ("ALSA: ump: Indicate the inactive group in legacy substream names")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202411300103.FrGuTAYp-lkp@intel.com/
+Link: https://patch.msgid.link/20241130090009.19849-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/core/ump.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/sound/core/ump.c b/sound/core/ump.c
+index 4aec90dac07e..32d27e58416a 100644
+--- a/sound/core/ump.c
++++ b/sound/core/ump.c
+@@ -1251,9 +1251,9 @@ static void fill_substream_names(struct snd_ump_endpoint *ump,
+               name = ump->groups[idx].name;
+               if (!*name)
+                       name = ump->info.name;
+-              snprintf(s->name, sizeof(s->name), "Group %d (%.16s)%s",
+-                       idx + 1, name,
+-                       ump->groups[idx].active ? "" : " [Inactive]");
++              scnprintf(s->name, sizeof(s->name), "Group %d (%.16s)%s",
++                        idx + 1, name,
++                        ump->groups[idx].active ? "" : " [Inactive]");
+       }
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.6/alsa-ump-update-legacy-substream-names-upon-fb-info-.patch b/queue-6.6/alsa-ump-update-legacy-substream-names-upon-fb-info-.patch
new file mode 100644 (file)
index 0000000..90293ee
--- /dev/null
@@ -0,0 +1,87 @@
+From 5182d79632c10ae484000c014ca9b83dab075f71 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Nov 2024 10:45:44 +0100
+Subject: ALSA: ump: Update legacy substream names upon FB info update
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit edad3f9519fcacb926d0e3f3217aecaf628a593f ]
+
+The legacy rawmidi substreams should be updated when UMP FB Info or
+UMP FB Name are received, too.
+
+Link: https://patch.msgid.link/20241129094546.32119-4-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/core/ump.c | 19 +++++++++++++++----
+ 1 file changed, 15 insertions(+), 4 deletions(-)
+
+diff --git a/sound/core/ump.c b/sound/core/ump.c
+index bb94f119869a..4aec90dac07e 100644
+--- a/sound/core/ump.c
++++ b/sound/core/ump.c
+@@ -37,6 +37,7 @@ static int process_legacy_output(struct snd_ump_endpoint *ump,
+                                u32 *buffer, int count);
+ static void process_legacy_input(struct snd_ump_endpoint *ump, const u32 *src,
+                                int words);
++static void update_legacy_names(struct snd_ump_endpoint *ump);
+ #else
+ static inline int process_legacy_output(struct snd_ump_endpoint *ump,
+                                       u32 *buffer, int count)
+@@ -47,6 +48,9 @@ static inline void process_legacy_input(struct snd_ump_endpoint *ump,
+                                       const u32 *src, int words)
+ {
+ }
++static inline void update_legacy_names(struct snd_ump_endpoint *ump)
++{
++}
+ #endif
+ static const struct snd_rawmidi_global_ops snd_ump_rawmidi_ops = {
+@@ -850,6 +854,7 @@ static int ump_handle_fb_info_msg(struct snd_ump_endpoint *ump,
+               fill_fb_info(ump, &fb->info, buf);
+               if (ump->parsed) {
+                       snd_ump_update_group_attrs(ump);
++                      update_legacy_names(ump);
+                       seq_notify_fb_change(ump, fb);
+               }
+       }
+@@ -882,6 +887,7 @@ static int ump_handle_fb_name_msg(struct snd_ump_endpoint *ump,
+       /* notify the FB name update to sequencer, too */
+       if (ret > 0 && ump->parsed) {
+               snd_ump_update_group_attrs(ump);
++              update_legacy_names(ump);
+               seq_notify_fb_change(ump, fb);
+       }
+       return ret;
+@@ -1251,6 +1257,14 @@ static void fill_substream_names(struct snd_ump_endpoint *ump,
+       }
+ }
++static void update_legacy_names(struct snd_ump_endpoint *ump)
++{
++      struct snd_rawmidi *rmidi = ump->legacy_rmidi;
++
++      fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_INPUT);
++      fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT);
++}
++
+ int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump,
+                                 char *id, int device)
+ {
+@@ -1287,10 +1301,7 @@ int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump,
+       rmidi->ops = &snd_ump_legacy_ops;
+       rmidi->private_data = ump;
+       ump->legacy_rmidi = rmidi;
+-      if (input)
+-              fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_INPUT);
+-      if (output)
+-              fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT);
++      update_legacy_names(ump);
+       ump_dbg(ump, "Created a legacy rawmidi #%d (%s)\n", device, id);
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.6/alsa-ump-use-guard-for-locking.patch b/queue-6.6/alsa-ump-use-guard-for-locking.patch
new file mode 100644 (file)
index 0000000..2772726
--- /dev/null
@@ -0,0 +1,129 @@
+From 891e572af18fce844430490b2c019dd6f6d30022 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Feb 2024 09:52:43 +0100
+Subject: ALSA: ump: Use guard() for locking
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 631896f7eaaf8cf8c639b065d3c9fbaa66da5d32 ]
+
+We can simplify the code gracefully with new guard() macro and co for
+automatic cleanup of locks.
+
+Only the code refactoring, and no functional changes.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/20240227085306.9764-2-tiwai@suse.de
+Stable-dep-of: 3978d53df723 ("ALSA: ump: Don't open legacy substream for an inactive group")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/core/ump.c | 35 ++++++++++++-----------------------
+ 1 file changed, 12 insertions(+), 23 deletions(-)
+
+diff --git a/sound/core/ump.c b/sound/core/ump.c
+index 83856b2f88b8..ada2625ce78f 100644
+--- a/sound/core/ump.c
++++ b/sound/core/ump.c
+@@ -1076,13 +1076,11 @@ static int snd_ump_legacy_open(struct snd_rawmidi_substream *substream)
+       struct snd_ump_endpoint *ump = substream->rmidi->private_data;
+       int dir = substream->stream;
+       int group = ump->legacy_mapping[substream->number];
+-      int err = 0;
++      int err;
+-      mutex_lock(&ump->open_mutex);
+-      if (ump->legacy_substreams[dir][group]) {
+-              err = -EBUSY;
+-              goto unlock;
+-      }
++      guard(mutex)(&ump->open_mutex);
++      if (ump->legacy_substreams[dir][group])
++              return -EBUSY;
+       if (dir == SNDRV_RAWMIDI_STREAM_OUTPUT) {
+               if (!ump->legacy_out_opens) {
+                       err = snd_rawmidi_kernel_open(&ump->core, 0,
+@@ -1090,17 +1088,14 @@ static int snd_ump_legacy_open(struct snd_rawmidi_substream *substream)
+                                                     SNDRV_RAWMIDI_LFLG_APPEND,
+                                                     &ump->legacy_out_rfile);
+                       if (err < 0)
+-                              goto unlock;
++                              return err;
+               }
+               ump->legacy_out_opens++;
+               snd_ump_convert_reset(&ump->out_cvts[group]);
+       }
+-      spin_lock_irq(&ump->legacy_locks[dir]);
++      guard(spinlock_irq)(&ump->legacy_locks[dir]);
+       ump->legacy_substreams[dir][group] = substream;
+-      spin_unlock_irq(&ump->legacy_locks[dir]);
+- unlock:
+-      mutex_unlock(&ump->open_mutex);
+-      return err;
++      return 0;
+ }
+ static int snd_ump_legacy_close(struct snd_rawmidi_substream *substream)
+@@ -1109,15 +1104,13 @@ static int snd_ump_legacy_close(struct snd_rawmidi_substream *substream)
+       int dir = substream->stream;
+       int group = ump->legacy_mapping[substream->number];
+-      mutex_lock(&ump->open_mutex);
+-      spin_lock_irq(&ump->legacy_locks[dir]);
+-      ump->legacy_substreams[dir][group] = NULL;
+-      spin_unlock_irq(&ump->legacy_locks[dir]);
++      guard(mutex)(&ump->open_mutex);
++      scoped_guard(spinlock_irq, &ump->legacy_locks[dir])
++              ump->legacy_substreams[dir][group] = NULL;
+       if (dir == SNDRV_RAWMIDI_STREAM_OUTPUT) {
+               if (!--ump->legacy_out_opens)
+                       snd_rawmidi_kernel_release(&ump->legacy_out_rfile);
+       }
+-      mutex_unlock(&ump->open_mutex);
+       return 0;
+ }
+@@ -1169,12 +1162,11 @@ static int process_legacy_output(struct snd_ump_endpoint *ump,
+       const int dir = SNDRV_RAWMIDI_STREAM_OUTPUT;
+       unsigned char c;
+       int group, size = 0;
+-      unsigned long flags;
+       if (!ump->out_cvts || !ump->legacy_out_opens)
+               return 0;
+-      spin_lock_irqsave(&ump->legacy_locks[dir], flags);
++      guard(spinlock_irqsave)(&ump->legacy_locks[dir]);
+       for (group = 0; group < SNDRV_UMP_MAX_GROUPS; group++) {
+               substream = ump->legacy_substreams[dir][group];
+               if (!substream)
+@@ -1190,7 +1182,6 @@ static int process_legacy_output(struct snd_ump_endpoint *ump,
+                       break;
+               }
+       }
+-      spin_unlock_irqrestore(&ump->legacy_locks[dir], flags);
+       return size;
+ }
+@@ -1200,18 +1191,16 @@ static void process_legacy_input(struct snd_ump_endpoint *ump, const u32 *src,
+       struct snd_rawmidi_substream *substream;
+       unsigned char buf[16];
+       unsigned char group;
+-      unsigned long flags;
+       const int dir = SNDRV_RAWMIDI_STREAM_INPUT;
+       int size;
+       size = snd_ump_convert_from_ump(src, buf, &group);
+       if (size <= 0)
+               return;
+-      spin_lock_irqsave(&ump->legacy_locks[dir], flags);
++      guard(spinlock_irqsave)(&ump->legacy_locks[dir]);
+       substream = ump->legacy_substreams[dir][group];
+       if (substream)
+               snd_rawmidi_receive(substream, buf, size);
+-      spin_unlock_irqrestore(&ump->legacy_locks[dir], flags);
+ }
+ /* Fill ump->legacy_mapping[] for groups to be used for legacy rawmidi */
+-- 
+2.39.5
+
diff --git a/queue-6.6/bluetooth-add-support-ittim-pe50-m75c.patch b/queue-6.6/bluetooth-add-support-ittim-pe50-m75c.patch
new file mode 100644 (file)
index 0000000..c680ac5
--- /dev/null
@@ -0,0 +1,73 @@
+From 184b333323b8b36407b7bdf782d4aef6849afc89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Sep 2023 16:31:47 +0800
+Subject: Bluetooth: Add support ITTIM PE50-M75C
+
+From: Jingyang Wang <wjy7717@126.com>
+
+[ Upstream commit 00b1c3c4b682ba4b4f9fc46e047b537e668576af ]
+
+-Device(35f5:7922) from /sys/kernel/debug/usb/devices
+P:  Vendor=35f5 ProdID=7922 Rev= 1.00
+S:  Manufacturer=MediaTek Inc.
+S:  Product=Wireless_Device
+S:  SerialNumber=000000000
+C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
+A:  FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01
+I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=125us
+E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
+I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=   9 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=   9 Ivl=1ms
+I:  If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  17 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  17 Ivl=1ms
+I:  If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  25 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  25 Ivl=1ms
+I:  If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  33 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  33 Ivl=1ms
+I:  If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  49 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  49 Ivl=1ms
+I:  If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  63 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  63 Ivl=1ms
+I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
+E:  Ad=8a(I) Atr=03(Int.) MxPS=  64 Ivl=125us
+E:  Ad=0a(O) Atr=03(Int.) MxPS=  64 Ivl=125us
+I:  If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
+E:  Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us
+E:  Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us
+
+Signed-off-by: Jingyang Wang <wjy7717@126.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: faa5fd605d20 ("Bluetooth: btusb: Add new VID/PID 0489/e111 for MT7925")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index fe5e30662017..6b0d9d9f3004 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -658,6 +658,9 @@ static const struct usb_device_id quirks_table[] = {
+       { USB_DEVICE(0x04ca, 0x3804), .driver_info = BTUSB_MEDIATEK |
+                                                    BTUSB_WIDEBAND_SPEECH |
+                                                    BTUSB_VALID_LE_STATES },
++      { USB_DEVICE(0x35f5, 0x7922), .driver_info = BTUSB_MEDIATEK |
++                                                   BTUSB_WIDEBAND_SPEECH |
++                                                   BTUSB_VALID_LE_STATES },
+       /* Additional Realtek 8723AE Bluetooth devices */
+       { USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK },
+-- 
+2.39.5
+
diff --git a/queue-6.6/bluetooth-btusb-add-callback-function-in-btusb-suspe.patch b/queue-6.6/bluetooth-btusb-add-callback-function-in-btusb-suspe.patch
new file mode 100644 (file)
index 0000000..fcf929b
--- /dev/null
@@ -0,0 +1,60 @@
+From f9068b5e32f698660cc1771b504d36044afe34b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jul 2024 14:01:12 +0800
+Subject: Bluetooth: btusb: add callback function in btusb suspend/resume
+
+From: Chris Lu <chris.lu@mediatek.com>
+
+[ Upstream commit 95f92928ad2215b5f524903e67eebd8e14f99564 ]
+
+Add suspend/resum callback function in btusb_data which are reserved
+for vendor specific usage during suspend/resume. hdev->suspend will be
+added before stop traffic in btusb_suspend and hdev-> resume will be
+added after resubmit urb in btusb_resume.
+
+Signed-off-by: Chris Lu <chris.lu@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: cea1805f165c ("Bluetooth: btusb: mediatek: add callback function in btusb_disconnect")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 67577933835f..19d371aa8317 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -892,6 +892,9 @@ struct btusb_data {
+       int (*setup_on_usb)(struct hci_dev *hdev);
++      int (*suspend)(struct hci_dev *hdev);
++      int (*resume)(struct hci_dev *hdev);
++
+       int oob_wake_irq;   /* irq for out-of-band wake-on-bt */
+       unsigned cmd_timeout_cnt;
+@@ -4691,6 +4694,9 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
+       cancel_work_sync(&data->work);
++      if (data->suspend)
++              data->suspend(data->hdev);
++
+       btusb_stop_traffic(data);
+       usb_kill_anchored_urbs(&data->tx_anchor);
+@@ -4794,6 +4800,9 @@ static int btusb_resume(struct usb_interface *intf)
+                       btusb_submit_isoc_urb(hdev, GFP_NOIO);
+       }
++      if (data->resume)
++              data->resume(hdev);
++
+       spin_lock_irq(&data->txlock);
+       play_deferred(data);
+       clear_bit(BTUSB_SUSPENDING, &data->flags);
+-- 
+2.39.5
+
diff --git a/queue-6.6/bluetooth-btusb-add-new-vid-pid-0489-e111-for-mt7925.patch b/queue-6.6/bluetooth-btusb-add-new-vid-pid-0489-e111-for-mt7925.patch
new file mode 100644 (file)
index 0000000..e968ada
--- /dev/null
@@ -0,0 +1,77 @@
+From b64aa42650bf5ef9023d886e77c0ee886c348c87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Oct 2024 11:18:18 +0800
+Subject: Bluetooth: btusb: Add new VID/PID 0489/e111 for MT7925
+
+From: Hao Qin <hao.qin@mediatek.com>
+
+[ Upstream commit faa5fd605d2081b6c9fa2355b59582d4ccd24b16 ]
+
+Add VID 0489 & PID e111 for MediaTek MT7925 USB Bluetooth chip.
+
+The information in /sys/kernel/debug/usb/devices about the Bluetooth
+device is listed as the below.
+
+T:  Bus=02 Lev=02 Prnt=02 Port=04 Cnt=02 Dev#=  4 Spd=480  MxCh= 0
+D:  Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
+P:  Vendor=0489 ProdID=e111 Rev= 1.00
+S:  Manufacturer=MediaTek Inc.
+S:  Product=Wireless_Device
+S:  SerialNumber=000000000
+C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
+A:  FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01
+I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=125us
+E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
+I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=   9 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=   9 Ivl=1ms
+I:  If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  17 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  17 Ivl=1ms
+I:  If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  25 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  25 Ivl=1ms
+I:  If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  33 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  33 Ivl=1ms
+I:  If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  49 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  49 Ivl=1ms
+I:  If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  63 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  63 Ivl=1ms
+I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
+E:  Ad=8a(I) Atr=03(Int.) MxPS=  64 Ivl=125us
+E:  Ad=0a(O) Atr=03(Int.) MxPS=  64 Ivl=125us
+I:  If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
+E:  Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us
+E:  Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us
+
+Signed-off-by: Hao Qin <hao.qin@mediatek.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index dc0bba7f4028..67577933835f 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -681,6 +681,8 @@ static const struct usb_device_id quirks_table[] = {
+                                                    BTUSB_VALID_LE_STATES },
+       /* Additional MediaTek MT7925 Bluetooth devices */
++      { USB_DEVICE(0x0489, 0xe111), .driver_info = BTUSB_MEDIATEK |
++                                                   BTUSB_WIDEBAND_SPEECH },
+       { USB_DEVICE(0x0489, 0xe113), .driver_info = BTUSB_MEDIATEK |
+                                                    BTUSB_WIDEBAND_SPEECH |
+                                                    BTUSB_VALID_LE_STATES },
+-- 
+2.39.5
+
diff --git a/queue-6.6/bluetooth-btusb-add-new-vid-pid-13d3-3602-for-mt7925.patch b/queue-6.6/bluetooth-btusb-add-new-vid-pid-13d3-3602-for-mt7925.patch
new file mode 100644 (file)
index 0000000..9522e7f
--- /dev/null
@@ -0,0 +1,82 @@
+From b1df58d95e1d8cc079b8f4953566371ddb663fef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 Jan 2024 15:27:38 +0800
+Subject: Bluetooth: btusb: Add new VID/PID 13d3/3602 for MT7925
+
+From: Ulrik Strid <ulrik@strid.tech>
+
+[ Upstream commit 560ff4bc99070bfb493018b6b7045af269a008a4 ]
+
+Add VID 13d3 & PID 3602 for MediaTek MT7925 USB Bluetooth chip.
+
+The information in /sys/kernel/debug/usb/devices about the Bluetooth
+device is listed as the below.
+
+T:  Bus=07 Lev=01 Prnt=01 Port=10 Cnt=02 Dev#=  2 Spd=480  MxCh= 0
+D:  Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
+P:  Vendor=13d3 ProdID=3602 Rev= 1.00
+S:  Manufacturer=MediaTek Inc.
+S:  Product=Wireless_Device
+S:  SerialNumber=000000000
+C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
+A:  FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01
+I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=125us
+E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
+I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=   9 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=   9 Ivl=1ms
+I:  If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  17 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  17 Ivl=1ms
+I:  If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  25 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  25 Ivl=1ms
+I:  If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  33 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  33 Ivl=1ms
+I:  If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  49 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  49 Ivl=1ms
+I:  If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  63 Ivl=1ms
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  63 Ivl=1ms
+I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
+E:  Ad=8a(I) Atr=03(Int.) MxPS=  64 Ivl=125us
+E:  Ad=0a(O) Atr=03(Int.) MxPS=  64 Ivl=125us
+I:  If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
+E:  Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us
+E:  Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us
+
+Signed-off-by: Ulrik Strid <ulrik@strid.tech>
+Signed-off-by: Deren Wu <deren.wu@mediatek.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: faa5fd605d20 ("Bluetooth: btusb: Add new VID/PID 0489/e111 for MT7925")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 6b0d9d9f3004..fd57a02046ae 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -662,6 +662,11 @@ static const struct usb_device_id quirks_table[] = {
+                                                    BTUSB_WIDEBAND_SPEECH |
+                                                    BTUSB_VALID_LE_STATES },
++      /* Additional MediaTek MT7925 Bluetooth devices */
++      { USB_DEVICE(0x13d3, 0x3602), .driver_info = BTUSB_MEDIATEK |
++                                                   BTUSB_WIDEBAND_SPEECH |
++                                                   BTUSB_VALID_LE_STATES },
++
+       /* Additional Realtek 8723AE Bluetooth devices */
+       { USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK },
+       { USB_DEVICE(0x13d3, 0x3394), .driver_info = BTUSB_REALTEK },
+-- 
+2.39.5
+
diff --git a/queue-6.6/bluetooth-btusb-add-usb-hw-ids-for-mt7921-mt7922-mt7.patch b/queue-6.6/bluetooth-btusb-add-usb-hw-ids-for-mt7921-mt7922-mt7.patch
new file mode 100644 (file)
index 0000000..c0704bb
--- /dev/null
@@ -0,0 +1,73 @@
+From dbdcdcf08d4fbde15da656d08ba5f5ba92933c88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Apr 2024 14:51:56 +0800
+Subject: Bluetooth: btusb: Add USB HW IDs for MT7921/MT7922/MT7925
+
+From: Jiande Lu <jiande.lu@mediatek.com>
+
+[ Upstream commit 129d329286f624b0ccd66e904a2c27eb4d5196e5 ]
+
+Add HW IDs for wireless module specific to Acer/ASUS
+notebook models to ensure proper recognition and functionality.
+These HW IDs are extracted from Windows driver inf file.
+Note some HW IDs without official drivers, still in testing phase.
+Thus, we update module HW ID and test ensure consistent boot success.
+
+Signed-off-by: Jiande Lu <jiande.lu@mediatek.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: faa5fd605d20 ("Bluetooth: btusb: Add new VID/PID 0489/e111 for MT7925")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index fd57a02046ae..dc0bba7f4028 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -620,6 +620,9 @@ static const struct usb_device_id quirks_table[] = {
+       { USB_DEVICE(0x0e8d, 0x0608), .driver_info = BTUSB_MEDIATEK |
+                                                    BTUSB_WIDEBAND_SPEECH |
+                                                    BTUSB_VALID_LE_STATES },
++      { USB_DEVICE(0x13d3, 0x3606), .driver_info = BTUSB_MEDIATEK |
++                                                   BTUSB_WIDEBAND_SPEECH |
++                                                   BTUSB_VALID_LE_STATES },
+       /* MediaTek MT7922A Bluetooth devices */
+       { USB_DEVICE(0x0489, 0xe0d8), .driver_info = BTUSB_MEDIATEK |
+@@ -661,11 +664,32 @@ static const struct usb_device_id quirks_table[] = {
+       { USB_DEVICE(0x35f5, 0x7922), .driver_info = BTUSB_MEDIATEK |
+                                                    BTUSB_WIDEBAND_SPEECH |
+                                                    BTUSB_VALID_LE_STATES },
++      { USB_DEVICE(0x13d3, 0x3614), .driver_info = BTUSB_MEDIATEK |
++                                                   BTUSB_WIDEBAND_SPEECH |
++                                                   BTUSB_VALID_LE_STATES },
++      { USB_DEVICE(0x13d3, 0x3615), .driver_info = BTUSB_MEDIATEK |
++                                                   BTUSB_WIDEBAND_SPEECH |
++                                                   BTUSB_VALID_LE_STATES },
++      { USB_DEVICE(0x04ca, 0x38e4), .driver_info = BTUSB_MEDIATEK |
++                                                   BTUSB_WIDEBAND_SPEECH |
++                                                   BTUSB_VALID_LE_STATES },
++      { USB_DEVICE(0x13d3, 0x3605), .driver_info = BTUSB_MEDIATEK |
++                                                   BTUSB_WIDEBAND_SPEECH |
++                                                   BTUSB_VALID_LE_STATES },
++      { USB_DEVICE(0x13d3, 0x3607), .driver_info = BTUSB_MEDIATEK |
++                                                   BTUSB_WIDEBAND_SPEECH |
++                                                   BTUSB_VALID_LE_STATES },
+       /* Additional MediaTek MT7925 Bluetooth devices */
++      { USB_DEVICE(0x0489, 0xe113), .driver_info = BTUSB_MEDIATEK |
++                                                   BTUSB_WIDEBAND_SPEECH |
++                                                   BTUSB_VALID_LE_STATES },
+       { USB_DEVICE(0x13d3, 0x3602), .driver_info = BTUSB_MEDIATEK |
+                                                    BTUSB_WIDEBAND_SPEECH |
+                                                    BTUSB_VALID_LE_STATES },
++      { USB_DEVICE(0x13d3, 0x3603), .driver_info = BTUSB_MEDIATEK |
++                                                   BTUSB_WIDEBAND_SPEECH |
++                                                   BTUSB_VALID_LE_STATES },
+       /* Additional Realtek 8723AE Bluetooth devices */
+       { USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK },
+-- 
+2.39.5
+
diff --git a/queue-6.6/bluetooth-btusb-mediatek-add-callback-function-in-bt.patch b/queue-6.6/bluetooth-btusb-mediatek-add-callback-function-in-bt.patch
new file mode 100644 (file)
index 0000000..7396f0c
--- /dev/null
@@ -0,0 +1,44 @@
+From 4e6ef6c7bcc35f825199ae135a5d8d90deecc447 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Sep 2024 16:47:03 +0800
+Subject: Bluetooth: btusb: mediatek: add callback function in btusb_disconnect
+
+From: Chris Lu <chris.lu@mediatek.com>
+
+[ Upstream commit cea1805f165cdd783dd21f26df957118cb8641b4 ]
+
+Add disconnect callback function in btusb_disconnect which is reserved
+for vendor specific usage before deregister hci in btusb_disconnect.
+
+Signed-off-by: Chris Lu <chris.lu@mediatek.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 19d371aa8317..c80b5aa7628a 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -894,6 +894,7 @@ struct btusb_data {
+       int (*suspend)(struct hci_dev *hdev);
+       int (*resume)(struct hci_dev *hdev);
++      int (*disconnect)(struct hci_dev *hdev);
+       int oob_wake_irq;   /* irq for out-of-band wake-on-bt */
+       unsigned cmd_timeout_cnt;
+@@ -4646,6 +4647,9 @@ static void btusb_disconnect(struct usb_interface *intf)
+       if (data->diag)
+               usb_set_intfdata(data->diag, NULL);
++      if (data->disconnect)
++              data->disconnect(hdev);
++
+       hci_unregister_dev(hdev);
+       if (intf == data->intf) {
+-- 
+2.39.5
+
diff --git a/queue-6.6/bluetooth-hci_conn-reduce-hci_conn_drop-calls-in-two.patch b/queue-6.6/bluetooth-hci_conn-reduce-hci_conn_drop-calls-in-two.patch
new file mode 100644 (file)
index 0000000..687e821
--- /dev/null
@@ -0,0 +1,62 @@
+From 8312de9db3bbe5da4de70dbdbbdf812b9f251838 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Oct 2024 09:21:25 +0200
+Subject: Bluetooth: hci_conn: Reduce hci_conn_drop() calls in two functions
+
+From: Markus Elfring <elfring@users.sourceforge.net>
+
+[ Upstream commit d96b543c6f3b78b6440b68b5a5bbface553eff28 ]
+
+An hci_conn_drop() call was immediately used after a null pointer check
+for an hci_conn_link() call in two function implementations.
+Thus call such a function only once instead directly before the checks.
+
+This issue was transformed by using the Coccinelle software.
+
+Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_conn.c | 13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index 6178ae8feafc..549ee9e87d63 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -2178,13 +2178,9 @@ struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst,
+                                         conn->iso_qos.bcast.big);
+       if (parent && parent != conn) {
+               link = hci_conn_link(parent, conn);
+-              if (!link) {
+-                      hci_conn_drop(conn);
+-                      return ERR_PTR(-ENOLINK);
+-              }
+-
+-              /* Link takes the refcount */
+               hci_conn_drop(conn);
++              if (!link)
++                      return ERR_PTR(-ENOLINK);
+       }
+       return conn;
+@@ -2274,15 +2270,12 @@ struct hci_conn *hci_connect_cis(struct hci_dev *hdev, bdaddr_t *dst,
+       }
+       link = hci_conn_link(le, cis);
++      hci_conn_drop(cis);
+       if (!link) {
+               hci_conn_drop(le);
+-              hci_conn_drop(cis);
+               return ERR_PTR(-ENOLINK);
+       }
+-      /* Link takes the refcount */
+-      hci_conn_drop(cis);
+-
+       cis->state = BT_CONNECT;
+       hci_le_create_cis_pending(hdev);
+-- 
+2.39.5
+
diff --git a/queue-6.6/btrfs-fix-use-after-free-when-cowing-tree-bock-and-t.patch b/queue-6.6/btrfs-fix-use-after-free-when-cowing-tree-bock-and-t.patch
new file mode 100644 (file)
index 0000000..2bea454
--- /dev/null
@@ -0,0 +1,79 @@
+From bc8fa542679b56ee1a982cac0fd5d7d2c59970ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Dec 2024 16:08:07 +0000
+Subject: btrfs: fix use-after-free when COWing tree bock and tracing is
+ enabled
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit 44f52bbe96dfdbe4aca3818a2534520082a07040 ]
+
+When a COWing a tree block, at btrfs_cow_block(), and we have the
+tracepoint trace_btrfs_cow_block() enabled and preemption is also enabled
+(CONFIG_PREEMPT=y), we can trigger a use-after-free in the COWed extent
+buffer while inside the tracepoint code. This is because in some paths
+that call btrfs_cow_block(), such as btrfs_search_slot(), we are holding
+the last reference on the extent buffer @buf so btrfs_force_cow_block()
+drops the last reference on the @buf extent buffer when it calls
+free_extent_buffer_stale(buf), which schedules the release of the extent
+buffer with RCU. This means that if we are on a kernel with preemption,
+the current task may be preempted before calling trace_btrfs_cow_block()
+and the extent buffer already released by the time trace_btrfs_cow_block()
+is called, resulting in a use-after-free.
+
+Fix this by moving the trace_btrfs_cow_block() from btrfs_cow_block() to
+btrfs_force_cow_block() before the COWed extent buffer is freed.
+This also has a side effect of invoking the tracepoint in the tree defrag
+code, at defrag.c:btrfs_realloc_node(), since btrfs_force_cow_block() is
+called there, but this is fine and it was actually missing there.
+
+Reported-by: syzbot+8517da8635307182c8a5@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/linux-btrfs/6759a9b9.050a0220.1ac542.000d.GAE@google.com/
+CC: stable@vger.kernel.org # 5.4+
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/ctree.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
+index 62032d3fda85..4b21ca49b666 100644
+--- a/fs/btrfs/ctree.c
++++ b/fs/btrfs/ctree.c
+@@ -660,6 +660,8 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans,
+                       return ret;
+               }
+       }
++
++      trace_btrfs_cow_block(root, buf, cow);
+       if (unlock_orig)
+               btrfs_tree_unlock(buf);
+       free_extent_buffer_stale(buf);
+@@ -711,7 +713,6 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans,
+ {
+       struct btrfs_fs_info *fs_info = root->fs_info;
+       u64 search_start;
+-      int ret;
+       if (unlikely(test_bit(BTRFS_ROOT_DELETING, &root->state))) {
+               btrfs_abort_transaction(trans, -EUCLEAN);
+@@ -752,12 +753,8 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans,
+        * Also We don't care about the error, as it's handled internally.
+        */
+       btrfs_qgroup_trace_subtree_after_cow(trans, root, buf);
+-      ret = btrfs_force_cow_block(trans, root, buf, parent, parent_slot,
+-                                  cow_ret, search_start, 0, nest);
+-
+-      trace_btrfs_cow_block(root, buf, *cow_ret);
+-
+-      return ret;
++      return btrfs_force_cow_block(trans, root, buf, parent, parent_slot,
++                                   cow_ret, search_start, 0, nest);
+ }
+ ALLOW_ERROR_INJECTION(btrfs_cow_block, ERRNO);
+-- 
+2.39.5
+
diff --git a/queue-6.6/btrfs-rename-and-export-__btrfs_cow_block.patch b/queue-6.6/btrfs-rename-and-export-__btrfs_cow_block.patch
new file mode 100644 (file)
index 0000000..1a7afd9
--- /dev/null
@@ -0,0 +1,106 @@
+From 477a23fee0d5df1f4183e52713f466cb097eb15d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Sep 2023 12:09:26 +0100
+Subject: btrfs: rename and export __btrfs_cow_block()
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit 95f93bc4cbcac6121a5ee85cd5019ee8e7447e0b ]
+
+Rename and export __btrfs_cow_block() as btrfs_force_cow_block(). This is
+to allow to move defrag specific code out of ctree.c and into defrag.c in
+one of the next patches.
+
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Stable-dep-of: 44f52bbe96df ("btrfs: fix use-after-free when COWing tree bock and tracing is enabled")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/ctree.c | 30 +++++++++++++++---------------
+ fs/btrfs/ctree.h |  7 +++++++
+ 2 files changed, 22 insertions(+), 15 deletions(-)
+
+diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
+index 25c902e7556d..62032d3fda85 100644
+--- a/fs/btrfs/ctree.c
++++ b/fs/btrfs/ctree.c
+@@ -526,13 +526,13 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
+  * bytes the allocator should try to find free next to the block it returns.
+  * This is just a hint and may be ignored by the allocator.
+  */
+-static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
+-                           struct btrfs_root *root,
+-                           struct extent_buffer *buf,
+-                           struct extent_buffer *parent, int parent_slot,
+-                           struct extent_buffer **cow_ret,
+-                           u64 search_start, u64 empty_size,
+-                           enum btrfs_lock_nesting nest)
++int btrfs_force_cow_block(struct btrfs_trans_handle *trans,
++                        struct btrfs_root *root,
++                        struct extent_buffer *buf,
++                        struct extent_buffer *parent, int parent_slot,
++                        struct extent_buffer **cow_ret,
++                        u64 search_start, u64 empty_size,
++                        enum btrfs_lock_nesting nest)
+ {
+       struct btrfs_fs_info *fs_info = root->fs_info;
+       struct btrfs_disk_key disk_key;
+@@ -699,7 +699,7 @@ static inline int should_cow_block(struct btrfs_trans_handle *trans,
+ }
+ /*
+- * cows a single block, see __btrfs_cow_block for the real work.
++ * COWs a single block, see btrfs_force_cow_block() for the real work.
+  * This version of it has extra checks so that a block isn't COWed more than
+  * once per transaction, as long as it hasn't been written yet
+  */
+@@ -752,8 +752,8 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans,
+        * Also We don't care about the error, as it's handled internally.
+        */
+       btrfs_qgroup_trace_subtree_after_cow(trans, root, buf);
+-      ret = __btrfs_cow_block(trans, root, buf, parent,
+-                               parent_slot, cow_ret, search_start, 0, nest);
++      ret = btrfs_force_cow_block(trans, root, buf, parent, parent_slot,
++                                  cow_ret, search_start, 0, nest);
+       trace_btrfs_cow_block(root, buf, *cow_ret);
+@@ -904,11 +904,11 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
+                       search_start = last_block;
+               btrfs_tree_lock(cur);
+-              err = __btrfs_cow_block(trans, root, cur, parent, i,
+-                                      &cur, search_start,
+-                                      min(16 * blocksize,
+-                                          (end_slot - i) * blocksize),
+-                                      BTRFS_NESTING_COW);
++              err = btrfs_force_cow_block(trans, root, cur, parent, i,
++                                          &cur, search_start,
++                                          min(16 * blocksize,
++                                              (end_slot - i) * blocksize),
++                                          BTRFS_NESTING_COW);
+               if (err) {
+                       btrfs_tree_unlock(cur);
+                       free_extent_buffer(cur);
+diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
+index f7bb4c34b984..7df3ed2945b0 100644
+--- a/fs/btrfs/ctree.h
++++ b/fs/btrfs/ctree.h
+@@ -538,6 +538,13 @@ int btrfs_cow_block(struct btrfs_trans_handle *trans,
+                   struct extent_buffer *parent, int parent_slot,
+                   struct extent_buffer **cow_ret,
+                   enum btrfs_lock_nesting nest);
++int btrfs_force_cow_block(struct btrfs_trans_handle *trans,
++                        struct btrfs_root *root,
++                        struct extent_buffer *buf,
++                        struct extent_buffer *parent, int parent_slot,
++                        struct extent_buffer **cow_ret,
++                        u64 search_start, u64 empty_size,
++                        enum btrfs_lock_nesting nest);
+ int btrfs_copy_root(struct btrfs_trans_handle *trans,
+                     struct btrfs_root *root,
+                     struct extent_buffer *buf,
+-- 
+2.39.5
+
diff --git a/queue-6.6/cleanup-add-conditional-guard-support.patch b/queue-6.6/cleanup-add-conditional-guard-support.patch
new file mode 100644 (file)
index 0000000..a8f8fa6
--- /dev/null
@@ -0,0 +1,225 @@
+From c18818f7036946b3477c4c02fbc20075266cbc07 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Sep 2023 13:22:17 +0200
+Subject: cleanup: Add conditional guard support
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit e4ab322fbaaaf84b23d6cb0e3317a7f68baf36dc ]
+
+Adds:
+
+ - DEFINE_GUARD_COND() / DEFINE_LOCK_GUARD_1_COND() to extend existing
+   guards with conditional lock primitives, eg. mutex_trylock(),
+   mutex_lock_interruptible().
+
+   nb. both primitives allow NULL 'locks', which cause the lock to
+       fail (obviously).
+
+ - extends scoped_guard() to not take the body when the the
+   conditional guard 'fails'. eg.
+
+     scoped_guard (mutex_intr, &task->signal_cred_guard_mutex) {
+       ...
+     }
+
+   will only execute the body when the mutex is held.
+
+ - provides scoped_cond_guard(name, fail, args...); which extends
+   scoped_guard() to do fail when the lock-acquire fails.
+
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20231102110706.460851167%40infradead.org
+Stable-dep-of: fcc22ac5baf0 ("cleanup: Adjust scoped_guard() macros to avoid potential warning")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/cleanup.h  | 52 +++++++++++++++++++++++++++++++++++++---
+ include/linux/mutex.h    |  3 ++-
+ include/linux/rwsem.h    |  8 +++----
+ include/linux/spinlock.h | 15 ++++++++++++
+ 4 files changed, 70 insertions(+), 8 deletions(-)
+
+diff --git a/include/linux/cleanup.h b/include/linux/cleanup.h
+index 53f1a7a932b0..6d7bfa899df0 100644
+--- a/include/linux/cleanup.h
++++ b/include/linux/cleanup.h
+@@ -92,25 +92,55 @@ static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \
+  *    trivial wrapper around DEFINE_CLASS() above specifically
+  *    for locks.
+  *
++ * DEFINE_GUARD_COND(name, ext, condlock)
++ *    wrapper around EXTEND_CLASS above to add conditional lock
++ *    variants to a base class, eg. mutex_trylock() or
++ *    mutex_lock_interruptible().
++ *
+  * guard(name):
+- *    an anonymous instance of the (guard) class
++ *    an anonymous instance of the (guard) class, not recommended for
++ *    conditional locks.
+  *
+  * scoped_guard (name, args...) { }:
+  *    similar to CLASS(name, scope)(args), except the variable (with the
+  *    explicit name 'scope') is declard in a for-loop such that its scope is
+  *    bound to the next (compound) statement.
+  *
++ *    for conditional locks the loop body is skipped when the lock is not
++ *    acquired.
++ *
++ * scoped_cond_guard (name, fail, args...) { }:
++ *      similar to scoped_guard(), except it does fail when the lock
++ *      acquire fails.
++ *
+  */
+ #define DEFINE_GUARD(_name, _type, _lock, _unlock) \
+-      DEFINE_CLASS(_name, _type, _unlock, ({ _lock; _T; }), _type _T)
++      DEFINE_CLASS(_name, _type, if (_T) { _unlock; }, ({ _lock; _T; }), _type _T); \
++      static inline void * class_##_name##_lock_ptr(class_##_name##_t *_T) \
++      { return *_T; }
++
++#define DEFINE_GUARD_COND(_name, _ext, _condlock) \
++      EXTEND_CLASS(_name, _ext, \
++                   ({ void *_t = _T; if (_T && !(_condlock)) _t = NULL; _t; }), \
++                   class_##_name##_t _T) \
++      static inline void * class_##_name##_ext##_lock_ptr(class_##_name##_t *_T) \
++      { return class_##_name##_lock_ptr(_T); }
+ #define guard(_name) \
+       CLASS(_name, __UNIQUE_ID(guard))
++#define __guard_ptr(_name) class_##_name##_lock_ptr
++
+ #define scoped_guard(_name, args...)                                  \
+       for (CLASS(_name, scope)(args),                                 \
+-           *done = NULL; !done; done = (void *)1)
++           *done = NULL; __guard_ptr(_name)(&scope) && !done; done = (void *)1)
++
++#define scoped_cond_guard(_name, _fail, args...) \
++      for (CLASS(_name, scope)(args), \
++           *done = NULL; !done; done = (void *)1) \
++              if (!__guard_ptr(_name)(&scope)) _fail; \
++              else
+ /*
+  * Additional helper macros for generating lock guards with types, either for
+@@ -119,6 +149,7 @@ static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \
+  *
+  * DEFINE_LOCK_GUARD_0(name, lock, unlock, ...)
+  * DEFINE_LOCK_GUARD_1(name, type, lock, unlock, ...)
++ * DEFINE_LOCK_GUARD_1_COND(name, ext, condlock)
+  *
+  * will result in the following type:
+  *
+@@ -140,6 +171,11 @@ typedef struct {                                                  \
+ static inline void class_##_name##_destructor(class_##_name##_t *_T)  \
+ {                                                                     \
+       if (_T->lock) { _unlock; }                                      \
++}                                                                     \
++                                                                      \
++static inline void *class_##_name##_lock_ptr(class_##_name##_t *_T)   \
++{                                                                     \
++      return _T->lock;                                                \
+ }
+@@ -168,4 +204,14 @@ __DEFINE_LOCK_GUARD_1(_name, _type, _lock)
+ __DEFINE_UNLOCK_GUARD(_name, void, _unlock, __VA_ARGS__)              \
+ __DEFINE_LOCK_GUARD_0(_name, _lock)
++#define DEFINE_LOCK_GUARD_1_COND(_name, _ext, _condlock)              \
++      EXTEND_CLASS(_name, _ext,                                       \
++                   ({ class_##_name##_t _t = { .lock = l }, *_T = &_t;\
++                      if (_T->lock && !(_condlock)) _T->lock = NULL;  \
++                      _t; }),                                         \
++                   typeof_member(class_##_name##_t, lock) l)          \
++      static inline void * class_##_name##_ext##_lock_ptr(class_##_name##_t *_T) \
++      { return class_##_name##_lock_ptr(_T); }
++
++
+ #endif /* __LINUX_GUARDS_H */
+diff --git a/include/linux/mutex.h b/include/linux/mutex.h
+index 5b5630e58407..e1c323c7d75b 100644
+--- a/include/linux/mutex.h
++++ b/include/linux/mutex.h
+@@ -248,6 +248,7 @@ extern void mutex_unlock(struct mutex *lock);
+ extern int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock);
+ DEFINE_GUARD(mutex, struct mutex *, mutex_lock(_T), mutex_unlock(_T))
+-DEFINE_FREE(mutex, struct mutex *, if (_T) mutex_unlock(_T))
++DEFINE_GUARD_COND(mutex, _try, mutex_trylock(_T))
++DEFINE_GUARD_COND(mutex, _intr, mutex_lock_interruptible(_T) == 0)
+ #endif /* __LINUX_MUTEX_H */
+diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h
+index 1dd530ce8b45..9c29689ff505 100644
+--- a/include/linux/rwsem.h
++++ b/include/linux/rwsem.h
+@@ -203,11 +203,11 @@ extern void up_read(struct rw_semaphore *sem);
+ extern void up_write(struct rw_semaphore *sem);
+ DEFINE_GUARD(rwsem_read, struct rw_semaphore *, down_read(_T), up_read(_T))
+-DEFINE_GUARD(rwsem_write, struct rw_semaphore *, down_write(_T), up_write(_T))
+-
+-DEFINE_FREE(up_read, struct rw_semaphore *, if (_T) up_read(_T))
+-DEFINE_FREE(up_write, struct rw_semaphore *, if (_T) up_write(_T))
++DEFINE_GUARD_COND(rwsem_read, _try, down_read_trylock(_T))
++DEFINE_GUARD_COND(rwsem_read, _intr, down_read_interruptible(_T) == 0)
++DEFINE_GUARD(rwsem_write, struct rw_semaphore *, down_write(_T), up_write(_T))
++DEFINE_GUARD_COND(rwsem_write, _try, down_write_trylock(_T))
+ /*
+  * downgrade write lock to read lock
+diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
+index 31d3d747a9db..ceb56b39c70f 100644
+--- a/include/linux/spinlock.h
++++ b/include/linux/spinlock.h
+@@ -507,6 +507,8 @@ DEFINE_LOCK_GUARD_1(raw_spinlock, raw_spinlock_t,
+                   raw_spin_lock(_T->lock),
+                   raw_spin_unlock(_T->lock))
++DEFINE_LOCK_GUARD_1_COND(raw_spinlock, _try, raw_spin_trylock(_T->lock))
++
+ DEFINE_LOCK_GUARD_1(raw_spinlock_nested, raw_spinlock_t,
+                   raw_spin_lock_nested(_T->lock, SINGLE_DEPTH_NESTING),
+                   raw_spin_unlock(_T->lock))
+@@ -515,23 +517,36 @@ DEFINE_LOCK_GUARD_1(raw_spinlock_irq, raw_spinlock_t,
+                   raw_spin_lock_irq(_T->lock),
+                   raw_spin_unlock_irq(_T->lock))
++DEFINE_LOCK_GUARD_1_COND(raw_spinlock_irq, _try, raw_spin_trylock_irq(_T->lock))
++
+ DEFINE_LOCK_GUARD_1(raw_spinlock_irqsave, raw_spinlock_t,
+                   raw_spin_lock_irqsave(_T->lock, _T->flags),
+                   raw_spin_unlock_irqrestore(_T->lock, _T->flags),
+                   unsigned long flags)
++DEFINE_LOCK_GUARD_1_COND(raw_spinlock_irqsave, _try,
++                       raw_spin_trylock_irqsave(_T->lock, _T->flags))
++
+ DEFINE_LOCK_GUARD_1(spinlock, spinlock_t,
+                   spin_lock(_T->lock),
+                   spin_unlock(_T->lock))
++DEFINE_LOCK_GUARD_1_COND(spinlock, _try, spin_trylock(_T->lock))
++
+ DEFINE_LOCK_GUARD_1(spinlock_irq, spinlock_t,
+                   spin_lock_irq(_T->lock),
+                   spin_unlock_irq(_T->lock))
++DEFINE_LOCK_GUARD_1_COND(spinlock_irq, _try,
++                       spin_trylock_irq(_T->lock))
++
+ DEFINE_LOCK_GUARD_1(spinlock_irqsave, spinlock_t,
+                   spin_lock_irqsave(_T->lock, _T->flags),
+                   spin_unlock_irqrestore(_T->lock, _T->flags),
+                   unsigned long flags)
++DEFINE_LOCK_GUARD_1_COND(spinlock_irqsave, _try,
++                       spin_trylock_irqsave(_T->lock, _T->flags))
++
+ #undef __LINUX_INSIDE_SPINLOCK_H
+ #endif /* __LINUX_SPINLOCK_H */
+-- 
+2.39.5
+
diff --git a/queue-6.6/cleanup-adjust-scoped_guard-macros-to-avoid-potentia.patch b/queue-6.6/cleanup-adjust-scoped_guard-macros-to-avoid-potentia.patch
new file mode 100644 (file)
index 0000000..7895f67
--- /dev/null
@@ -0,0 +1,171 @@
+From d81bc8e1b23a893d4199e396baa46e4267026c6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Oct 2024 13:38:14 +0200
+Subject: cleanup: Adjust scoped_guard() macros to avoid potential warning
+
+From: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+
+[ Upstream commit fcc22ac5baf06dd17193de44b60dbceea6461983 ]
+
+Change scoped_guard() and scoped_cond_guard() macros to make reasoning
+about them easier for static analysis tools (smatch, compiler
+diagnostics), especially to enable them to tell if the given usage of
+scoped_guard() is with a conditional lock class (interruptible-locks,
+try-locks) or not (like simple mutex_lock()).
+
+Add compile-time error if scoped_cond_guard() is used for non-conditional
+lock class.
+
+Beyond easier tooling and a little shrink reported by bloat-o-meter
+this patch enables developer to write code like:
+
+int foo(struct my_drv *adapter)
+{
+       scoped_guard(spinlock, &adapter->some_spinlock)
+               return adapter->spinlock_protected_var;
+}
+
+Current scoped_guard() implementation does not support that,
+due to compiler complaining:
+error: control reaches end of non-void function [-Werror=return-type]
+
+Technical stuff about the change:
+scoped_guard() macro uses common idiom of using "for" statement to declare
+a scoped variable. Unfortunately, current logic is too hard for compiler
+diagnostics to be sure that there is exactly one loop step; fix that.
+
+To make any loop so trivial that there is no above warning, it must not
+depend on any non-const variable to tell if there are more steps. There is
+no obvious solution for that in C, but one could use the compound
+statement expression with "goto" jumping past the "loop", effectively
+leaving only the subscope part of the loop semantics.
+
+More impl details:
+one more level of macro indirection is now needed to avoid duplicating
+label names;
+I didn't spot any other place that is using the
+"for (...; goto label) if (0) label: break;" idiom, so it's not packed for
+reuse beyond scoped_guard() family, what makes actual macros code cleaner.
+
+There was also a need to introduce const true/false variable per lock
+class, it is used to aid compiler diagnostics reasoning about "exactly
+1 step" loops (note that converting that to function would undo the whole
+benefit).
+
+Big thanks to Andy Shevchenko for help on this patch, both internal and
+public, ranging from whitespace/formatting, through commit message
+clarifications, general improvements, ending with presenting alternative
+approaches - all despite not even liking the idea.
+
+Big thanks to Dmitry Torokhov for the idea of compile-time check for
+scoped_cond_guard() (to use it only with conditional locsk), and general
+improvements for the patch.
+
+Big thanks to David Lechner for idea to cover also scoped_cond_guard().
+
+Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Link: https://lkml.kernel.org/r/20241018113823.171256-1-przemyslaw.kitszel@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/cleanup.h | 52 +++++++++++++++++++++++++++++++++--------
+ 1 file changed, 42 insertions(+), 10 deletions(-)
+
+diff --git a/include/linux/cleanup.h b/include/linux/cleanup.h
+index 6d7bfa899df0..f0c6d1d45e67 100644
+--- a/include/linux/cleanup.h
++++ b/include/linux/cleanup.h
+@@ -113,14 +113,20 @@ static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \
+  *      similar to scoped_guard(), except it does fail when the lock
+  *      acquire fails.
+  *
++ *      Only for conditional locks.
+  */
++#define __DEFINE_CLASS_IS_CONDITIONAL(_name, _is_cond)        \
++static __maybe_unused const bool class_##_name##_is_conditional = _is_cond
++
+ #define DEFINE_GUARD(_name, _type, _lock, _unlock) \
++      __DEFINE_CLASS_IS_CONDITIONAL(_name, false); \
+       DEFINE_CLASS(_name, _type, if (_T) { _unlock; }, ({ _lock; _T; }), _type _T); \
+       static inline void * class_##_name##_lock_ptr(class_##_name##_t *_T) \
+       { return *_T; }
+ #define DEFINE_GUARD_COND(_name, _ext, _condlock) \
++      __DEFINE_CLASS_IS_CONDITIONAL(_name##_ext, true); \
+       EXTEND_CLASS(_name, _ext, \
+                    ({ void *_t = _T; if (_T && !(_condlock)) _t = NULL; _t; }), \
+                    class_##_name##_t _T) \
+@@ -131,17 +137,40 @@ static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \
+       CLASS(_name, __UNIQUE_ID(guard))
+ #define __guard_ptr(_name) class_##_name##_lock_ptr
++#define __is_cond_ptr(_name) class_##_name##_is_conditional
+-#define scoped_guard(_name, args...)                                  \
+-      for (CLASS(_name, scope)(args),                                 \
+-           *done = NULL; __guard_ptr(_name)(&scope) && !done; done = (void *)1)
+-
+-#define scoped_cond_guard(_name, _fail, args...) \
+-      for (CLASS(_name, scope)(args), \
+-           *done = NULL; !done; done = (void *)1) \
+-              if (!__guard_ptr(_name)(&scope)) _fail; \
+-              else
+-
++/*
++ * Helper macro for scoped_guard().
++ *
++ * Note that the "!__is_cond_ptr(_name)" part of the condition ensures that
++ * compiler would be sure that for the unconditional locks the body of the
++ * loop (caller-provided code glued to the else clause) could not be skipped.
++ * It is needed because the other part - "__guard_ptr(_name)(&scope)" - is too
++ * hard to deduce (even if could be proven true for unconditional locks).
++ */
++#define __scoped_guard(_name, _label, args...)                                \
++      for (CLASS(_name, scope)(args);                                 \
++           __guard_ptr(_name)(&scope) || !__is_cond_ptr(_name);       \
++           ({ goto _label; }))                                        \
++              if (0) {                                                \
++_label:                                                                       \
++                      break;                                          \
++              } else
++
++#define scoped_guard(_name, args...)  \
++      __scoped_guard(_name, __UNIQUE_ID(label), args)
++
++#define __scoped_cond_guard(_name, _fail, _label, args...)            \
++      for (CLASS(_name, scope)(args); true; ({ goto _label; }))       \
++              if (!__guard_ptr(_name)(&scope)) {                      \
++                      BUILD_BUG_ON(!__is_cond_ptr(_name));            \
++                      _fail;                                          \
++_label:                                                                       \
++                      break;                                          \
++              } else
++
++#define scoped_cond_guard(_name, _fail, args...)      \
++      __scoped_cond_guard(_name, _fail, __UNIQUE_ID(label), args)
+ /*
+  * Additional helper macros for generating lock guards with types, either for
+  * locks that don't have a native type (eg. RCU, preempt) or those that need a
+@@ -197,14 +226,17 @@ static inline class_##_name##_t class_##_name##_constructor(void)        \
+ }
+ #define DEFINE_LOCK_GUARD_1(_name, _type, _lock, _unlock, ...)                \
++__DEFINE_CLASS_IS_CONDITIONAL(_name, false);                          \
+ __DEFINE_UNLOCK_GUARD(_name, _type, _unlock, __VA_ARGS__)             \
+ __DEFINE_LOCK_GUARD_1(_name, _type, _lock)
+ #define DEFINE_LOCK_GUARD_0(_name, _lock, _unlock, ...)                       \
++__DEFINE_CLASS_IS_CONDITIONAL(_name, false);                          \
+ __DEFINE_UNLOCK_GUARD(_name, void, _unlock, __VA_ARGS__)              \
+ __DEFINE_LOCK_GUARD_0(_name, _lock)
+ #define DEFINE_LOCK_GUARD_1_COND(_name, _ext, _condlock)              \
++      __DEFINE_CLASS_IS_CONDITIONAL(_name##_ext, true);               \
+       EXTEND_CLASS(_name, _ext,                                       \
+                    ({ class_##_name##_t _t = { .lock = l }, *_T = &_t;\
+                       if (_T->lock && !(_condlock)) _T->lock = NULL;  \
+-- 
+2.39.5
+
diff --git a/queue-6.6/cleanup-remove-address-space-of-returned-pointer.patch b/queue-6.6/cleanup-remove-address-space-of-returned-pointer.patch
new file mode 100644 (file)
index 0000000..2ddeb2c
--- /dev/null
@@ -0,0 +1,60 @@
+From 8a8b512523945efc15399f4dfa0df9606970dfd8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Aug 2024 09:41:15 +0200
+Subject: cleanup: Remove address space of returned pointer
+
+From: Uros Bizjak <ubizjak@gmail.com>
+
+[ Upstream commit f730fd535fc51573f982fad629f2fc6b4a0cde2f ]
+
+Guard functions in local_lock.h are defined using DEFINE_GUARD() and
+DEFINE_LOCK_GUARD_1() macros having lock type defined as pointer in
+the percpu address space. The functions, defined by these macros
+return value in generic address space, causing:
+
+cleanup.h:157:18: error: return from pointer to non-enclosed address space
+
+and
+
+cleanup.h:214:18: error: return from pointer to non-enclosed address space
+
+when strict percpu checks are enabled.
+
+Add explicit casts to remove address space of the returned pointer.
+
+Found by GCC's named address space checks.
+
+Fixes: e4ab322fbaaa ("cleanup: Add conditional guard support")
+Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20240819074124.143565-1-ubizjak@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/cleanup.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/cleanup.h b/include/linux/cleanup.h
+index f0c6d1d45e67..64b8600eb8c0 100644
+--- a/include/linux/cleanup.h
++++ b/include/linux/cleanup.h
+@@ -123,7 +123,7 @@ static __maybe_unused const bool class_##_name##_is_conditional = _is_cond
+       __DEFINE_CLASS_IS_CONDITIONAL(_name, false); \
+       DEFINE_CLASS(_name, _type, if (_T) { _unlock; }, ({ _lock; _T; }), _type _T); \
+       static inline void * class_##_name##_lock_ptr(class_##_name##_t *_T) \
+-      { return *_T; }
++      { return (void *)(__force unsigned long)*_T; }
+ #define DEFINE_GUARD_COND(_name, _ext, _condlock) \
+       __DEFINE_CLASS_IS_CONDITIONAL(_name##_ext, true); \
+@@ -204,7 +204,7 @@ static inline void class_##_name##_destructor(class_##_name##_t *_T)       \
+                                                                       \
+ static inline void *class_##_name##_lock_ptr(class_##_name##_t *_T)   \
+ {                                                                     \
+-      return _T->lock;                                                \
++      return (void *)(__force unsigned long)_T->lock;                 \
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.6/clk-qcom-clk-alpha-pll-add-nss-huayra-alpha-pll-supp.patch b/queue-6.6/clk-qcom-clk-alpha-pll-add-nss-huayra-alpha-pll-supp.patch
new file mode 100644 (file)
index 0000000..9abbc94
--- /dev/null
@@ -0,0 +1,61 @@
+From 3e6fca922bedf3a475677799ba01c2dc75fc3316 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Oct 2024 11:35:01 +0530
+Subject: clk: qcom: clk-alpha-pll: Add NSS HUAYRA ALPHA PLL support for
+ ipq9574
+
+From: Devi Priya <quic_devipriy@quicinc.com>
+
+[ Upstream commit 79dfed29aa3f714e0a94a39b2bfe9ac14ce19a6a ]
+
+Add support for NSS Huayra alpha pll found on ipq9574 SoCs.
+Programming sequence is the same as that of Huayra type Alpha PLL,
+so we can re-use the same.
+
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Devi Priya <quic_devipriy@quicinc.com>
+Link: https://lore.kernel.org/r/20241028060506.246606-2-quic_srichara@quicinc.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/clk-alpha-pll.c | 11 +++++++++++
+ drivers/clk/qcom/clk-alpha-pll.h |  1 +
+ 2 files changed, 12 insertions(+)
+
+diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
+index 87040b949eb4..ce44dbfd47e2 100644
+--- a/drivers/clk/qcom/clk-alpha-pll.c
++++ b/drivers/clk/qcom/clk-alpha-pll.c
+@@ -243,6 +243,17 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
+               [PLL_OFF_OPMODE] = 0x30,
+               [PLL_OFF_STATUS] = 0x3c,
+       },
++      [CLK_ALPHA_PLL_TYPE_NSS_HUAYRA] =  {
++              [PLL_OFF_L_VAL] = 0x04,
++              [PLL_OFF_ALPHA_VAL] = 0x08,
++              [PLL_OFF_TEST_CTL] = 0x0c,
++              [PLL_OFF_TEST_CTL_U] = 0x10,
++              [PLL_OFF_USER_CTL] = 0x14,
++              [PLL_OFF_CONFIG_CTL] = 0x18,
++              [PLL_OFF_CONFIG_CTL_U] = 0x1c,
++              [PLL_OFF_STATUS] = 0x20,
++      },
++
+ };
+ EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
+diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
+index f50de33a045d..52dc5b9b546a 100644
+--- a/drivers/clk/qcom/clk-alpha-pll.h
++++ b/drivers/clk/qcom/clk-alpha-pll.h
+@@ -29,6 +29,7 @@ enum {
+       CLK_ALPHA_PLL_TYPE_BRAMMO_EVO,
+       CLK_ALPHA_PLL_TYPE_STROMER,
+       CLK_ALPHA_PLL_TYPE_STROMER_PLUS,
++      CLK_ALPHA_PLL_TYPE_NSS_HUAYRA,
+       CLK_ALPHA_PLL_TYPE_MAX,
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.6/clk-qcom-clk-alpha-pll-add-support-for-zonda-ole-pll.patch b/queue-6.6/clk-qcom-clk-alpha-pll-add-support-for-zonda-ole-pll.patch
new file mode 100644 (file)
index 0000000..e5c2f10
--- /dev/null
@@ -0,0 +1,96 @@
+From a95f1dad014dbec897f674977adbf57e85a97296 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Feb 2024 20:34:41 +0200
+Subject: clk: qcom: clk-alpha-pll: Add support for zonda ole pll configure
+
+From: Rajendra Nayak <quic_rjendra@quicinc.com>
+
+[ Upstream commit c32f4f4ae1c6035b44bb4ca7a41fa4fd51244597 ]
+
+Zonda ole pll has as extra PLL_OFF_CONFIG_CTL_U2 register, hence add
+support for it.
+
+Signed-off-by: Rajendra Nayak <quic_rjendra@quicinc.com>
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://lore.kernel.org/r/20240202-x1e80100-clock-controllers-v4-6-7fb08c861c7c@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: 79dfed29aa3f ("clk: qcom: clk-alpha-pll: Add NSS HUAYRA ALPHA PLL support for ipq9574")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/clk-alpha-pll.c | 16 ++++++++++++++++
+ drivers/clk/qcom/clk-alpha-pll.h |  4 ++++
+ 2 files changed, 20 insertions(+)
+
+diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
+index 8b3e5f84e89a..87040b949eb4 100644
+--- a/drivers/clk/qcom/clk-alpha-pll.c
++++ b/drivers/clk/qcom/clk-alpha-pll.c
+@@ -52,6 +52,7 @@
+ #define PLL_CONFIG_CTL(p)     ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL])
+ #define PLL_CONFIG_CTL_U(p)   ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U])
+ #define PLL_CONFIG_CTL_U1(p)  ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U1])
++#define PLL_CONFIG_CTL_U2(p)  ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U2])
+ #define PLL_TEST_CTL(p)               ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL])
+ #define PLL_TEST_CTL_U(p)     ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U])
+ #define PLL_TEST_CTL_U1(p)     ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U1])
+@@ -227,6 +228,21 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
+               [PLL_OFF_ALPHA_VAL] = 0x24,
+               [PLL_OFF_ALPHA_VAL_U] = 0x28,
+       },
++      [CLK_ALPHA_PLL_TYPE_ZONDA_OLE] =  {
++              [PLL_OFF_L_VAL] = 0x04,
++              [PLL_OFF_ALPHA_VAL] = 0x08,
++              [PLL_OFF_USER_CTL] = 0x0c,
++              [PLL_OFF_USER_CTL_U] = 0x10,
++              [PLL_OFF_CONFIG_CTL] = 0x14,
++              [PLL_OFF_CONFIG_CTL_U] = 0x18,
++              [PLL_OFF_CONFIG_CTL_U1] = 0x1c,
++              [PLL_OFF_CONFIG_CTL_U2] = 0x20,
++              [PLL_OFF_TEST_CTL] = 0x24,
++              [PLL_OFF_TEST_CTL_U] = 0x28,
++              [PLL_OFF_TEST_CTL_U1] = 0x2c,
++              [PLL_OFF_OPMODE] = 0x30,
++              [PLL_OFF_STATUS] = 0x3c,
++      },
+ };
+ EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
+diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
+index 3fd0ef41c72c..f50de33a045d 100644
+--- a/drivers/clk/qcom/clk-alpha-pll.h
++++ b/drivers/clk/qcom/clk-alpha-pll.h
+@@ -21,6 +21,7 @@ enum {
+       CLK_ALPHA_PLL_TYPE_LUCID = CLK_ALPHA_PLL_TYPE_TRION,
+       CLK_ALPHA_PLL_TYPE_AGERA,
+       CLK_ALPHA_PLL_TYPE_ZONDA,
++      CLK_ALPHA_PLL_TYPE_ZONDA_OLE,
+       CLK_ALPHA_PLL_TYPE_LUCID_EVO,
+       CLK_ALPHA_PLL_TYPE_LUCID_OLE,
+       CLK_ALPHA_PLL_TYPE_RIVIAN_EVO,
+@@ -42,6 +43,7 @@ enum {
+       PLL_OFF_CONFIG_CTL,
+       PLL_OFF_CONFIG_CTL_U,
+       PLL_OFF_CONFIG_CTL_U1,
++      PLL_OFF_CONFIG_CTL_U2,
+       PLL_OFF_TEST_CTL,
+       PLL_OFF_TEST_CTL_U,
+       PLL_OFF_TEST_CTL_U1,
+@@ -119,6 +121,7 @@ struct alpha_pll_config {
+       u32 config_ctl_val;
+       u32 config_ctl_hi_val;
+       u32 config_ctl_hi1_val;
++      u32 config_ctl_hi2_val;
+       u32 user_ctl_val;
+       u32 user_ctl_hi_val;
+       u32 user_ctl_hi1_val;
+@@ -173,6 +176,7 @@ extern const struct clk_ops clk_alpha_pll_postdiv_lucid_5lpe_ops;
+ extern const struct clk_ops clk_alpha_pll_zonda_ops;
+ #define clk_alpha_pll_postdiv_zonda_ops clk_alpha_pll_postdiv_fabia_ops
++#define clk_alpha_pll_zonda_ole_ops clk_alpha_pll_zonda_ops
+ extern const struct clk_ops clk_alpha_pll_lucid_evo_ops;
+ extern const struct clk_ops clk_alpha_pll_reset_lucid_evo_ops;
+-- 
+2.39.5
+
diff --git a/queue-6.6/crypto-ecc-prevent-ecc_digits_from_bytes-from-readin.patch b/queue-6.6/crypto-ecc-prevent-ecc_digits_from_bytes-from-readin.patch
new file mode 100644 (file)
index 0000000..482cf5c
--- /dev/null
@@ -0,0 +1,93 @@
+From 18bafd95480493a14aa3c863daf98b98f5030da3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 May 2024 21:59:21 -0400
+Subject: crypto: ecc - Prevent ecc_digits_from_bytes from reading too many
+ bytes
+
+From: Stefan Berger <stefanb@linux.ibm.com>
+
+[ Upstream commit c6ab5c915da460c0397960af3c308386c3f3247b ]
+
+Prevent ecc_digits_from_bytes from reading too many bytes from the input
+byte array in case an insufficient number of bytes is provided to fill the
+output digit array of ndigits. Therefore, initialize the most significant
+digits with 0 to avoid trying to read too many bytes later on. Convert the
+function into a regular function since it is getting too big for an inline
+function.
+
+If too many bytes are provided on the input byte array the extra bytes
+are ignored since the input variable 'ndigits' limits the number of digits
+that will be filled.
+
+Fixes: d67c96fb97b5 ("crypto: ecdsa - Convert byte arrays with key coordinates to digits")
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/ecc.c                  | 22 ++++++++++++++++++++++
+ include/crypto/internal/ecc.h | 15 ++-------------
+ 2 files changed, 24 insertions(+), 13 deletions(-)
+
+diff --git a/crypto/ecc.c b/crypto/ecc.c
+index f53fb4d6af99..21504280aca2 100644
+--- a/crypto/ecc.c
++++ b/crypto/ecc.c
+@@ -66,6 +66,28 @@ const struct ecc_curve *ecc_get_curve(unsigned int curve_id)
+ }
+ EXPORT_SYMBOL(ecc_get_curve);
++void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes,
++                         u64 *out, unsigned int ndigits)
++{
++      int diff = ndigits - DIV_ROUND_UP(nbytes, sizeof(u64));
++      unsigned int o = nbytes & 7;
++      __be64 msd = 0;
++
++      /* diff > 0: not enough input bytes: set most significant digits to 0 */
++      if (diff > 0) {
++              ndigits -= diff;
++              memset(&out[ndigits - 1], 0, diff * sizeof(u64));
++      }
++
++      if (o) {
++              memcpy((u8 *)&msd + sizeof(msd) - o, in, o);
++              out[--ndigits] = be64_to_cpu(msd);
++              in += o;
++      }
++      ecc_swap_digits(in, out, ndigits);
++}
++EXPORT_SYMBOL(ecc_digits_from_bytes);
++
+ static u64 *ecc_alloc_digits_space(unsigned int ndigits)
+ {
+       size_t len = ndigits * sizeof(u64);
+diff --git a/include/crypto/internal/ecc.h b/include/crypto/internal/ecc.h
+index ab722a8986b7..c0b8be63cbde 100644
+--- a/include/crypto/internal/ecc.h
++++ b/include/crypto/internal/ecc.h
+@@ -63,19 +63,8 @@ static inline void ecc_swap_digits(const void *in, u64 *out, unsigned int ndigit
+  * @out       Output digits array
+  * @ndigits:  Number of digits to create from byte array
+  */
+-static inline void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes,
+-                                       u64 *out, unsigned int ndigits)
+-{
+-      unsigned int o = nbytes & 7;
+-      __be64 msd = 0;
+-
+-      if (o) {
+-              memcpy((u8 *)&msd + sizeof(msd) - o, in, o);
+-              out[--ndigits] = be64_to_cpu(msd);
+-              in += o;
+-      }
+-      ecc_swap_digits(in, out, ndigits);
+-}
++void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes,
++                         u64 *out, unsigned int ndigits);
+ /**
+  * ecc_is_key_valid() - Validate a given ECDH private key
+-- 
+2.39.5
+
diff --git a/queue-6.6/crypto-ecdsa-avoid-signed-integer-overflow-on-signat.patch b/queue-6.6/crypto-ecdsa-avoid-signed-integer-overflow-on-signat.patch
new file mode 100644 (file)
index 0000000..767ab01
--- /dev/null
@@ -0,0 +1,82 @@
+From bff91a5e31a75df1b810958068278ff04294b171 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Sep 2024 16:30:24 +0200
+Subject: crypto: ecdsa - Avoid signed integer overflow on signature decoding
+
+From: Lukas Wunner <lukas@wunner.de>
+
+[ Upstream commit 3b0565c703503f832d6cd7ba805aafa3b330cb9d ]
+
+When extracting a signature component r or s from an ASN.1-encoded
+integer, ecdsa_get_signature_rs() subtracts the expected length
+"bufsize" from the ASN.1 length "vlen" (both of unsigned type size_t)
+and stores the result in "diff" (of signed type ssize_t).
+
+This results in a signed integer overflow if vlen > SSIZE_MAX + bufsize.
+
+The kernel is compiled with -fno-strict-overflow, which implies -fwrapv,
+meaning signed integer overflow is not undefined behavior.  And the
+function does check for overflow:
+
+       if (-diff >= bufsize)
+               return -EINVAL;
+
+So the code is fine in principle but not very obvious.  In the future it
+might trigger a false-positive with CONFIG_UBSAN_SIGNED_WRAP=y.
+
+Avoid by comparing the two unsigned variables directly and erroring out
+if "vlen" is too large.
+
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/ecdsa.c | 19 +++++++------------
+ 1 file changed, 7 insertions(+), 12 deletions(-)
+
+diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c
+index 28441311af36..da04df3c8ecf 100644
+--- a/crypto/ecdsa.c
++++ b/crypto/ecdsa.c
+@@ -36,29 +36,24 @@ static int ecdsa_get_signature_rs(u64 *dest, size_t hdrlen, unsigned char tag,
+                                 const void *value, size_t vlen, unsigned int ndigits)
+ {
+       size_t bufsize = ndigits * sizeof(u64);
+-      ssize_t diff = vlen - bufsize;
+       const char *d = value;
+-      if (!value || !vlen)
++      if (!value || !vlen || vlen > bufsize + 1)
+               return -EINVAL;
+-      /* diff = 0: 'value' has exacly the right size
+-       * diff > 0: 'value' has too many bytes; one leading zero is allowed that
+-       *           makes the value a positive integer; error on more
+-       * diff < 0: 'value' is missing leading zeros
++      /*
++       * vlen may be 1 byte larger than bufsize due to a leading zero byte
++       * (necessary if the most significant bit of the integer is set).
+        */
+-      if (diff > 0) {
++      if (vlen > bufsize) {
+               /* skip over leading zeros that make 'value' a positive int */
+               if (*d == 0) {
+                       vlen -= 1;
+-                      diff--;
+                       d++;
+-              }
+-              if (diff)
++              } else {
+                       return -EINVAL;
++              }
+       }
+-      if (-diff >= bufsize)
+-              return -EINVAL;
+       ecc_digits_from_bytes(d, vlen, dest, ndigits);
+-- 
+2.39.5
+
diff --git a/queue-6.6/crypto-ecdsa-convert-byte-arrays-with-key-coordinate.patch b/queue-6.6/crypto-ecdsa-convert-byte-arrays-with-key-coordinate.patch
new file mode 100644 (file)
index 0000000..c3e1d67
--- /dev/null
@@ -0,0 +1,102 @@
+From 966f3aba5338678e38a7fec2811bda90f75ebaf4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Apr 2024 10:18:45 -0400
+Subject: crypto: ecdsa - Convert byte arrays with key coordinates to digits
+
+From: Stefan Berger <stefanb@linux.ibm.com>
+
+[ Upstream commit d67c96fb97b5811e15c881d5cb72e293faa5f8e1 ]
+
+For NIST P192/256/384 the public key's x and y parameters could be copied
+directly from a given array since both parameters filled 'ndigits' of
+digits (a 'digit' is a u64). For support of NIST P521 the key parameters
+need to have leading zeros prepended to the most significant digit since
+only 2 bytes of the most significant digit are provided.
+
+Therefore, implement ecc_digits_from_bytes to convert a byte array into an
+array of digits and use this function in ecdsa_set_pub_key where an input
+byte array needs to be converted into digits.
+
+Suggested-by: Lukas Wunner <lukas@wunner.de>
+Tested-by: Lukas Wunner <lukas@wunner.de>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: 3b0565c70350 ("crypto: ecdsa - Avoid signed integer overflow on signature decoding")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/ecdsa.c                | 14 +++++++++-----
+ include/crypto/internal/ecc.h | 21 +++++++++++++++++++++
+ 2 files changed, 30 insertions(+), 5 deletions(-)
+
+diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c
+index 3f9ec273a121..e819d0983bd3 100644
+--- a/crypto/ecdsa.c
++++ b/crypto/ecdsa.c
+@@ -222,9 +222,8 @@ static int ecdsa_ecc_ctx_reset(struct ecc_ctx *ctx)
+ static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsigned int keylen)
+ {
+       struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
++      unsigned int digitlen, ndigits;
+       const unsigned char *d = key;
+-      const u64 *digits = (const u64 *)&d[1];
+-      unsigned int ndigits;
+       int ret;
+       ret = ecdsa_ecc_ctx_reset(ctx);
+@@ -238,12 +237,17 @@ static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsig
+               return -EINVAL;
+       keylen--;
+-      ndigits = (keylen >> 1) / sizeof(u64);
++      digitlen = keylen >> 1;
++
++      ndigits = DIV_ROUND_UP(digitlen, sizeof(u64));
+       if (ndigits != ctx->curve->g.ndigits)
+               return -EINVAL;
+-      ecc_swap_digits(digits, ctx->pub_key.x, ndigits);
+-      ecc_swap_digits(&digits[ndigits], ctx->pub_key.y, ndigits);
++      d++;
++
++      ecc_digits_from_bytes(d, digitlen, ctx->pub_key.x, ndigits);
++      ecc_digits_from_bytes(&d[digitlen], digitlen, ctx->pub_key.y, ndigits);
++
+       ret = ecc_is_pubkey_valid_full(ctx->curve, &ctx->pub_key);
+       ctx->pub_key_set = ret == 0;
+diff --git a/include/crypto/internal/ecc.h b/include/crypto/internal/ecc.h
+index 4f6c1a68882f..ab722a8986b7 100644
+--- a/include/crypto/internal/ecc.h
++++ b/include/crypto/internal/ecc.h
+@@ -56,6 +56,27 @@ static inline void ecc_swap_digits(const void *in, u64 *out, unsigned int ndigit
+               out[i] = get_unaligned_be64(&src[ndigits - 1 - i]);
+ }
++/**
++ * ecc_digits_from_bytes() - Create ndigits-sized digits array from byte array
++ * @in:       Input byte array
++ * @nbytes    Size of input byte array
++ * @out       Output digits array
++ * @ndigits:  Number of digits to create from byte array
++ */
++static inline void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes,
++                                       u64 *out, unsigned int ndigits)
++{
++      unsigned int o = nbytes & 7;
++      __be64 msd = 0;
++
++      if (o) {
++              memcpy((u8 *)&msd + sizeof(msd) - o, in, o);
++              out[--ndigits] = be64_to_cpu(msd);
++              in += o;
++      }
++      ecc_swap_digits(in, out, ndigits);
++}
++
+ /**
+  * ecc_is_key_valid() - Validate a given ECDH private key
+  *
+-- 
+2.39.5
+
diff --git a/queue-6.6/crypto-ecdsa-rename-keylen-to-bufsize-where-necessar.patch b/queue-6.6/crypto-ecdsa-rename-keylen-to-bufsize-where-necessar.patch
new file mode 100644 (file)
index 0000000..b294ec3
--- /dev/null
@@ -0,0 +1,78 @@
+From 6bbf61bedb7d51bc6aed1110b9c58e0fc950b14c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Apr 2024 10:18:53 -0400
+Subject: crypto: ecdsa - Rename keylen to bufsize where necessary
+
+From: Stefan Berger <stefanb@linux.ibm.com>
+
+[ Upstream commit 703ca5cda1ea04735e48882a7cccff97d57656c3 ]
+
+In cases where 'keylen' was referring to the size of the buffer used by
+a curve's digits, it does not reflect the purpose of the variable anymore
+once NIST P521 is used. What it refers to then is the size of the buffer,
+which may be a few bytes larger than the size a coordinate of a key.
+Therefore, rename keylen to bufsize where appropriate.
+
+Tested-by: Lukas Wunner <lukas@wunner.de>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: 3b0565c70350 ("crypto: ecdsa - Avoid signed integer overflow on signature decoding")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/ecdsa.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c
+index e819d0983bd3..142bed98fa97 100644
+--- a/crypto/ecdsa.c
++++ b/crypto/ecdsa.c
+@@ -35,8 +35,8 @@ struct ecdsa_signature_ctx {
+ static int ecdsa_get_signature_rs(u64 *dest, size_t hdrlen, unsigned char tag,
+                                 const void *value, size_t vlen, unsigned int ndigits)
+ {
+-      size_t keylen = ndigits * sizeof(u64);
+-      ssize_t diff = vlen - keylen;
++      size_t bufsize = ndigits * sizeof(u64);
++      ssize_t diff = vlen - bufsize;
+       const char *d = value;
+       u8 rs[ECC_MAX_BYTES];
+@@ -58,7 +58,7 @@ static int ecdsa_get_signature_rs(u64 *dest, size_t hdrlen, unsigned char tag,
+               if (diff)
+                       return -EINVAL;
+       }
+-      if (-diff >= keylen)
++      if (-diff >= bufsize)
+               return -EINVAL;
+       if (diff) {
+@@ -138,7 +138,7 @@ static int ecdsa_verify(struct akcipher_request *req)
+ {
+       struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+       struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
+-      size_t keylen = ctx->curve->g.ndigits * sizeof(u64);
++      size_t bufsize = ctx->curve->g.ndigits * sizeof(u64);
+       struct ecdsa_signature_ctx sig_ctx = {
+               .curve = ctx->curve,
+       };
+@@ -165,14 +165,14 @@ static int ecdsa_verify(struct akcipher_request *req)
+               goto error;
+       /* if the hash is shorter then we will add leading zeros to fit to ndigits */
+-      diff = keylen - req->dst_len;
++      diff = bufsize - req->dst_len;
+       if (diff >= 0) {
+               if (diff)
+                       memset(rawhash, 0, diff);
+               memcpy(&rawhash[diff], buffer + req->src_len, req->dst_len);
+       } else if (diff < 0) {
+               /* given hash is longer, we take the left-most bytes */
+-              memcpy(&rawhash, buffer + req->src_len, keylen);
++              memcpy(&rawhash, buffer + req->src_len, bufsize);
+       }
+       ecc_swap_digits((u64 *)rawhash, hash, ctx->curve->g.ndigits);
+-- 
+2.39.5
+
diff --git a/queue-6.6/crypto-ecdsa-use-ecc_digits_from_bytes-to-convert-si.patch b/queue-6.6/crypto-ecdsa-use-ecc_digits_from_bytes-to-convert-si.patch
new file mode 100644 (file)
index 0000000..389c991
--- /dev/null
@@ -0,0 +1,64 @@
+From 25239e3755b80ba5f1c7adb673d3d3b1e8007fc0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 May 2024 19:08:27 -0400
+Subject: crypto: ecdsa - Use ecc_digits_from_bytes to convert signature
+
+From: Stefan Berger <stefanb@linux.ibm.com>
+
+[ Upstream commit 546ce0bdc91afd9f5c4c67d9fc4733e0fc7086d1 ]
+
+Since ecc_digits_from_bytes will provide zeros when an insufficient number
+of bytes are passed in the input byte array, use it to convert the r and s
+components of the signature to digits directly from the input byte
+array. This avoids going through an intermediate byte array that has the
+first few bytes filled with zeros.
+
+Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: 3b0565c70350 ("crypto: ecdsa - Avoid signed integer overflow on signature decoding")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/ecdsa.c | 12 ++----------
+ 1 file changed, 2 insertions(+), 10 deletions(-)
+
+diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c
+index 142bed98fa97..28441311af36 100644
+--- a/crypto/ecdsa.c
++++ b/crypto/ecdsa.c
+@@ -38,7 +38,6 @@ static int ecdsa_get_signature_rs(u64 *dest, size_t hdrlen, unsigned char tag,
+       size_t bufsize = ndigits * sizeof(u64);
+       ssize_t diff = vlen - bufsize;
+       const char *d = value;
+-      u8 rs[ECC_MAX_BYTES];
+       if (!value || !vlen)
+               return -EINVAL;
+@@ -46,7 +45,7 @@ static int ecdsa_get_signature_rs(u64 *dest, size_t hdrlen, unsigned char tag,
+       /* diff = 0: 'value' has exacly the right size
+        * diff > 0: 'value' has too many bytes; one leading zero is allowed that
+        *           makes the value a positive integer; error on more
+-       * diff < 0: 'value' is missing leading zeros, which we add
++       * diff < 0: 'value' is missing leading zeros
+        */
+       if (diff > 0) {
+               /* skip over leading zeros that make 'value' a positive int */
+@@ -61,14 +60,7 @@ static int ecdsa_get_signature_rs(u64 *dest, size_t hdrlen, unsigned char tag,
+       if (-diff >= bufsize)
+               return -EINVAL;
+-      if (diff) {
+-              /* leading zeros not given in 'value' */
+-              memset(rs, 0, -diff);
+-      }
+-
+-      memcpy(&rs[-diff], d, vlen);
+-
+-      ecc_swap_digits((u64 *)rs, dest, ndigits);
++      ecc_digits_from_bytes(d, vlen, dest, ndigits);
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.6/docs-media-update-location-of-the-media-patches.patch b/queue-6.6/docs-media-update-location-of-the-media-patches.patch
new file mode 100644 (file)
index 0000000..33e63c8
--- /dev/null
@@ -0,0 +1,52 @@
+From d59373db606b374e6108c4107d48b0eaf9506573 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Nov 2024 07:05:54 +0100
+Subject: docs: media: update location of the media patches
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit 72ad4ff638047bbbdf3232178fea4bec1f429319 ]
+
+Due to recent changes on the way we're maintaining media, the
+location of the main tree was updated.
+
+Change docs accordingly.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/admin-guide/media/building.rst | 2 +-
+ Documentation/admin-guide/media/saa7134.rst  | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/admin-guide/media/building.rst b/Documentation/admin-guide/media/building.rst
+index a06473429916..7a413ba07f93 100644
+--- a/Documentation/admin-guide/media/building.rst
++++ b/Documentation/admin-guide/media/building.rst
+@@ -15,7 +15,7 @@ Please notice, however, that, if:
+ you should use the main media development tree ``master`` branch:
+-    https://git.linuxtv.org/media_tree.git/
++    https://git.linuxtv.org/media.git/
+ In this case, you may find some useful information at the
+ `LinuxTv wiki pages <https://linuxtv.org/wiki>`_:
+diff --git a/Documentation/admin-guide/media/saa7134.rst b/Documentation/admin-guide/media/saa7134.rst
+index 51eae7eb5ab7..18d7cbc897db 100644
+--- a/Documentation/admin-guide/media/saa7134.rst
++++ b/Documentation/admin-guide/media/saa7134.rst
+@@ -67,7 +67,7 @@ Changes / Fixes
+ Please mail to linux-media AT vger.kernel.org unified diffs against
+ the linux media git tree:
+-    https://git.linuxtv.org/media_tree.git/
++    https://git.linuxtv.org/media.git/
+ This is done by committing a patch at a clone of the git tree and
+ submitting the patch using ``git send-email``. Don't forget to
+-- 
+2.39.5
+
diff --git a/queue-6.6/drm-amd-display-fix-dsc-re-computing.patch b/queue-6.6/drm-amd-display-fix-dsc-re-computing.patch
new file mode 100644 (file)
index 0000000..41ad0e7
--- /dev/null
@@ -0,0 +1,74 @@
+From 6c2f9aa834ccdc6080a18cd85574238abe914960 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Apr 2024 13:53:52 -0400
+Subject: drm/amd/display: Fix DSC-re-computing
+
+From: Agustin Gutierrez <agustin.gutierrez@amd.com>
+
+[ Upstream commit b9b5a82c532109a09f4340ef5cabdfdbb0691a9d ]
+
+[Why]
+This fixes a bug introduced by commit c53655545141 ("drm/amd/display: dsc
+mst re-compute pbn for changes on hub").
+The change caused light-up issues with a second display that required
+DSC on some MST docks.
+
+[How]
+Use Virtual DPCD for DSC caps in MST case.
+
+[Limitations]
+This change only affects MST DSC devices that follow specifications
+additional changes are required to check for old MST DSC devices such as
+ones which do not check for Virtual DPCD registers.
+
+Reviewed-by: Swapnil Patel <swapnil.patel@amd.com>
+Reviewed-by: Hersen Wu <hersenxs.wu@amd.com>
+Acked-by: Tom Chung <chiahsuan.chung@amd.com>
+Signed-off-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: 4641169a8c95 ("drm/amd/display: Fix incorrect DSC recompute trigger")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../display/amdgpu_dm/amdgpu_dm_mst_types.c    | 18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+index 9ec9792f115a..b4bbd3be35a6 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+@@ -1219,10 +1219,6 @@ static bool is_dsc_need_re_compute(
+       if (dc_link->type != dc_connection_mst_branch)
+               return false;
+-      if (!(dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT ||
+-              dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT))
+-              return false;
+-
+       for (i = 0; i < MAX_PIPES; i++)
+               stream_on_link[i] = NULL;
+@@ -1240,7 +1236,19 @@ static bool is_dsc_need_re_compute(
+                       continue;
+               aconnector = (struct amdgpu_dm_connector *) stream->dm_stream_context;
+-              if (!aconnector)
++              if (!aconnector || !aconnector->dsc_aux)
++                      continue;
++
++              /*
++               *      Check if cached virtual MST DSC caps are available and DSC is supported
++               *      this change takes care of newer MST DSC capable devices that report their
++               *      DPCD caps as per specifications in their Virtual DPCD registers.
++
++               *      TODO: implement the check for older MST DSC devices that do not conform to
++               *      specifications.
++              */
++              if (!(aconnector->dc_sink->dsc_caps.dsc_dec_caps.is_dsc_supported ||
++                      aconnector->dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT))
+                       continue;
+               stream_on_link[new_stream_on_link_num] = aconnector;
+-- 
+2.39.5
+
diff --git a/queue-6.6/drm-amd-display-fix-incorrect-dsc-recompute-trigger.patch b/queue-6.6/drm-amd-display-fix-incorrect-dsc-recompute-trigger.patch
new file mode 100644 (file)
index 0000000..40555ac
--- /dev/null
@@ -0,0 +1,42 @@
+From 13ffe0d08973db083440582b0886462bb6b16b2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Sep 2024 16:56:45 -0400
+Subject: drm/amd/display: Fix incorrect DSC recompute trigger
+
+From: Fangzhi Zuo <Jerry.Zuo@amd.com>
+
+[ Upstream commit 4641169a8c95d9efc35d2d3c55c3948f3b375ff9 ]
+
+A stream without dsc_aux should not be eliminated from
+the dsc determination. Whether it needs a dsc recompute depends on
+whether its mode has changed or not. Eliminating such a no-dsc stream
+from the dsc determination policy will end up with inconsistencies
+in the new dc_state when compared to the current dc_state,
+triggering a dsc recompute that should not have happened.
+
+Reviewed-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
+Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
+Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+index b4bbd3be35a6..385a5a75fdf8 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+@@ -1236,7 +1236,7 @@ static bool is_dsc_need_re_compute(
+                       continue;
+               aconnector = (struct amdgpu_dm_connector *) stream->dm_stream_context;
+-              if (!aconnector || !aconnector->dsc_aux)
++              if (!aconnector)
+                       continue;
+               /*
+-- 
+2.39.5
+
diff --git a/queue-6.6/drm-radeon-delay-connector-detecting-when-hpd-singal.patch b/queue-6.6/drm-radeon-delay-connector-detecting-when-hpd-singal.patch
new file mode 100644 (file)
index 0000000..509fdbd
--- /dev/null
@@ -0,0 +1,47 @@
+From 20430c3e75a06c4736598de02404f768653d953a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 May 2024 16:57:58 +0800
+Subject: drm/radeon: Delay Connector detecting when HPD singals is unstable
+
+From: Shixiong Ou <oushixiong@kylinos.cn>
+
+[ Upstream commit 949658cb9b69ab9d22a42a662b2fdc7085689ed8 ]
+
+In some causes, HPD signals will jitter when plugging in
+or unplugging HDMI.
+
+Rescheduling the hotplug work for a second when EDID may still be
+readable but HDP is disconnected, and fixes this issue.
+
+Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: 979bfe291b5b ("Revert "drm/radeon: Delay Connector detecting when HPD singals is unstable"")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/radeon_connectors.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
+index b84b58926106..cf0114ca59a4 100644
+--- a/drivers/gpu/drm/radeon/radeon_connectors.c
++++ b/drivers/gpu/drm/radeon/radeon_connectors.c
+@@ -1267,6 +1267,16 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
+                       goto exit;
+               }
+       }
++
++      if (dret && radeon_connector->hpd.hpd != RADEON_HPD_NONE &&
++          !radeon_hpd_sense(rdev, radeon_connector->hpd.hpd) &&
++          connector->connector_type == DRM_MODE_CONNECTOR_HDMIA) {
++              DRM_DEBUG_KMS("EDID is readable when HPD disconnected\n");
++              schedule_delayed_work(&rdev->hotplug_work, msecs_to_jiffies(1000));
++              ret = connector_status_disconnected;
++              goto exit;
++      }
++
+       if (dret) {
+               radeon_connector->detected_by_load = false;
+               radeon_connector_free_edid(connector);
+-- 
+2.39.5
+
diff --git a/queue-6.6/ext4-convert-to-new-timestamp-accessors.patch b/queue-6.6/ext4-convert-to-new-timestamp-accessors.patch
new file mode 100644 (file)
index 0000000..1806ada
--- /dev/null
@@ -0,0 +1,351 @@
+From e75b016ff152c27764f4ffd046391b6b9577e58b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Oct 2023 14:52:20 -0400
+Subject: ext4: convert to new timestamp accessors
+
+From: Jeff Layton <jlayton@kernel.org>
+
+[ Upstream commit b898ab233611f7903d88c0b10f8145e1c15d3642 ]
+
+Convert to using the new inode timestamp accessor functions.
+
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Link: https://lore.kernel.org/r/20231004185347.80880-33-jlayton@kernel.org
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Stable-dep-of: c7fc0366c656 ("ext4: partial zero eof block on unaligned inode size extension")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/ext4.h    | 20 +++++++++++++++-----
+ fs/ext4/extents.c | 11 ++++++-----
+ fs/ext4/ialloc.c  |  4 ++--
+ fs/ext4/inline.c  |  4 ++--
+ fs/ext4/inode.c   | 19 ++++++++++---------
+ fs/ext4/ioctl.c   | 13 +++++++++++--
+ fs/ext4/namei.c   | 10 +++++-----
+ fs/ext4/super.c   |  2 +-
+ fs/ext4/xattr.c   |  8 ++++----
+ 9 files changed, 56 insertions(+), 35 deletions(-)
+
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index 3db01b933c3e..60455c84a937 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -891,10 +891,13 @@ do {                                                                             \
+               (raw_inode)->xtime = cpu_to_le32(clamp_t(int32_t, (ts).tv_sec, S32_MIN, S32_MAX));      \
+ } while (0)
+-#define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode)                         \
+-      EXT4_INODE_SET_XTIME_VAL(xtime, inode, raw_inode, (inode)->xtime)
++#define EXT4_INODE_SET_ATIME(inode, raw_inode)                                                \
++      EXT4_INODE_SET_XTIME_VAL(i_atime, inode, raw_inode, inode_get_atime(inode))
+-#define EXT4_INODE_SET_CTIME(inode, raw_inode)                                        \
++#define EXT4_INODE_SET_MTIME(inode, raw_inode)                                                \
++      EXT4_INODE_SET_XTIME_VAL(i_mtime, inode, raw_inode, inode_get_mtime(inode))
++
++#define EXT4_INODE_SET_CTIME(inode, raw_inode)                                                \
+       EXT4_INODE_SET_XTIME_VAL(i_ctime, inode, raw_inode, inode_get_ctime(inode))
+ #define EXT4_EINODE_SET_XTIME(xtime, einode, raw_inode)                               \
+@@ -910,9 +913,16 @@ do {                                                                              \
+                       .tv_sec = (signed)le32_to_cpu((raw_inode)->xtime)       \
+               })
+-#define EXT4_INODE_GET_XTIME(xtime, inode, raw_inode)                         \
++#define EXT4_INODE_GET_ATIME(inode, raw_inode)                                        \
++do {                                                                          \
++      inode_set_atime_to_ts(inode,                                            \
++              EXT4_INODE_GET_XTIME_VAL(i_atime, inode, raw_inode));           \
++} while (0)
++
++#define EXT4_INODE_GET_MTIME(inode, raw_inode)                                        \
+ do {                                                                          \
+-      (inode)->xtime = EXT4_INODE_GET_XTIME_VAL(xtime, inode, raw_inode);     \
++      inode_set_mtime_to_ts(inode,                                            \
++              EXT4_INODE_GET_XTIME_VAL(i_mtime, inode, raw_inode));           \
+ } while (0)
+ #define EXT4_INODE_GET_CTIME(inode, raw_inode)                                        \
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index 5ea75af6ca22..f2341d99d09f 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -4532,7 +4532,8 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
+                       if (epos > new_size)
+                               epos = new_size;
+                       if (ext4_update_inode_size(inode, epos) & 0x1)
+-                              inode->i_mtime = inode_get_ctime(inode);
++                              inode_set_mtime_to_ts(inode,
++                                                    inode_get_ctime(inode));
+               }
+               ret2 = ext4_mark_inode_dirty(handle, inode);
+               ext4_update_inode_fsync_trans(handle, inode, 1);
+@@ -4670,7 +4671,7 @@ static long ext4_zero_range(struct file *file, loff_t offset,
+               /* Now release the pages and zero block aligned part of pages */
+               truncate_pagecache_range(inode, start, end - 1);
+-              inode->i_mtime = inode_set_ctime_current(inode);
++              inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
+               ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size,
+                                            flags);
+@@ -4695,7 +4696,7 @@ static long ext4_zero_range(struct file *file, loff_t offset,
+               goto out_mutex;
+       }
+-      inode->i_mtime = inode_set_ctime_current(inode);
++      inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
+       if (new_size)
+               ext4_update_inode_size(inode, new_size);
+       ret = ext4_mark_inode_dirty(handle, inode);
+@@ -5431,7 +5432,7 @@ static int ext4_collapse_range(struct file *file, loff_t offset, loff_t len)
+       up_write(&EXT4_I(inode)->i_data_sem);
+       if (IS_SYNC(inode))
+               ext4_handle_sync(handle);
+-      inode->i_mtime = inode_set_ctime_current(inode);
++      inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
+       ret = ext4_mark_inode_dirty(handle, inode);
+       ext4_update_inode_fsync_trans(handle, inode, 1);
+@@ -5541,7 +5542,7 @@ static int ext4_insert_range(struct file *file, loff_t offset, loff_t len)
+       /* Expand file to avoid data loss if there is error while shifting */
+       inode->i_size += len;
+       EXT4_I(inode)->i_disksize += len;
+-      inode->i_mtime = inode_set_ctime_current(inode);
++      inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
+       ret = ext4_mark_inode_dirty(handle, inode);
+       if (ret)
+               goto out_stop;
+diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
+index d4d0ad689d3c..52f2959d29e6 100644
+--- a/fs/ext4/ialloc.c
++++ b/fs/ext4/ialloc.c
+@@ -1255,8 +1255,8 @@ struct inode *__ext4_new_inode(struct mnt_idmap *idmap,
+       inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb);
+       /* This is the optimal IO size (for stat), not the fs block size */
+       inode->i_blocks = 0;
+-      inode->i_mtime = inode->i_atime = inode_set_ctime_current(inode);
+-      ei->i_crtime = inode->i_mtime;
++      simple_inode_init_ts(inode);
++      ei->i_crtime = inode_get_mtime(inode);
+       memset(ei->i_data, 0, sizeof(ei->i_data));
+       ei->i_dir_start_lookup = 0;
+diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
+index cb65052ee3de..3f363276ddd3 100644
+--- a/fs/ext4/inline.c
++++ b/fs/ext4/inline.c
+@@ -1037,7 +1037,7 @@ static int ext4_add_dirent_to_inline(handle_t *handle,
+        * happen is that the times are slightly out of date
+        * and/or different from the directory change time.
+        */
+-      dir->i_mtime = inode_set_ctime_current(dir);
++      inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
+       ext4_update_dx_flag(dir);
+       inode_inc_iversion(dir);
+       return 1;
+@@ -2010,7 +2010,7 @@ int ext4_inline_data_truncate(struct inode *inode, int *has_inline)
+               ext4_orphan_del(handle, inode);
+       if (err == 0) {
+-              inode->i_mtime = inode_set_ctime_current(inode);
++              inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
+               err = ext4_mark_inode_dirty(handle, inode);
+               if (IS_SYNC(inode))
+                       ext4_handle_sync(handle);
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 18ec9106c5b0..04f25a04f35a 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -4055,7 +4055,7 @@ int ext4_punch_hole(struct file *file, loff_t offset, loff_t length)
+       if (IS_SYNC(inode))
+               ext4_handle_sync(handle);
+-      inode->i_mtime = inode_set_ctime_current(inode);
++      inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
+       ret2 = ext4_mark_inode_dirty(handle, inode);
+       if (unlikely(ret2))
+               ret = ret2;
+@@ -4215,7 +4215,7 @@ int ext4_truncate(struct inode *inode)
+       if (inode->i_nlink)
+               ext4_orphan_del(handle, inode);
+-      inode->i_mtime = inode_set_ctime_current(inode);
++      inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
+       err2 = ext4_mark_inode_dirty(handle, inode);
+       if (unlikely(err2 && !err))
+               err = err2;
+@@ -4319,8 +4319,8 @@ static int ext4_fill_raw_inode(struct inode *inode, struct ext4_inode *raw_inode
+       raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
+       EXT4_INODE_SET_CTIME(inode, raw_inode);
+-      EXT4_INODE_SET_XTIME(i_mtime, inode, raw_inode);
+-      EXT4_INODE_SET_XTIME(i_atime, inode, raw_inode);
++      EXT4_INODE_SET_MTIME(inode, raw_inode);
++      EXT4_INODE_SET_ATIME(inode, raw_inode);
+       EXT4_EINODE_SET_XTIME(i_crtime, ei, raw_inode);
+       raw_inode->i_dtime = cpu_to_le32(ei->i_dtime);
+@@ -4928,8 +4928,8 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
+       }
+       EXT4_INODE_GET_CTIME(inode, raw_inode);
+-      EXT4_INODE_GET_XTIME(i_mtime, inode, raw_inode);
+-      EXT4_INODE_GET_XTIME(i_atime, inode, raw_inode);
++      EXT4_INODE_GET_ATIME(inode, raw_inode);
++      EXT4_INODE_GET_MTIME(inode, raw_inode);
+       EXT4_EINODE_GET_XTIME(i_crtime, ei, raw_inode);
+       if (likely(!test_opt2(inode->i_sb, HURD_COMPAT))) {
+@@ -5054,8 +5054,8 @@ static void __ext4_update_other_inode_time(struct super_block *sb,
+               spin_lock(&ei->i_raw_lock);
+               EXT4_INODE_SET_CTIME(inode, raw_inode);
+-              EXT4_INODE_SET_XTIME(i_mtime, inode, raw_inode);
+-              EXT4_INODE_SET_XTIME(i_atime, inode, raw_inode);
++              EXT4_INODE_SET_MTIME(inode, raw_inode);
++              EXT4_INODE_SET_ATIME(inode, raw_inode);
+               ext4_inode_csum_set(inode, raw_inode, ei);
+               spin_unlock(&ei->i_raw_lock);
+               trace_ext4_other_inode_update_time(inode, orig_ino);
+@@ -5451,7 +5451,8 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
+                        * update c/mtime in shrink case below
+                        */
+                       if (!shrink)
+-                              inode->i_mtime = inode_set_ctime_current(inode);
++                              inode_set_mtime_to_ts(inode,
++                                                    inode_set_ctime_current(inode));
+                       if (shrink)
+                               ext4_fc_track_range(handle, inode,
+diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
+index 0bfe2ce589e2..4f931f80cb34 100644
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -312,13 +312,22 @@ static void swap_inode_data(struct inode *inode1, struct inode *inode2)
+       struct ext4_inode_info *ei1;
+       struct ext4_inode_info *ei2;
+       unsigned long tmp;
++      struct timespec64 ts1, ts2;
+       ei1 = EXT4_I(inode1);
+       ei2 = EXT4_I(inode2);
+       swap(inode1->i_version, inode2->i_version);
+-      swap(inode1->i_atime, inode2->i_atime);
+-      swap(inode1->i_mtime, inode2->i_mtime);
++
++      ts1 = inode_get_atime(inode1);
++      ts2 = inode_get_atime(inode2);
++      inode_set_atime_to_ts(inode1, ts2);
++      inode_set_atime_to_ts(inode2, ts1);
++
++      ts1 = inode_get_mtime(inode1);
++      ts2 = inode_get_mtime(inode2);
++      inode_set_mtime_to_ts(inode1, ts2);
++      inode_set_mtime_to_ts(inode2, ts1);
+       memswap(ei1->i_data, ei2->i_data, sizeof(ei1->i_data));
+       tmp = ei1->i_flags & EXT4_FL_SHOULD_SWAP;
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index 4de1f61bba76..96a048d3f51b 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -2210,7 +2210,7 @@ static int add_dirent_to_buf(handle_t *handle, struct ext4_filename *fname,
+        * happen is that the times are slightly out of date
+        * and/or different from the directory change time.
+        */
+-      dir->i_mtime = inode_set_ctime_current(dir);
++      inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
+       ext4_update_dx_flag(dir);
+       inode_inc_iversion(dir);
+       err2 = ext4_mark_inode_dirty(handle, dir);
+@@ -3248,7 +3248,7 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
+        * recovery. */
+       inode->i_size = 0;
+       ext4_orphan_add(handle, inode);
+-      dir->i_mtime = inode_set_ctime_current(dir);
++      inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
+       inode_set_ctime_current(inode);
+       retval = ext4_mark_inode_dirty(handle, inode);
+       if (retval)
+@@ -3323,7 +3323,7 @@ int __ext4_unlink(struct inode *dir, const struct qstr *d_name,
+               retval = ext4_delete_entry(handle, dir, de, bh);
+               if (retval)
+                       goto out_handle;
+-              dir->i_mtime = inode_set_ctime_current(dir);
++              inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
+               ext4_update_dx_flag(dir);
+               retval = ext4_mark_inode_dirty(handle, dir);
+               if (retval)
+@@ -3691,7 +3691,7 @@ static int ext4_setent(handle_t *handle, struct ext4_renament *ent,
+       if (ext4_has_feature_filetype(ent->dir->i_sb))
+               ent->de->file_type = file_type;
+       inode_inc_iversion(ent->dir);
+-      ent->dir->i_mtime = inode_set_ctime_current(ent->dir);
++      inode_set_mtime_to_ts(ent->dir, inode_set_ctime_current(ent->dir));
+       retval = ext4_mark_inode_dirty(handle, ent->dir);
+       BUFFER_TRACE(ent->bh, "call ext4_handle_dirty_metadata");
+       if (!ent->inlined) {
+@@ -4006,7 +4006,7 @@ static int ext4_rename(struct mnt_idmap *idmap, struct inode *old_dir,
+               ext4_dec_count(new.inode);
+               inode_set_ctime_current(new.inode);
+       }
+-      old.dir->i_mtime = inode_set_ctime_current(old.dir);
++      inode_set_mtime_to_ts(old.dir, inode_set_ctime_current(old.dir));
+       ext4_update_dx_flag(old.dir);
+       if (old.dir_bh) {
+               retval = ext4_rename_dir_finish(handle, &old, new.dir->i_ino);
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 2346ef071b24..71ced0ada9a2 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -7180,7 +7180,7 @@ static int ext4_quota_off(struct super_block *sb, int type)
+       }
+       EXT4_I(inode)->i_flags &= ~(EXT4_NOATIME_FL | EXT4_IMMUTABLE_FL);
+       inode_set_flags(inode, 0, S_NOATIME | S_IMMUTABLE);
+-      inode->i_mtime = inode_set_ctime_current(inode);
++      inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
+       err = ext4_mark_inode_dirty(handle, inode);
+       ext4_journal_stop(handle);
+ out_unlock:
+diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+index f40785bc4e55..df5ab1a75fc4 100644
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -356,7 +356,7 @@ ext4_xattr_inode_hash(struct ext4_sb_info *sbi, const void *buffer, size_t size)
+ static u64 ext4_xattr_inode_get_ref(struct inode *ea_inode)
+ {
+-      return ((u64) inode_get_ctime(ea_inode).tv_sec << 32) |
++      return ((u64) inode_get_ctime_sec(ea_inode) << 32) |
+               (u32) inode_peek_iversion_raw(ea_inode);
+ }
+@@ -368,12 +368,12 @@ static void ext4_xattr_inode_set_ref(struct inode *ea_inode, u64 ref_count)
+ static u32 ext4_xattr_inode_get_hash(struct inode *ea_inode)
+ {
+-      return (u32)ea_inode->i_atime.tv_sec;
++      return (u32) inode_get_atime_sec(ea_inode);
+ }
+ static void ext4_xattr_inode_set_hash(struct inode *ea_inode, u32 hash)
+ {
+-      ea_inode->i_atime.tv_sec = hash;
++      inode_set_atime(ea_inode, hash, 0);
+ }
+ /*
+@@ -418,7 +418,7 @@ static int ext4_xattr_inode_read(struct inode *ea_inode, void *buf, size_t size)
+       return ret;
+ }
+-#define EXT4_XATTR_INODE_GET_PARENT(inode) ((__u32)(inode)->i_mtime.tv_sec)
++#define EXT4_XATTR_INODE_GET_PARENT(inode) ((__u32)(inode_get_mtime_sec(inode)))
+ static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino,
+                                u32 ea_inode_hash, struct inode **ea_inode)
+-- 
+2.39.5
+
diff --git a/queue-6.6/ext4-partial-zero-eof-block-on-unaligned-inode-size-.patch b/queue-6.6/ext4-partial-zero-eof-block-on-unaligned-inode-size-.patch
new file mode 100644 (file)
index 0000000..c09f2a7
--- /dev/null
@@ -0,0 +1,179 @@
+From b4c61306206b6b231fc73a688d1b6a45c019d998 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Sep 2024 12:07:40 -0400
+Subject: ext4: partial zero eof block on unaligned inode size extension
+
+From: Brian Foster <bfoster@redhat.com>
+
+[ Upstream commit c7fc0366c65628fd69bfc310affec4918199aae2 ]
+
+Using mapped writes, it's technically possible to expose stale
+post-eof data on a truncate up operation. Consider the following
+example:
+
+$ xfs_io -fc "pwrite 0 2k" -c "mmap 0 4k" -c "mwrite 2k 2k" \
+       -c "truncate 8k" -c "pread -v 2k 16" <file>
+...
+00000800:  58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58  XXXXXXXXXXXXXXXX
+...
+
+This shows that the post-eof data written via mwrite lands within
+EOF after a truncate up. While this is deliberate of the test case,
+behavior is somewhat unpredictable because writeback does post-eof
+zeroing, and writeback can occur at any time in the background. For
+example, an fsync inserted between the mwrite and truncate causes
+the subsequent read to instead return zeroes. This basically means
+that there is a race window in this situation between any subsequent
+extending operation and writeback that dictates whether post-eof
+data is exposed to the file or zeroed.
+
+To prevent this problem, perform partial block zeroing as part of
+the various inode size extending operations that are susceptible to
+it. For truncate extension, zero around the original eof similar to
+how truncate down does partial zeroing of the new eof. For extension
+via writes and fallocate related operations, zero the newly exposed
+range of the file to cover any partial zeroing that must occur at
+the original and new eof blocks.
+
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Link: https://patch.msgid.link/20240919160741.208162-2-bfoster@redhat.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/extents.c |  7 ++++++-
+ fs/ext4/inode.c   | 51 +++++++++++++++++++++++++++++++++--------------
+ 2 files changed, 42 insertions(+), 16 deletions(-)
+
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index f2341d99d09f..32218ac7f50f 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -4475,7 +4475,7 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
+       int depth = 0;
+       struct ext4_map_blocks map;
+       unsigned int credits;
+-      loff_t epos;
++      loff_t epos, old_size = i_size_read(inode);
+       BUG_ON(!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS));
+       map.m_lblk = offset;
+@@ -4534,6 +4534,11 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
+                       if (ext4_update_inode_size(inode, epos) & 0x1)
+                               inode_set_mtime_to_ts(inode,
+                                                     inode_get_ctime(inode));
++                      if (epos > old_size) {
++                              pagecache_isize_extended(inode, old_size, epos);
++                              ext4_zero_partial_blocks(handle, inode,
++                                                   old_size, epos - old_size);
++                      }
+               }
+               ret2 = ext4_mark_inode_dirty(handle, inode);
+               ext4_update_inode_fsync_trans(handle, inode, 1);
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 04f25a04f35a..19d7bcf16ebb 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -1328,8 +1328,10 @@ static int ext4_write_end(struct file *file,
+       folio_unlock(folio);
+       folio_put(folio);
+-      if (old_size < pos && !verity)
++      if (old_size < pos && !verity) {
+               pagecache_isize_extended(inode, old_size, pos);
++              ext4_zero_partial_blocks(handle, inode, old_size, pos - old_size);
++      }
+       /*
+        * Don't mark the inode dirty under folio lock. First, it unnecessarily
+        * makes the holding time of folio lock longer. Second, it forces lock
+@@ -1445,8 +1447,10 @@ static int ext4_journalled_write_end(struct file *file,
+       folio_unlock(folio);
+       folio_put(folio);
+-      if (old_size < pos && !verity)
++      if (old_size < pos && !verity) {
+               pagecache_isize_extended(inode, old_size, pos);
++              ext4_zero_partial_blocks(handle, inode, old_size, pos - old_size);
++      }
+       if (size_changed) {
+               ret2 = ext4_mark_inode_dirty(handle, inode);
+@@ -2971,7 +2975,8 @@ static int ext4_da_do_write_end(struct address_space *mapping,
+       struct inode *inode = mapping->host;
+       loff_t old_size = inode->i_size;
+       bool disksize_changed = false;
+-      loff_t new_i_size;
++      loff_t new_i_size, zero_len = 0;
++      handle_t *handle;
+       if (unlikely(!folio_buffers(folio))) {
+               folio_unlock(folio);
+@@ -3015,18 +3020,21 @@ static int ext4_da_do_write_end(struct address_space *mapping,
+       folio_unlock(folio);
+       folio_put(folio);
+-      if (old_size < pos)
++      if (pos > old_size) {
+               pagecache_isize_extended(inode, old_size, pos);
++              zero_len = pos - old_size;
++      }
+-      if (disksize_changed) {
+-              handle_t *handle;
++      if (!disksize_changed && !zero_len)
++              return copied;
+-              handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
+-              if (IS_ERR(handle))
+-                      return PTR_ERR(handle);
+-              ext4_mark_inode_dirty(handle, inode);
+-              ext4_journal_stop(handle);
+-      }
++      handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
++      if (IS_ERR(handle))
++              return PTR_ERR(handle);
++      if (zero_len)
++              ext4_zero_partial_blocks(handle, inode, old_size, zero_len);
++      ext4_mark_inode_dirty(handle, inode);
++      ext4_journal_stop(handle);
+       return copied;
+ }
+@@ -5437,6 +5445,14 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
+               }
+               if (attr->ia_size != inode->i_size) {
++                      /* attach jbd2 jinode for EOF folio tail zeroing */
++                      if (attr->ia_size & (inode->i_sb->s_blocksize - 1) ||
++                          oldsize & (inode->i_sb->s_blocksize - 1)) {
++                              error = ext4_inode_attach_jinode(inode);
++                              if (error)
++                                      goto err_out;
++                      }
++
+                       handle = ext4_journal_start(inode, EXT4_HT_INODE, 3);
+                       if (IS_ERR(handle)) {
+                               error = PTR_ERR(handle);
+@@ -5447,12 +5463,17 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
+                               orphan = 1;
+                       }
+                       /*
+-                       * Update c/mtime on truncate up, ext4_truncate() will
+-                       * update c/mtime in shrink case below
++                       * Update c/mtime and tail zero the EOF folio on
++                       * truncate up. ext4_truncate() handles the shrink case
++                       * below.
+                        */
+-                      if (!shrink)
++                      if (!shrink) {
+                               inode_set_mtime_to_ts(inode,
+                                                     inode_set_ctime_current(inode));
++                              if (oldsize & (inode->i_sb->s_blocksize - 1))
++                                      ext4_block_truncate_page(handle,
++                                                      inode->i_mapping, oldsize);
++                      }
+                       if (shrink)
+                               ext4_fc_track_range(handle, inode,
+-- 
+2.39.5
+
diff --git a/queue-6.6/fs-ntfs3-fix-warning-in-ni_fiemap.patch b/queue-6.6/fs-ntfs3-fix-warning-in-ni_fiemap.patch
new file mode 100644 (file)
index 0000000..902a9b6
--- /dev/null
@@ -0,0 +1,293 @@
+From ffe61420d97aacd8aa85cd89c8272ec22e62b5c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Oct 2024 10:48:15 +0300
+Subject: fs/ntfs3: Fix warning in ni_fiemap
+
+From: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+
+[ Upstream commit e2705dd3d16d1000f1fd8193d82447065de8c899 ]
+
+Use local runs_tree instead of cached. This way excludes rw_semaphore lock.
+
+Reported-by: syzbot+1c25748a40fe79b8a119@syzkaller.appspotmail.com
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/attrib.c  |   9 ++--
+ fs/ntfs3/frecord.c | 103 +++++++--------------------------------------
+ fs/ntfs3/ntfs_fs.h |   3 +-
+ 3 files changed, 21 insertions(+), 94 deletions(-)
+
+diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c
+index 582628b9b796..e25989dd2c6b 100644
+--- a/fs/ntfs3/attrib.c
++++ b/fs/ntfs3/attrib.c
+@@ -978,7 +978,7 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,
+       /* Check for compressed frame. */
+       err = attr_is_frame_compressed(ni, attr_b, vcn >> NTFS_LZNT_CUNIT,
+-                                     &hint);
++                                     &hint, run);
+       if (err)
+               goto out;
+@@ -1534,16 +1534,16 @@ int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr,
+  * attr_is_frame_compressed - Used to detect compressed frame.
+  *
+  * attr - base (primary) attribute segment.
++ * run  - run to use, usually == &ni->file.run.
+  * Only base segments contains valid 'attr->nres.c_unit'
+  */
+ int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr,
+-                           CLST frame, CLST *clst_data)
++                           CLST frame, CLST *clst_data, struct runs_tree *run)
+ {
+       int err;
+       u32 clst_frame;
+       CLST clen, lcn, vcn, alen, slen, vcn_next;
+       size_t idx;
+-      struct runs_tree *run;
+       *clst_data = 0;
+@@ -1555,7 +1555,6 @@ int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr,
+       clst_frame = 1u << attr->nres.c_unit;
+       vcn = frame * clst_frame;
+-      run = &ni->file.run;
+       if (!run_lookup_entry(run, vcn, &lcn, &clen, &idx)) {
+               err = attr_load_runs_vcn(ni, attr->type, attr_name(attr),
+@@ -1691,7 +1690,7 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size,
+       if (err)
+               goto out;
+-      err = attr_is_frame_compressed(ni, attr_b, frame, &clst_data);
++      err = attr_is_frame_compressed(ni, attr_b, frame, &clst_data, run);
+       if (err)
+               goto out;
+diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c
+index 12e03feb3074..3c876c468c2c 100644
+--- a/fs/ntfs3/frecord.c
++++ b/fs/ntfs3/frecord.c
+@@ -1900,46 +1900,6 @@ enum REPARSE_SIGN ni_parse_reparse(struct ntfs_inode *ni, struct ATTRIB *attr,
+       return REPARSE_LINK;
+ }
+-/*
+- * fiemap_fill_next_extent_k - a copy of fiemap_fill_next_extent
+- * but it uses 'fe_k' instead of fieinfo->fi_extents_start
+- */
+-static int fiemap_fill_next_extent_k(struct fiemap_extent_info *fieinfo,
+-                                   struct fiemap_extent *fe_k, u64 logical,
+-                                   u64 phys, u64 len, u32 flags)
+-{
+-      struct fiemap_extent extent;
+-
+-      /* only count the extents */
+-      if (fieinfo->fi_extents_max == 0) {
+-              fieinfo->fi_extents_mapped++;
+-              return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
+-      }
+-
+-      if (fieinfo->fi_extents_mapped >= fieinfo->fi_extents_max)
+-              return 1;
+-
+-      if (flags & FIEMAP_EXTENT_DELALLOC)
+-              flags |= FIEMAP_EXTENT_UNKNOWN;
+-      if (flags & FIEMAP_EXTENT_DATA_ENCRYPTED)
+-              flags |= FIEMAP_EXTENT_ENCODED;
+-      if (flags & (FIEMAP_EXTENT_DATA_TAIL | FIEMAP_EXTENT_DATA_INLINE))
+-              flags |= FIEMAP_EXTENT_NOT_ALIGNED;
+-
+-      memset(&extent, 0, sizeof(extent));
+-      extent.fe_logical = logical;
+-      extent.fe_physical = phys;
+-      extent.fe_length = len;
+-      extent.fe_flags = flags;
+-
+-      memcpy(fe_k + fieinfo->fi_extents_mapped, &extent, sizeof(extent));
+-
+-      fieinfo->fi_extents_mapped++;
+-      if (fieinfo->fi_extents_mapped == fieinfo->fi_extents_max)
+-              return 1;
+-      return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
+-}
+-
+ /*
+  * ni_fiemap - Helper for file_fiemap().
+  *
+@@ -1950,11 +1910,9 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
+             __u64 vbo, __u64 len)
+ {
+       int err = 0;
+-      struct fiemap_extent *fe_k = NULL;
+       struct ntfs_sb_info *sbi = ni->mi.sbi;
+       u8 cluster_bits = sbi->cluster_bits;
+-      struct runs_tree *run;
+-      struct rw_semaphore *run_lock;
++      struct runs_tree run;
+       struct ATTRIB *attr;
+       CLST vcn = vbo >> cluster_bits;
+       CLST lcn, clen;
+@@ -1965,13 +1923,11 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
+       u32 flags;
+       bool ok;
++      run_init(&run);
+       if (S_ISDIR(ni->vfs_inode.i_mode)) {
+-              run = &ni->dir.alloc_run;
+               attr = ni_find_attr(ni, NULL, NULL, ATTR_ALLOC, I30_NAME,
+                                   ARRAY_SIZE(I30_NAME), NULL, NULL);
+-              run_lock = &ni->dir.run_lock;
+       } else {
+-              run = &ni->file.run;
+               attr = ni_find_attr(ni, NULL, NULL, ATTR_DATA, NULL, 0, NULL,
+                                   NULL);
+               if (!attr) {
+@@ -1986,7 +1942,6 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
+                               "fiemap is not supported for compressed file (cp -r)");
+                       goto out;
+               }
+-              run_lock = &ni->file.run_lock;
+       }
+       if (!attr || !attr->non_res) {
+@@ -1998,51 +1953,33 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
+               goto out;
+       }
+-      /*
+-       * To avoid lock problems replace pointer to user memory by pointer to kernel memory.
+-       */
+-      fe_k = kmalloc_array(fieinfo->fi_extents_max,
+-                           sizeof(struct fiemap_extent),
+-                           GFP_NOFS | __GFP_ZERO);
+-      if (!fe_k) {
+-              err = -ENOMEM;
+-              goto out;
+-      }
+-
+       end = vbo + len;
+       alloc_size = le64_to_cpu(attr->nres.alloc_size);
+       if (end > alloc_size)
+               end = alloc_size;
+-      down_read(run_lock);
+       while (vbo < end) {
+               if (idx == -1) {
+-                      ok = run_lookup_entry(run, vcn, &lcn, &clen, &idx);
++                      ok = run_lookup_entry(&run, vcn, &lcn, &clen, &idx);
+               } else {
+                       CLST vcn_next = vcn;
+-                      ok = run_get_entry(run, ++idx, &vcn, &lcn, &clen) &&
++                      ok = run_get_entry(&run, ++idx, &vcn, &lcn, &clen) &&
+                            vcn == vcn_next;
+                       if (!ok)
+                               vcn = vcn_next;
+               }
+               if (!ok) {
+-                      up_read(run_lock);
+-                      down_write(run_lock);
+-
+                       err = attr_load_runs_vcn(ni, attr->type,
+                                                attr_name(attr),
+-                                               attr->name_len, run, vcn);
+-
+-                      up_write(run_lock);
+-                      down_read(run_lock);
++                                               attr->name_len, &run, vcn);
+                       if (err)
+                               break;
+-                      ok = run_lookup_entry(run, vcn, &lcn, &clen, &idx);
++                      ok = run_lookup_entry(&run, vcn, &lcn, &clen, &idx);
+                       if (!ok) {
+                               err = -EINVAL;
+@@ -2067,8 +2004,9 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
+               } else if (is_attr_compressed(attr)) {
+                       CLST clst_data;
+-                      err = attr_is_frame_compressed(
+-                              ni, attr, vcn >> attr->nres.c_unit, &clst_data);
++                      err = attr_is_frame_compressed(ni, attr,
++                                                     vcn >> attr->nres.c_unit,
++                                                     &clst_data, &run);
+                       if (err)
+                               break;
+                       if (clst_data < NTFS_LZNT_CLUSTERS)
+@@ -2097,8 +2035,8 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
+                       if (vbo + dlen >= end)
+                               flags |= FIEMAP_EXTENT_LAST;
+-                      err = fiemap_fill_next_extent_k(fieinfo, fe_k, vbo, lbo,
+-                                                      dlen, flags);
++                      err = fiemap_fill_next_extent(fieinfo, vbo, lbo, dlen,
++                                                    flags);
+                       if (err < 0)
+                               break;
+@@ -2119,8 +2057,7 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
+               if (vbo + bytes >= end)
+                       flags |= FIEMAP_EXTENT_LAST;
+-              err = fiemap_fill_next_extent_k(fieinfo, fe_k, vbo, lbo, bytes,
+-                                              flags);
++              err = fiemap_fill_next_extent(fieinfo, vbo, lbo, bytes, flags);
+               if (err < 0)
+                       break;
+               if (err == 1) {
+@@ -2131,19 +2068,8 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
+               vbo += bytes;
+       }
+-      up_read(run_lock);
+-
+-      /*
+-       * Copy to user memory out of lock
+-       */
+-      if (copy_to_user(fieinfo->fi_extents_start, fe_k,
+-                       fieinfo->fi_extents_max *
+-                               sizeof(struct fiemap_extent))) {
+-              err = -EFAULT;
+-      }
+-
+ out:
+-      kfree(fe_k);
++      run_close(&run);
+       return err;
+ }
+@@ -2674,7 +2600,8 @@ int ni_read_frame(struct ntfs_inode *ni, u64 frame_vbo, struct page **pages,
+               down_write(&ni->file.run_lock);
+               run_truncate_around(run, le64_to_cpu(attr->nres.svcn));
+               frame = frame_vbo >> (cluster_bits + NTFS_LZNT_CUNIT);
+-              err = attr_is_frame_compressed(ni, attr, frame, &clst_data);
++              err = attr_is_frame_compressed(ni, attr, frame, &clst_data,
++                                             run);
+               up_write(&ni->file.run_lock);
+               if (err)
+                       goto out1;
+diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h
+index cfe9d3bf07f9..c98e6868bfba 100644
+--- a/fs/ntfs3/ntfs_fs.h
++++ b/fs/ntfs3/ntfs_fs.h
+@@ -446,7 +446,8 @@ int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr,
+                       struct runs_tree *run, u64 frame, u64 frames,
+                       u8 frame_bits, u32 *ondisk_size, u64 *vbo_data);
+ int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr,
+-                           CLST frame, CLST *clst_data);
++                           CLST frame, CLST *clst_data,
++                           struct runs_tree *run);
+ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size,
+                       u64 new_valid);
+ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes);
+-- 
+2.39.5
+
diff --git a/queue-6.6/fs-ntfs3-implement-fallocate-for-compressed-files.patch b/queue-6.6/fs-ntfs3-implement-fallocate-for-compressed-files.patch
new file mode 100644 (file)
index 0000000..3c16cd2
--- /dev/null
@@ -0,0 +1,93 @@
+From 3e0d6209482e390039e43b4f876faf149173a248 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Jul 2024 17:45:12 +0300
+Subject: fs/ntfs3: Implement fallocate for compressed files
+
+From: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+
+[ Upstream commit 9a2d6a40b8a1a6fa62eaf47ceee10a5eef62284c ]
+
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Stable-dep-of: e2705dd3d16d ("fs/ntfs3: Fix warning in ni_fiemap")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/attrib.c | 25 +++++++++++++++----------
+ fs/ntfs3/inode.c  |  3 ++-
+ 2 files changed, 17 insertions(+), 11 deletions(-)
+
+diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c
+index fc6cea60044e..582628b9b796 100644
+--- a/fs/ntfs3/attrib.c
++++ b/fs/ntfs3/attrib.c
+@@ -977,15 +977,17 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,
+               goto out;
+       /* Check for compressed frame. */
+-      err = attr_is_frame_compressed(ni, attr, vcn >> NTFS_LZNT_CUNIT, &hint);
++      err = attr_is_frame_compressed(ni, attr_b, vcn >> NTFS_LZNT_CUNIT,
++                                     &hint);
+       if (err)
+               goto out;
+       if (hint) {
+               /* if frame is compressed - don't touch it. */
+               *lcn = COMPRESSED_LCN;
+-              *len = hint;
+-              err = -EOPNOTSUPP;
++              /* length to the end of frame. */
++              *len = NTFS_LZNT_CLUSTERS - (vcn & (NTFS_LZNT_CLUSTERS - 1));
++              err = 0;
+               goto out;
+       }
+@@ -1028,16 +1030,16 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,
+               /* Check if 'vcn' and 'vcn0' in different attribute segments. */
+               if (vcn < svcn || evcn1 <= vcn) {
+-                      /* Load attribute for truncated vcn. */
+-                      attr = ni_find_attr(ni, attr_b, &le, ATTR_DATA, NULL, 0,
+-                                          &vcn, &mi);
+-                      if (!attr) {
++                      struct ATTRIB *attr2;
++                      /* Load runs for truncated vcn. */
++                      attr2 = ni_find_attr(ni, attr_b, &le_b, ATTR_DATA, NULL,
++                                           0, &vcn, &mi);
++                      if (!attr2) {
+                               err = -EINVAL;
+                               goto out;
+                       }
+-                      svcn = le64_to_cpu(attr->nres.svcn);
+-                      evcn1 = le64_to_cpu(attr->nres.evcn) + 1;
+-                      err = attr_load_runs(attr, ni, run, NULL);
++                      evcn1 = le64_to_cpu(attr2->nres.evcn) + 1;
++                      err = attr_load_runs(attr2, ni, run, NULL);
+                       if (err)
+                               goto out;
+               }
+@@ -1530,6 +1532,9 @@ int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr,
+ /*
+  * attr_is_frame_compressed - Used to detect compressed frame.
++ *
++ * attr - base (primary) attribute segment.
++ * Only base segments contains valid 'attr->nres.c_unit'
+  */
+ int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr,
+                            CLST frame, CLST *clst_data)
+diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
+index 52b80fd15914..af7c0cbba74e 100644
+--- a/fs/ntfs3/inode.c
++++ b/fs/ntfs3/inode.c
+@@ -604,7 +604,8 @@ static noinline int ntfs_get_block_vbo(struct inode *inode, u64 vbo,
+       bytes = ((u64)len << cluster_bits) - off;
+-      if (lcn == SPARSE_LCN) {
++      if (lcn >= sbi->used.bitmap.nbits) {
++              /* This case includes resident/compressed/sparse. */
+               if (!create) {
+                       if (bh->b_size > bytes)
+                               bh->b_size = bytes;
+-- 
+2.39.5
+
diff --git a/queue-6.6/fs-smb-client-implement-chmod-for-smb3-posix-extensi.patch b/queue-6.6/fs-smb-client-implement-chmod-for-smb3-posix-extensi.patch
new file mode 100644 (file)
index 0000000..8023144
--- /dev/null
@@ -0,0 +1,248 @@
+From 5e439435fd1e50f0f2fc17e194fe5602c41bf82a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Nov 2024 11:05:13 +0100
+Subject: fs/smb/client: implement chmod() for SMB3 POSIX Extensions
+
+From: Ralph Boehme <slow@samba.org>
+
+[ Upstream commit d413eabff18d640031fc955d107ad9c03c3bf9f1 ]
+
+The NT ACL format for an SMB3 POSIX Extensions chmod() is a single ACE with the
+magic S-1-5-88-3-mode SID:
+
+  NT Security Descriptor
+      Revision: 1
+      Type: 0x8004, Self Relative, DACL Present
+      Offset to owner SID: 56
+      Offset to group SID: 124
+      Offset to SACL: 0
+      Offset to DACL: 20
+      Owner: S-1-5-21-3177838999-3893657415-1037673384-1000
+      Group: S-1-22-2-1000
+      NT User (DACL) ACL
+          Revision: NT4 (2)
+          Size: 36
+          Num ACEs: 1
+          NT ACE: S-1-5-88-3-438, flags 0x00, Access Allowed, mask 0x00000000
+              Type: Access Allowed
+              NT ACE Flags: 0x00
+              Size: 28
+              Access required: 0x00000000
+              SID: S-1-5-88-3-438
+
+Owner and Group should be NULL, but the server is not required to fail the
+request if they are present.
+
+Signed-off-by: Ralph Boehme <slow@samba.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/cifsacl.c   | 50 +++++++++++++++++++++++----------------
+ fs/smb/client/cifsproto.h |  4 +++-
+ fs/smb/client/inode.c     |  4 +++-
+ fs/smb/client/smb2pdu.c   |  2 +-
+ 4 files changed, 37 insertions(+), 23 deletions(-)
+
+diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c
+index e2ec1d934335..bff8d0dd74fe 100644
+--- a/fs/smb/client/cifsacl.c
++++ b/fs/smb/client/cifsacl.c
+@@ -885,12 +885,17 @@ unsigned int setup_authusers_ACE(struct smb_ace *pntace)
+  * Fill in the special SID based on the mode. See
+  * https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
+  */
+-unsigned int setup_special_mode_ACE(struct smb_ace *pntace, __u64 nmode)
++unsigned int setup_special_mode_ACE(struct smb_ace *pntace,
++                                  bool posix,
++                                  __u64 nmode)
+ {
+       int i;
+       unsigned int ace_size = 28;
+-      pntace->type = ACCESS_DENIED_ACE_TYPE;
++      if (posix)
++              pntace->type = ACCESS_ALLOWED_ACE_TYPE;
++      else
++              pntace->type = ACCESS_DENIED_ACE_TYPE;
+       pntace->flags = 0x0;
+       pntace->access_req = 0;
+       pntace->sid.num_subauth = 3;
+@@ -933,7 +938,8 @@ static void populate_new_aces(char *nacl_base,
+               struct smb_sid *pownersid,
+               struct smb_sid *pgrpsid,
+               __u64 *pnmode, u32 *pnum_aces, u16 *pnsize,
+-              bool modefromsid)
++              bool modefromsid,
++              bool posix)
+ {
+       __u64 nmode;
+       u32 num_aces = 0;
+@@ -950,13 +956,15 @@ static void populate_new_aces(char *nacl_base,
+       num_aces = *pnum_aces;
+       nsize = *pnsize;
+-      if (modefromsid) {
+-              pnntace = (struct smb_ace *) (nacl_base + nsize);
+-              nsize += setup_special_mode_ACE(pnntace, nmode);
+-              num_aces++;
++      if (modefromsid || posix) {
+               pnntace = (struct smb_ace *) (nacl_base + nsize);
+-              nsize += setup_authusers_ACE(pnntace);
++              nsize += setup_special_mode_ACE(pnntace, posix, nmode);
+               num_aces++;
++              if (modefromsid) {
++                      pnntace = (struct smb_ace *) (nacl_base + nsize);
++                      nsize += setup_authusers_ACE(pnntace);
++                      num_aces++;
++              }
+               goto set_size;
+       }
+@@ -1076,7 +1084,7 @@ static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *p
+ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
+               struct smb_sid *pownersid,      struct smb_sid *pgrpsid,
+-              __u64 *pnmode, bool mode_from_sid)
++              __u64 *pnmode, bool mode_from_sid, bool posix)
+ {
+       int i;
+       u16 size = 0;
+@@ -1094,11 +1102,11 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
+       nsize = sizeof(struct smb_acl);
+       /* If pdacl is NULL, we don't have a src. Simply populate new ACL. */
+-      if (!pdacl) {
++      if (!pdacl || posix) {
+               populate_new_aces(nacl_base,
+                               pownersid, pgrpsid,
+                               pnmode, &num_aces, &nsize,
+-                              mode_from_sid);
++                              mode_from_sid, posix);
+               goto finalize_dacl;
+       }
+@@ -1115,7 +1123,7 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
+                       populate_new_aces(nacl_base,
+                                       pownersid, pgrpsid,
+                                       pnmode, &num_aces, &nsize,
+-                                      mode_from_sid);
++                                      mode_from_sid, posix);
+                       new_aces_set = true;
+               }
+@@ -1144,7 +1152,7 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
+               populate_new_aces(nacl_base,
+                               pownersid, pgrpsid,
+                               pnmode, &num_aces, &nsize,
+-                              mode_from_sid);
++                              mode_from_sid, posix);
+               new_aces_set = true;
+       }
+@@ -1251,7 +1259,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
+ /* Convert permission bits from mode to equivalent CIFS ACL */
+ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
+       __u32 secdesclen, __u32 *pnsecdesclen, __u64 *pnmode, kuid_t uid, kgid_t gid,
+-      bool mode_from_sid, bool id_from_sid, int *aclflag)
++      bool mode_from_sid, bool id_from_sid, bool posix, int *aclflag)
+ {
+       int rc = 0;
+       __u32 dacloffset;
+@@ -1288,7 +1296,7 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
+               ndacl_ptr->num_aces = cpu_to_le32(0);
+               rc = set_chmod_dacl(dacl_ptr, ndacl_ptr, owner_sid_ptr, group_sid_ptr,
+-                                  pnmode, mode_from_sid);
++                                  pnmode, mode_from_sid, posix);
+               sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
+               /* copy the non-dacl portion of secdesc */
+@@ -1587,6 +1595,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
+       struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
+       struct smb_version_operations *ops;
+       bool mode_from_sid, id_from_sid;
++      bool posix = tlink_tcon(tlink)->posix_extensions;
+       const u32 info = 0;
+       if (IS_ERR(tlink))
+@@ -1622,12 +1631,13 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
+               id_from_sid = false;
+       /* Potentially, five new ACEs can be added to the ACL for U,G,O mapping */
+-      nsecdesclen = secdesclen;
+       if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
+-              if (mode_from_sid)
+-                      nsecdesclen += 2 * sizeof(struct smb_ace);
++              if (posix)
++                      nsecdesclen = 1 * sizeof(struct smb_ace);
++              else if (mode_from_sid)
++                      nsecdesclen = secdesclen + (2 * sizeof(struct smb_ace));
+               else /* cifsacl */
+-                      nsecdesclen += 5 * sizeof(struct smb_ace);
++                      nsecdesclen = secdesclen + (5 * sizeof(struct smb_ace));
+       } else { /* chown */
+               /* When ownership changes, changes new owner sid length could be different */
+               nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct smb_sid) * 2);
+@@ -1657,7 +1667,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
+       }
+       rc = build_sec_desc(pntsd, pnntsd, secdesclen, &nsecdesclen, pnmode, uid, gid,
+-                          mode_from_sid, id_from_sid, &aclflag);
++                          mode_from_sid, id_from_sid, posix, &aclflag);
+       cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
+diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
+index 6399dbd04625..a151ffffc6f3 100644
+--- a/fs/smb/client/cifsproto.h
++++ b/fs/smb/client/cifsproto.h
+@@ -242,7 +242,9 @@ extern int cifs_set_acl(struct mnt_idmap *idmap,
+ extern int set_cifs_acl(struct smb_ntsd *pntsd, __u32 len, struct inode *ino,
+                               const char *path, int flag);
+ extern unsigned int setup_authusers_ACE(struct smb_ace *pace);
+-extern unsigned int setup_special_mode_ACE(struct smb_ace *pace, __u64 nmode);
++extern unsigned int setup_special_mode_ACE(struct smb_ace *pace,
++                                         bool posix,
++                                         __u64 nmode);
+ extern unsigned int setup_special_user_owner_ACE(struct smb_ace *pace);
+ extern void dequeue_mid(struct mid_q_entry *mid, bool malformed);
+diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
+index ce7e0aed8f7d..b3e59a7c7120 100644
+--- a/fs/smb/client/inode.c
++++ b/fs/smb/client/inode.c
+@@ -3087,6 +3087,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
+       int rc = -EACCES;
+       __u32 dosattr = 0;
+       __u64 mode = NO_CHANGE_64;
++      bool posix = cifs_sb_master_tcon(cifs_sb)->posix_extensions;
+       xid = get_xid();
+@@ -3177,7 +3178,8 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
+               mode = attrs->ia_mode;
+               rc = 0;
+               if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) ||
+-                  (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)) {
++                  (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) ||
++                  posix) {
+                       rc = id_mode_to_cifs_acl(inode, full_path, &mode,
+                                               INVALID_UID, INVALID_GID);
+                       if (rc) {
+diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
+index 101c80f22d77..c012fbc2638e 100644
+--- a/fs/smb/client/smb2pdu.c
++++ b/fs/smb/client/smb2pdu.c
+@@ -2672,7 +2672,7 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len)
+       ptr += sizeof(struct smb3_acl);
+       /* create one ACE to hold the mode embedded in reserved special SID */
+-      acelen = setup_special_mode_ACE((struct smb_ace *)ptr, (__u64)mode);
++      acelen = setup_special_mode_ACE((struct smb_ace *)ptr, false, (__u64)mode);
+       ptr += acelen;
+       acl_size = acelen + sizeof(struct smb3_acl);
+       ace_count = 1;
+-- 
+2.39.5
+
diff --git a/queue-6.6/i2c-i801-add-support-for-intel-arrow-lake-h.patch b/queue-6.6/i2c-i801-add-support-for-intel-arrow-lake-h.patch
new file mode 100644 (file)
index 0000000..1144a2b
--- /dev/null
@@ -0,0 +1,76 @@
+From 7cd35e4a4c0091571c1de2b63531060d4ffb49d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Jun 2024 13:18:01 +0300
+Subject: i2c: i801: Add support for Intel Arrow Lake-H
+
+From: Jarkko Nikula <jarkko.nikula@linux.intel.com>
+
+[ Upstream commit f0eda4ddb2146a9f29d31b54c396f741bd0c82f1 ]
+
+Add SMBus PCI ID on Intel Arrow Lake-H.
+
+Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
+Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
+Stable-dep-of: bd492b583712 ("i2c: i801: Add support for Intel Panther Lake")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/i2c/busses/i2c-i801.rst | 1 +
+ drivers/i2c/busses/Kconfig            | 1 +
+ drivers/i2c/busses/i2c-i801.c         | 3 +++
+ 3 files changed, 5 insertions(+)
+
+diff --git a/Documentation/i2c/busses/i2c-i801.rst b/Documentation/i2c/busses/i2c-i801.rst
+index 10eced6c2e46..c840b597912c 100644
+--- a/Documentation/i2c/busses/i2c-i801.rst
++++ b/Documentation/i2c/busses/i2c-i801.rst
+@@ -48,6 +48,7 @@ Supported adapters:
+   * Intel Raptor Lake (PCH)
+   * Intel Meteor Lake (SOC and PCH)
+   * Intel Birch Stream (SOC)
++  * Intel Arrow Lake (SOC)
+    Datasheets: Publicly available at the Intel website
+diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
+index 97d27e01a6ee..0dc3c91f52a8 100644
+--- a/drivers/i2c/busses/Kconfig
++++ b/drivers/i2c/busses/Kconfig
+@@ -159,6 +159,7 @@ config I2C_I801
+           Raptor Lake (PCH)
+           Meteor Lake (SOC and PCH)
+           Birch Stream (SOC)
++          Arrow Lake (SOC)
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-i801.
+diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
+index 2b8bcd121ffa..ed943f303cdb 100644
+--- a/drivers/i2c/busses/i2c-i801.c
++++ b/drivers/i2c/busses/i2c-i801.c
+@@ -80,6 +80,7 @@
+  * Meteor Lake SoC-S (SOC)    0xae22  32      hard    yes     yes     yes
+  * Meteor Lake PCH-S (PCH)    0x7f23  32      hard    yes     yes     yes
+  * Birch Stream (SOC)         0x5796  32      hard    yes     yes     yes
++ * Arrow Lake-H (SOC)         0x7722  32      hard    yes     yes     yes
+  *
+  * Features supported by this driver:
+  * Software PEC                               no
+@@ -234,6 +235,7 @@
+ #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_M_SMBUS                0x54a3
+ #define PCI_DEVICE_ID_INTEL_BIRCH_STREAM_SMBUS                0x5796
+ #define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS             0x5ad4
++#define PCI_DEVICE_ID_INTEL_ARROW_LAKE_H_SMBUS                0x7722
+ #define PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_S_SMBUS               0x7a23
+ #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_S_SMBUS                0x7aa3
+ #define PCI_DEVICE_ID_INTEL_METEOR_LAKE_P_SMBUS               0x7e22
+@@ -1046,6 +1048,7 @@ static const struct pci_device_id i801_ids[] = {
+       { PCI_DEVICE_DATA(INTEL, METEOR_LAKE_SOC_S_SMBUS,       FEATURES_ICH5 | FEATURE_TCO_CNL) },
+       { PCI_DEVICE_DATA(INTEL, METEOR_LAKE_PCH_S_SMBUS,       FEATURES_ICH5 | FEATURE_TCO_CNL) },
+       { PCI_DEVICE_DATA(INTEL, BIRCH_STREAM_SMBUS,            FEATURES_ICH5 | FEATURE_TCO_CNL) },
++      { PCI_DEVICE_DATA(INTEL, ARROW_LAKE_H_SMBUS,            FEATURES_ICH5 | FEATURE_TCO_CNL) },
+       { 0, }
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.6/i2c-i801-add-support-for-intel-panther-lake.patch b/queue-6.6/i2c-i801-add-support-for-intel-panther-lake.patch
new file mode 100644 (file)
index 0000000..d56fec0
--- /dev/null
@@ -0,0 +1,78 @@
+From 844c2a3603523a5da2bb6a996dc26d275fe84a79 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Sep 2024 16:27:19 +0300
+Subject: i2c: i801: Add support for Intel Panther Lake
+
+From: Jarkko Nikula <jarkko.nikula@linux.intel.com>
+
+[ Upstream commit bd492b58371295d3ae26162b9666be584abad68a ]
+
+Add SMBus PCI IDs on Intel Panther Lake-P and -U.
+
+Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
+Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/i2c/busses/i2c-i801.rst | 1 +
+ drivers/i2c/busses/Kconfig            | 1 +
+ drivers/i2c/busses/i2c-i801.c         | 6 ++++++
+ 3 files changed, 8 insertions(+)
+
+diff --git a/Documentation/i2c/busses/i2c-i801.rst b/Documentation/i2c/busses/i2c-i801.rst
+index c840b597912c..47e8ac5b7099 100644
+--- a/Documentation/i2c/busses/i2c-i801.rst
++++ b/Documentation/i2c/busses/i2c-i801.rst
+@@ -49,6 +49,7 @@ Supported adapters:
+   * Intel Meteor Lake (SOC and PCH)
+   * Intel Birch Stream (SOC)
+   * Intel Arrow Lake (SOC)
++  * Intel Panther Lake (SOC)
+    Datasheets: Publicly available at the Intel website
+diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
+index 0dc3c91f52a8..982007a112c2 100644
+--- a/drivers/i2c/busses/Kconfig
++++ b/drivers/i2c/busses/Kconfig
+@@ -160,6 +160,7 @@ config I2C_I801
+           Meteor Lake (SOC and PCH)
+           Birch Stream (SOC)
+           Arrow Lake (SOC)
++          Panther Lake (SOC)
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-i801.
+diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
+index ed943f303cdb..18c04f5e41d9 100644
+--- a/drivers/i2c/busses/i2c-i801.c
++++ b/drivers/i2c/busses/i2c-i801.c
+@@ -81,6 +81,8 @@
+  * Meteor Lake PCH-S (PCH)    0x7f23  32      hard    yes     yes     yes
+  * Birch Stream (SOC)         0x5796  32      hard    yes     yes     yes
+  * Arrow Lake-H (SOC)         0x7722  32      hard    yes     yes     yes
++ * Panther Lake-H (SOC)               0xe322  32      hard    yes     yes     yes
++ * Panther Lake-P (SOC)               0xe422  32      hard    yes     yes     yes
+  *
+  * Features supported by this driver:
+  * Software PEC                               no
+@@ -258,6 +260,8 @@
+ #define PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS                0xa323
+ #define PCI_DEVICE_ID_INTEL_COMETLAKE_V_SMBUS         0xa3a3
+ #define PCI_DEVICE_ID_INTEL_METEOR_LAKE_SOC_S_SMBUS   0xae22
++#define PCI_DEVICE_ID_INTEL_PANTHER_LAKE_H_SMBUS      0xe322
++#define PCI_DEVICE_ID_INTEL_PANTHER_LAKE_P_SMBUS      0xe422
+ struct i801_mux_config {
+       char *gpio_chip;
+@@ -1049,6 +1053,8 @@ static const struct pci_device_id i801_ids[] = {
+       { PCI_DEVICE_DATA(INTEL, METEOR_LAKE_PCH_S_SMBUS,       FEATURES_ICH5 | FEATURE_TCO_CNL) },
+       { PCI_DEVICE_DATA(INTEL, BIRCH_STREAM_SMBUS,            FEATURES_ICH5 | FEATURE_TCO_CNL) },
+       { PCI_DEVICE_DATA(INTEL, ARROW_LAKE_H_SMBUS,            FEATURES_ICH5 | FEATURE_TCO_CNL) },
++      { PCI_DEVICE_DATA(INTEL, PANTHER_LAKE_H_SMBUS,          FEATURES_ICH5 | FEATURE_TCO_CNL) },
++      { PCI_DEVICE_DATA(INTEL, PANTHER_LAKE_P_SMBUS,          FEATURES_ICH5 | FEATURE_TCO_CNL) },
+       { 0, }
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.6/iio-adc-ad7192-convert-from-of-specific-to-fwnode-pr.patch b/queue-6.6/iio-adc-ad7192-convert-from-of-specific-to-fwnode-pr.patch
new file mode 100644 (file)
index 0000000..812942e
--- /dev/null
@@ -0,0 +1,152 @@
+From 1c8ce48a99bfd64f85b9e2ecce2ed846805075d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 Feb 2024 17:27:28 +0000
+Subject: iio: adc: ad7192: Convert from of specific to fwnode property
+ handling
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit c3708c829a0662af429897a90aed46b70f14a50b ]
+
+Enables use of with other firmwware types.
+Removes a case of device tree specific handlers that might get copied
+into new drivers.
+
+Cc: Alisa-Dariana Roman <alisa.roman@analog.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20240218172731.1023367-6-jic23@kernel.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: b7f99fa1b64a ("iio: adc: ad7192: properly check spi_get_device_match_data()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7192.c | 38 +++++++++++++++++++-------------------
+ 1 file changed, 19 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c
+index b64fd365f83f..ecaf87af539b 100644
+--- a/drivers/iio/adc/ad7192.c
++++ b/drivers/iio/adc/ad7192.c
+@@ -16,7 +16,9 @@
+ #include <linux/err.h>
+ #include <linux/sched.h>
+ #include <linux/delay.h>
+-#include <linux/of.h>
++#include <linux/module.h>
++#include <linux/mod_devicetable.h>
++#include <linux/property.h>
+ #include <linux/iio/iio.h>
+ #include <linux/iio/sysfs.h>
+@@ -360,19 +362,19 @@ static inline bool ad7192_valid_external_frequency(u32 freq)
+               freq <= AD7192_EXT_FREQ_MHZ_MAX);
+ }
+-static int ad7192_of_clock_select(struct ad7192_state *st)
++static int ad7192_clock_select(struct ad7192_state *st)
+ {
+-      struct device_node *np = st->sd.spi->dev.of_node;
++      struct device *dev = &st->sd.spi->dev;
+       unsigned int clock_sel;
+       clock_sel = AD7192_CLK_INT;
+       /* use internal clock */
+       if (!st->mclk) {
+-              if (of_property_read_bool(np, "adi,int-clock-output-enable"))
++              if (device_property_read_bool(dev, "adi,int-clock-output-enable"))
+                       clock_sel = AD7192_CLK_INT_CO;
+       } else {
+-              if (of_property_read_bool(np, "adi,clock-xtal"))
++              if (device_property_read_bool(dev, "adi,clock-xtal"))
+                       clock_sel = AD7192_CLK_EXT_MCLK1_2;
+               else
+                       clock_sel = AD7192_CLK_EXT_MCLK2;
+@@ -381,7 +383,7 @@ static int ad7192_of_clock_select(struct ad7192_state *st)
+       return clock_sel;
+ }
+-static int ad7192_setup(struct iio_dev *indio_dev, struct device_node *np)
++static int ad7192_setup(struct iio_dev *indio_dev, struct device *dev)
+ {
+       struct ad7192_state *st = iio_priv(indio_dev);
+       bool rej60_en, refin2_en;
+@@ -403,7 +405,7 @@ static int ad7192_setup(struct iio_dev *indio_dev, struct device_node *np)
+       id &= AD7192_ID_MASK;
+       if (id != st->chip_info->chip_id)
+-              dev_warn(&st->sd.spi->dev, "device ID query failed (0x%X != 0x%X)\n",
++              dev_warn(dev, "device ID query failed (0x%X != 0x%X)\n",
+                        id, st->chip_info->chip_id);
+       st->mode = AD7192_MODE_SEL(AD7192_MODE_IDLE) |
+@@ -412,31 +414,31 @@ static int ad7192_setup(struct iio_dev *indio_dev, struct device_node *np)
+       st->conf = AD7192_CONF_GAIN(0);
+-      rej60_en = of_property_read_bool(np, "adi,rejection-60-Hz-enable");
++      rej60_en = device_property_read_bool(dev, "adi,rejection-60-Hz-enable");
+       if (rej60_en)
+               st->mode |= AD7192_MODE_REJ60;
+-      refin2_en = of_property_read_bool(np, "adi,refin2-pins-enable");
++      refin2_en = device_property_read_bool(dev, "adi,refin2-pins-enable");
+       if (refin2_en && st->chip_info->chip_id != CHIPID_AD7195)
+               st->conf |= AD7192_CONF_REFSEL;
+       st->conf &= ~AD7192_CONF_CHOP;
+       st->f_order = AD7192_NO_SYNC_FILTER;
+-      buf_en = of_property_read_bool(np, "adi,buffer-enable");
++      buf_en = device_property_read_bool(dev, "adi,buffer-enable");
+       if (buf_en)
+               st->conf |= AD7192_CONF_BUF;
+-      bipolar = of_property_read_bool(np, "bipolar");
++      bipolar = device_property_read_bool(dev, "bipolar");
+       if (!bipolar)
+               st->conf |= AD7192_CONF_UNIPOLAR;
+-      burnout_curr_en = of_property_read_bool(np,
+-                                              "adi,burnout-currents-enable");
++      burnout_curr_en = device_property_read_bool(dev,
++                                                  "adi,burnout-currents-enable");
+       if (burnout_curr_en && buf_en) {
+               st->conf |= AD7192_CONF_BURN;
+       } else if (burnout_curr_en) {
+-              dev_warn(&st->sd.spi->dev,
++              dev_warn(dev,
+                        "Can't enable burnout currents: see CHOP or buffer\n");
+       }
+@@ -1036,9 +1038,7 @@ static int ad7192_probe(struct spi_device *spi)
+       }
+       st->int_vref_mv = ret / 1000;
+-      st->chip_info = of_device_get_match_data(&spi->dev);
+-      if (!st->chip_info)
+-              st->chip_info = (void *)spi_get_device_id(spi)->driver_data;
++      st->chip_info = spi_get_device_match_data(spi);
+       indio_dev->name = st->chip_info->name;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+@@ -1065,7 +1065,7 @@ static int ad7192_probe(struct spi_device *spi)
+       if (IS_ERR(st->mclk))
+               return PTR_ERR(st->mclk);
+-      st->clock_sel = ad7192_of_clock_select(st);
++      st->clock_sel = ad7192_clock_select(st);
+       if (st->clock_sel == AD7192_CLK_EXT_MCLK1_2 ||
+           st->clock_sel == AD7192_CLK_EXT_MCLK2) {
+@@ -1077,7 +1077,7 @@ static int ad7192_probe(struct spi_device *spi)
+               }
+       }
+-      ret = ad7192_setup(indio_dev, spi->dev.of_node);
++      ret = ad7192_setup(indio_dev, &spi->dev);
+       if (ret)
+               return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.6/iio-adc-ad7192-properly-check-spi_get_device_match_d.patch b/queue-6.6/iio-adc-ad7192-properly-check-spi_get_device_match_d.patch
new file mode 100644 (file)
index 0000000..4200804
--- /dev/null
@@ -0,0 +1,37 @@
+From 26f3ccd0be7348ec261a5bf86ee500214c3c43b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Oct 2024 17:01:21 +0200
+Subject: iio: adc: ad7192: properly check spi_get_device_match_data()
+
+From: Nuno Sa <nuno.sa@analog.com>
+
+[ Upstream commit b7f99fa1b64af2f696b13cec581cb4cd7d3982b8 ]
+
+spi_get_device_match_data() can return a NULL pointer. Hence, let's
+check for it.
+
+Signed-off-by: Nuno Sa <nuno.sa@analog.com>
+Link: https://patch.msgid.link/20241014-fix-error-check-v1-1-089e1003d12f@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7192.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c
+index ecaf87af539b..fa6810aa6a4a 100644
+--- a/drivers/iio/adc/ad7192.c
++++ b/drivers/iio/adc/ad7192.c
+@@ -1039,6 +1039,9 @@ static int ad7192_probe(struct spi_device *spi)
+       st->int_vref_mv = ret / 1000;
+       st->chip_info = spi_get_device_match_data(spi);
++      if (!st->chip_info)
++              return -ENODEV;
++
+       indio_dev->name = st->chip_info->name;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+-- 
+2.39.5
+
diff --git a/queue-6.6/mailbox-pcc-add-support-for-platform-notification-ha.patch b/queue-6.6/mailbox-pcc-add-support-for-platform-notification-ha.patch
new file mode 100644 (file)
index 0000000..5d757b1
--- /dev/null
@@ -0,0 +1,141 @@
+From 28f65e8200c4ee0a9a3f9bf6295026d76794cf61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Aug 2023 14:38:26 +0800
+Subject: mailbox: pcc: Add support for platform notification handling
+
+From: Huisong Li <lihuisong@huawei.com>
+
+[ Upstream commit 60c40b06fa68694dd08a1a0038ea8b9de3f3b1ca ]
+
+Currently, PCC driver doesn't support the processing of platform
+notification for type 4 PCC subspaces.
+
+According to ACPI specification, if platform sends a notification
+to OSPM, it must clear the command complete bit and trigger platform
+interrupt. OSPM needs to check whether the command complete bit is
+cleared, clear platform interrupt, process command, and then set the
+command complete and ring doorbell to the Platform.
+
+Let us stash the value of the pcc type and use the same while processing
+the interrupt of the channel. We also need to set the command complete
+bit and ring doorbell in the interrupt handler for the type 4 channel to
+complete the communication flow after processing the notification from
+the Platform.
+
+Signed-off-by: Huisong Li <lihuisong@huawei.com>
+Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
+Link: https://lore.kernel.org/r/20230801063827.25336-2-lihuisong@huawei.com
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Stable-dep-of: 7f9e19f207be ("mailbox: pcc: Check before sending MCTP PCC response ACK")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/pcc.c | 50 +++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 41 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
+index a44d4b3e5beb..80310b48bfb6 100644
+--- a/drivers/mailbox/pcc.c
++++ b/drivers/mailbox/pcc.c
+@@ -91,6 +91,7 @@ struct pcc_chan_reg {
+  * @cmd_update: PCC register bundle for the command complete update register
+  * @error: PCC register bundle for the error status register
+  * @plat_irq: platform interrupt
++ * @type: PCC subspace type
+  */
+ struct pcc_chan_info {
+       struct pcc_mbox_chan chan;
+@@ -100,12 +101,15 @@ struct pcc_chan_info {
+       struct pcc_chan_reg cmd_update;
+       struct pcc_chan_reg error;
+       int plat_irq;
++      u8 type;
+ };
+ #define to_pcc_chan_info(c) container_of(c, struct pcc_chan_info, chan)
+ static struct pcc_chan_info *chan_info;
+ static int pcc_chan_count;
++static int pcc_send_data(struct mbox_chan *chan, void *data);
++
+ /*
+  * PCC can be used with perf critical drivers such as CPPC
+  * So it makes sense to locally cache the virtual address and
+@@ -221,6 +225,34 @@ static int pcc_map_interrupt(u32 interrupt, u32 flags)
+       return acpi_register_gsi(NULL, interrupt, trigger, polarity);
+ }
++static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan)
++{
++      u64 val;
++      int ret;
++
++      ret = pcc_chan_reg_read(&pchan->cmd_complete, &val);
++      if (ret)
++              return false;
++
++      if (!pchan->cmd_complete.gas)
++              return true;
++
++      /*
++       * Judge if the channel respond the interrupt based on the value of
++       * command complete.
++       */
++      val &= pchan->cmd_complete.status_mask;
++      /*
++       * If this is PCC slave subspace channel, and the command complete
++       * bit 0 indicates that Platform is sending a notification and OSPM
++       * needs to respond this interrupt to process this command.
++       */
++      if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE)
++              return !val;
++
++      return !!val;
++}
++
+ /**
+  * pcc_mbox_irq - PCC mailbox interrupt handler
+  * @irq:      interrupt number
+@@ -236,17 +268,9 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
+       int ret;
+       pchan = chan->con_priv;
+-
+-      ret = pcc_chan_reg_read(&pchan->cmd_complete, &val);
+-      if (ret)
++      if (!pcc_mbox_cmd_complete_check(pchan))
+               return IRQ_NONE;
+-      if (val) { /* Ensure GAS exists and value is non-zero */
+-              val &= pchan->cmd_complete.status_mask;
+-              if (!val)
+-                      return IRQ_NONE;
+-      }
+-
+       ret = pcc_chan_reg_read(&pchan->error, &val);
+       if (ret)
+               return IRQ_NONE;
+@@ -262,6 +286,13 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
+       mbox_chan_received_data(chan, NULL);
++      /*
++       * The PCC slave subspace channel needs to set the command complete bit
++       * and ring doorbell after processing message.
++       */
++      if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE)
++              pcc_send_data(chan, NULL);
++
+       return IRQ_HANDLED;
+ }
+@@ -698,6 +729,7 @@ static int pcc_mbox_probe(struct platform_device *pdev)
+               pcc_parse_subspace_shmem(pchan, pcct_entry);
++              pchan->type = pcct_entry->type;
+               pcct_entry = (struct acpi_subtable_header *)
+                       ((unsigned long) pcct_entry + pcct_entry->length);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.6/mailbox-pcc-check-before-sending-mctp-pcc-response-a.patch b/queue-6.6/mailbox-pcc-check-before-sending-mctp-pcc-response-a.patch
new file mode 100644 (file)
index 0000000..431701f
--- /dev/null
@@ -0,0 +1,166 @@
+From 1ae935579de9c7756e39fd4620fd39b6a6e185f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Nov 2024 14:02:14 -0500
+Subject: mailbox: pcc: Check before sending MCTP PCC response ACK
+
+From: Adam Young <admiyo@os.amperecomputing.com>
+
+[ Upstream commit 7f9e19f207be0c534d517d65e01417ba968cdd34 ]
+
+Type 4 PCC channels have an option to send back a response
+to the platform when they are done processing the request.
+The flag to indicate whether or not to respond is inside
+the message body, and thus is not available to the pcc
+mailbox.
+
+If the flag is not set, still set command completion
+bit after processing message.
+
+In order to read the flag, this patch maps the shared
+buffer to virtual memory. To avoid duplication of mapping
+the shared buffer is then made available to be used by
+the driver that uses the mailbox.
+
+Signed-off-by: Adam Young <admiyo@os.amperecomputing.com>
+Cc: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/pcc.c | 61 +++++++++++++++++++++++++++++++++++++------
+ include/acpi/pcc.h    |  7 +++++
+ 2 files changed, 60 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
+index 94885e411085..82102a4c5d68 100644
+--- a/drivers/mailbox/pcc.c
++++ b/drivers/mailbox/pcc.c
+@@ -269,6 +269,35 @@ static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan)
+       return !!val;
+ }
++static void check_and_ack(struct pcc_chan_info *pchan, struct mbox_chan *chan)
++{
++      struct acpi_pcct_ext_pcc_shared_memory pcc_hdr;
++
++      if (pchan->type != ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE)
++              return;
++      /* If the memory region has not been mapped, we cannot
++       * determine if we need to send the message, but we still
++       * need to set the cmd_update flag before returning.
++       */
++      if (pchan->chan.shmem == NULL) {
++              pcc_chan_reg_read_modify_write(&pchan->cmd_update);
++              return;
++      }
++      memcpy_fromio(&pcc_hdr, pchan->chan.shmem,
++                    sizeof(struct acpi_pcct_ext_pcc_shared_memory));
++      /*
++       * The PCC slave subspace channel needs to set the command complete bit
++       * after processing message. If the PCC_ACK_FLAG is set, it should also
++       * ring the doorbell.
++       *
++       * The PCC master subspace channel clears chan_in_use to free channel.
++       */
++      if (le32_to_cpup(&pcc_hdr.flags) & PCC_ACK_FLAG_MASK)
++              pcc_send_data(chan, NULL);
++      else
++              pcc_chan_reg_read_modify_write(&pchan->cmd_update);
++}
++
+ /**
+  * pcc_mbox_irq - PCC mailbox interrupt handler
+  * @irq:      interrupt number
+@@ -306,14 +335,7 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
+       mbox_chan_received_data(chan, NULL);
+-      /*
+-       * The PCC slave subspace channel needs to set the command complete bit
+-       * and ring doorbell after processing message.
+-       *
+-       * The PCC master subspace channel clears chan_in_use to free channel.
+-       */
+-      if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE)
+-              pcc_send_data(chan, NULL);
++      check_and_ack(pchan, chan);
+       pchan->chan_in_use = false;
+       return IRQ_HANDLED;
+@@ -365,14 +387,37 @@ EXPORT_SYMBOL_GPL(pcc_mbox_request_channel);
+ void pcc_mbox_free_channel(struct pcc_mbox_chan *pchan)
+ {
+       struct mbox_chan *chan = pchan->mchan;
++      struct pcc_chan_info *pchan_info;
++      struct pcc_mbox_chan *pcc_mbox_chan;
+       if (!chan || !chan->cl)
+               return;
++      pchan_info = chan->con_priv;
++      pcc_mbox_chan = &pchan_info->chan;
++      if (pcc_mbox_chan->shmem) {
++              iounmap(pcc_mbox_chan->shmem);
++              pcc_mbox_chan->shmem = NULL;
++      }
+       mbox_free_channel(chan);
+ }
+ EXPORT_SYMBOL_GPL(pcc_mbox_free_channel);
++int pcc_mbox_ioremap(struct mbox_chan *chan)
++{
++      struct pcc_chan_info *pchan_info;
++      struct pcc_mbox_chan *pcc_mbox_chan;
++
++      if (!chan || !chan->cl)
++              return -1;
++      pchan_info = chan->con_priv;
++      pcc_mbox_chan = &pchan_info->chan;
++      pcc_mbox_chan->shmem = ioremap(pcc_mbox_chan->shmem_base_addr,
++                                     pcc_mbox_chan->shmem_size);
++      return 0;
++}
++EXPORT_SYMBOL_GPL(pcc_mbox_ioremap);
++
+ /**
+  * pcc_send_data - Called from Mailbox Controller code. Used
+  *            here only to ring the channel doorbell. The PCC client
+diff --git a/include/acpi/pcc.h b/include/acpi/pcc.h
+index 9b373d172a77..699c1a37b8e7 100644
+--- a/include/acpi/pcc.h
++++ b/include/acpi/pcc.h
+@@ -12,6 +12,7 @@
+ struct pcc_mbox_chan {
+       struct mbox_chan *mchan;
+       u64 shmem_base_addr;
++      void __iomem *shmem;
+       u64 shmem_size;
+       u32 latency;
+       u32 max_access_rate;
+@@ -31,11 +32,13 @@ struct pcc_mbox_chan {
+ #define PCC_CMD_COMPLETION_NOTIFY     BIT(0)
+ #define MAX_PCC_SUBSPACES     256
++#define PCC_ACK_FLAG_MASK     0x1
+ #ifdef CONFIG_PCC
+ extern struct pcc_mbox_chan *
+ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id);
+ extern void pcc_mbox_free_channel(struct pcc_mbox_chan *chan);
++extern int pcc_mbox_ioremap(struct mbox_chan *chan);
+ #else
+ static inline struct pcc_mbox_chan *
+ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id)
+@@ -43,6 +46,10 @@ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id)
+       return ERR_PTR(-ENODEV);
+ }
+ static inline void pcc_mbox_free_channel(struct pcc_mbox_chan *chan) { }
++static inline int pcc_mbox_ioremap(struct mbox_chan *chan)
++{
++      return 0;
++};
+ #endif
+ #endif /* _PCC_H */
+-- 
+2.39.5
+
diff --git a/queue-6.6/mailbox-pcc-support-shared-interrupt-for-multiple-su.patch b/queue-6.6/mailbox-pcc-support-shared-interrupt-for-multiple-su.patch
new file mode 100644 (file)
index 0000000..a93ab4a
--- /dev/null
@@ -0,0 +1,178 @@
+From d279bdd1a39fd44f0bc58f7088cb00359906a01d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Aug 2023 14:38:27 +0800
+Subject: mailbox: pcc: Support shared interrupt for multiple subspaces
+
+From: Huisong Li <lihuisong@huawei.com>
+
+[ Upstream commit 3db174e478cb0bb34888c20a531608b70aec9c1f ]
+
+If the platform acknowledge interrupt is level triggered, then it can
+be shared by multiple subspaces provided each one has a unique platform
+interrupt ack preserve and ack set masks.
+
+If it can be shared, then we can request the irq with IRQF_SHARED and
+IRQF_ONESHOT flags. The first one indicating it can be shared and the
+latter one to keep the interrupt disabled until the hardirq handler
+finished.
+
+Further, since there is no way to detect if the interrupt is for a given
+channel as the interrupt ack preserve and ack set masks are for clearing
+the interrupt and not for reading the status(in case Irq Ack register
+may be write-only on some platforms), we need a way to identify if the
+given channel is in use and expecting the interrupt.
+
+PCC type0, type1 and type5 do not support shared level triggered interrupt.
+The methods of determining whether a given channel for remaining types
+should respond to an interrupt are as follows:
+ - type2: Whether the interrupt belongs to a given channel is only
+          determined by the status field in Generic Communications Channel
+          Shared Memory Region, which is done in rx_callback of PCC client.
+ - type3: This channel checks chan_in_use flag first and then checks the
+          command complete bit(value '1' indicates that the command has
+          been completed).
+ - type4: Platform ensure that the default value of the command complete
+          bit corresponding to the type4 channel is '1'. This command
+          complete bit is '0' when receive a platform notification.
+
+The new field, 'chan_in_use' is used by the type only support the
+communication from OSPM to Platform (like type3) and should be completely
+ignored by other types so as to avoid too many type unnecessary checks in
+IRQ handler.
+
+Signed-off-by: Huisong Li <lihuisong@huawei.com>
+Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
+Link: https://lore.kernel.org/r/20230801063827.25336-3-lihuisong@huawei.com
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Stable-dep-of: 7f9e19f207be ("mailbox: pcc: Check before sending MCTP PCC response ACK")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/pcc.c | 43 ++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 40 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
+index 80310b48bfb6..94885e411085 100644
+--- a/drivers/mailbox/pcc.c
++++ b/drivers/mailbox/pcc.c
+@@ -92,6 +92,13 @@ struct pcc_chan_reg {
+  * @error: PCC register bundle for the error status register
+  * @plat_irq: platform interrupt
+  * @type: PCC subspace type
++ * @plat_irq_flags: platform interrupt flags
++ * @chan_in_use: this flag is used just to check if the interrupt needs
++ *            handling when it is shared. Since only one transfer can occur
++ *            at a time and mailbox takes care of locking, this flag can be
++ *            accessed without a lock. Note: the type only support the
++ *            communication from OSPM to Platform, like type3, use it, and
++ *            other types completely ignore it.
+  */
+ struct pcc_chan_info {
+       struct pcc_mbox_chan chan;
+@@ -102,6 +109,8 @@ struct pcc_chan_info {
+       struct pcc_chan_reg error;
+       int plat_irq;
+       u8 type;
++      unsigned int plat_irq_flags;
++      bool chan_in_use;
+ };
+ #define to_pcc_chan_info(c) container_of(c, struct pcc_chan_info, chan)
+@@ -225,6 +234,12 @@ static int pcc_map_interrupt(u32 interrupt, u32 flags)
+       return acpi_register_gsi(NULL, interrupt, trigger, polarity);
+ }
++static bool pcc_chan_plat_irq_can_be_shared(struct pcc_chan_info *pchan)
++{
++      return (pchan->plat_irq_flags & ACPI_PCCT_INTERRUPT_MODE) ==
++              ACPI_LEVEL_SENSITIVE;
++}
++
+ static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan)
+ {
+       u64 val;
+@@ -242,6 +257,7 @@ static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan)
+        * command complete.
+        */
+       val &= pchan->cmd_complete.status_mask;
++
+       /*
+        * If this is PCC slave subspace channel, and the command complete
+        * bit 0 indicates that Platform is sending a notification and OSPM
+@@ -268,6 +284,10 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
+       int ret;
+       pchan = chan->con_priv;
++      if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE &&
++          !pchan->chan_in_use)
++              return IRQ_NONE;
++
+       if (!pcc_mbox_cmd_complete_check(pchan))
+               return IRQ_NONE;
+@@ -289,9 +309,12 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
+       /*
+        * The PCC slave subspace channel needs to set the command complete bit
+        * and ring doorbell after processing message.
++       *
++       * The PCC master subspace channel clears chan_in_use to free channel.
+        */
+       if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE)
+               pcc_send_data(chan, NULL);
++      pchan->chan_in_use = false;
+       return IRQ_HANDLED;
+ }
+@@ -371,7 +394,11 @@ static int pcc_send_data(struct mbox_chan *chan, void *data)
+       if (ret)
+               return ret;
+-      return pcc_chan_reg_read_modify_write(&pchan->db);
++      ret = pcc_chan_reg_read_modify_write(&pchan->db);
++      if (!ret && pchan->plat_irq > 0)
++              pchan->chan_in_use = true;
++
++      return ret;
+ }
+ /**
+@@ -384,11 +411,14 @@ static int pcc_send_data(struct mbox_chan *chan, void *data)
+ static int pcc_startup(struct mbox_chan *chan)
+ {
+       struct pcc_chan_info *pchan = chan->con_priv;
++      unsigned long irqflags;
+       int rc;
+       if (pchan->plat_irq > 0) {
+-              rc = devm_request_irq(chan->mbox->dev, pchan->plat_irq, pcc_mbox_irq, 0,
+-                                    MBOX_IRQ_NAME, chan);
++              irqflags = pcc_chan_plat_irq_can_be_shared(pchan) ?
++                                              IRQF_SHARED | IRQF_ONESHOT : 0;
++              rc = devm_request_irq(chan->mbox->dev, pchan->plat_irq, pcc_mbox_irq,
++                                    irqflags, MBOX_IRQ_NAME, chan);
+               if (unlikely(rc)) {
+                       dev_err(chan->mbox->dev, "failed to register PCC interrupt %d\n",
+                               pchan->plat_irq);
+@@ -494,6 +524,7 @@ static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan,
+                      pcct_ss->platform_interrupt);
+               return -EINVAL;
+       }
++      pchan->plat_irq_flags = pcct_ss->flags;
+       if (pcct_ss->header.type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) {
+               struct acpi_pcct_hw_reduced_type2 *pcct2_ss = (void *)pcct_ss;
+@@ -515,6 +546,12 @@ static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan,
+                                       "PLAT IRQ ACK");
+       }
++      if (pcc_chan_plat_irq_can_be_shared(pchan) &&
++          !pchan->plat_irq_ack.gas) {
++              pr_err("PCC subspace has level IRQ with no ACK register\n");
++              return -EINVAL;
++      }
++
+       return ret;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.6/media-uvcvideo-force-uvc-version-to-1.0a-for-0408-40.patch b/queue-6.6/media-uvcvideo-force-uvc-version-to-1.0a-for-0408-40.patch
new file mode 100644 (file)
index 0000000..aeb136d
--- /dev/null
@@ -0,0 +1,49 @@
+From 2e7152f3794ef1552c3b5f699e81a051ae578323 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 Jan 2023 22:52:10 +0200
+Subject: media: uvcvideo: Force UVC version to 1.0a for 0408:4035
+
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+[ Upstream commit c397e8c45d911443b4ab60084fb723edf2a5b604 ]
+
+The Quanta ACER HD User Facing camera reports a UVC 1.50 version, but
+implements UVC 1.0a as shown by the UVC probe control being 26 bytes
+long. Force the UVC version for that device.
+
+Reported-by: Giuliano Lotta <giuliano.lotta@gmail.com>
+Closes: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2000947
+Link: https://lore.kernel.org/r/20230115205210.20077-1-laurent.pinchart@ideasonboard.com
+Tested-by: Giuliano Lotta <giuliano.lotta@gmail.com>
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Stable-dep-of: c9df99302fff ("media: uvcvideo: Force UVC version to 1.0a for 0408:4033")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/uvc/uvc_driver.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
+index 5a3e933df633..adf1abce5333 100644
+--- a/drivers/media/usb/uvc/uvc_driver.c
++++ b/drivers/media/usb/uvc/uvc_driver.c
+@@ -2519,6 +2519,17 @@ static const struct usb_device_id uvc_ids[] = {
+         .bInterfaceSubClass   = 1,
+         .bInterfaceProtocol   = UVC_PC_PROTOCOL_15,
+         .driver_info          = (kernel_ulong_t)&uvc_ctrl_power_line_limited },
++      /* Quanta ACER HD User Facing */
++      { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
++                              | USB_DEVICE_ID_MATCH_INT_INFO,
++        .idVendor             = 0x0408,
++        .idProduct            = 0x4035,
++        .bInterfaceClass      = USB_CLASS_VIDEO,
++        .bInterfaceSubClass   = 1,
++        .bInterfaceProtocol   = UVC_PC_PROTOCOL_15,
++        .driver_info          = (kernel_ulong_t)&(const struct uvc_device_info){
++              .uvc_version = 0x010a,
++        } },
+       /* LogiLink Wireless Webcam */
+       { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
+                               | USB_DEVICE_ID_MATCH_INT_INFO,
+-- 
+2.39.5
+
diff --git a/queue-6.6/media-uvcvideo-force-uvc-version-to-1.0a-for-0408-40.patch-10342 b/queue-6.6/media-uvcvideo-force-uvc-version-to-1.0a-for-0408-40.patch-10342
new file mode 100644 (file)
index 0000000..caac9d5
--- /dev/null
@@ -0,0 +1,50 @@
+From 20279b06e3f4153f8a5bbf4b6e579826b1f7491c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Sep 2024 13:33:29 +0000
+Subject: media: uvcvideo: Force UVC version to 1.0a for 0408:4033
+
+From: Ricardo Ribalda <ribalda@chromium.org>
+
+[ Upstream commit c9df99302fff53b6007666136b9f43fbac7ee3d8 ]
+
+The Quanta ACER HD User Facing camera reports a UVC 1.50 version, but
+implements UVC 1.0a as shown by the UVC probe control being 26 bytes
+long. Force the UVC version for that device.
+
+Reported-by: Giuliano Lotta <giuliano.lotta@gmail.com>
+Closes: https://lore.kernel.org/linux-media/fce4f906-d69b-417d-9f13-bf69fe5c81e3@koyu.space/
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Link: https://lore.kernel.org/r/20240924-uvc-quanta-v1-1-2de023863767@chromium.org
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/uvc/uvc_driver.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
+index adf1abce5333..1b05890f99f4 100644
+--- a/drivers/media/usb/uvc/uvc_driver.c
++++ b/drivers/media/usb/uvc/uvc_driver.c
+@@ -2520,6 +2520,17 @@ static const struct usb_device_id uvc_ids[] = {
+         .bInterfaceProtocol   = UVC_PC_PROTOCOL_15,
+         .driver_info          = (kernel_ulong_t)&uvc_ctrl_power_line_limited },
+       /* Quanta ACER HD User Facing */
++      { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
++                              | USB_DEVICE_ID_MATCH_INT_INFO,
++        .idVendor             = 0x0408,
++        .idProduct            = 0x4033,
++        .bInterfaceClass      = USB_CLASS_VIDEO,
++        .bInterfaceSubClass   = 1,
++        .bInterfaceProtocol   = UVC_PC_PROTOCOL_15,
++        .driver_info          = (kernel_ulong_t)&(const struct uvc_device_info){
++              .uvc_version = 0x010a,
++        } },
++      /* Quanta ACER HD User Facing */
+       { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
+                               | USB_DEVICE_ID_MATCH_INT_INFO,
+         .idVendor             = 0x0408,
+-- 
+2.39.5
+
diff --git a/queue-6.6/memblock-allow-zero-threshold-in-validate_numa_conve.patch b/queue-6.6/memblock-allow-zero-threshold-in-validate_numa_conve.patch
new file mode 100644 (file)
index 0000000..bba3231
--- /dev/null
@@ -0,0 +1,47 @@
+From 941ae9f40f17bb4178fc34ce43def7359e99afe1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Nov 2024 11:13:47 +0200
+Subject: memblock: allow zero threshold in validate_numa_converage()
+
+From: Mike Rapoport (Microsoft) <rppt@kernel.org>
+
+[ Upstream commit 9cdc6423acb49055efb444ecd895d853a70ef931 ]
+
+Currently memblock validate_numa_converage() returns false negative when
+threshold set to zero.
+
+Make the check if the memory size with invalid node ID is greater than
+the threshold exclusive to fix that.
+
+Link: https://lore.kernel.org/all/Z0mIDBD4KLyxyOCm@kernel.org/
+Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/memblock.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/mm/memblock.c b/mm/memblock.c
+index 3a3ab73546f5..87a2b4340ce4 100644
+--- a/mm/memblock.c
++++ b/mm/memblock.c
+@@ -738,7 +738,7 @@ int __init_memblock memblock_add(phys_addr_t base, phys_addr_t size)
+ /**
+  * memblock_validate_numa_coverage - check if amount of memory with
+  * no node ID assigned is less than a threshold
+- * @threshold_bytes: maximal number of pages that can have unassigned node
++ * @threshold_bytes: maximal memory size that can have unassigned node
+  * ID (in bytes).
+  *
+  * A buggy firmware may report memory that does not belong to any node.
+@@ -758,7 +758,7 @@ bool __init_memblock memblock_validate_numa_coverage(unsigned long threshold_byt
+                       nr_pages += end_pfn - start_pfn;
+       }
+-      if ((nr_pages << PAGE_SHIFT) >= threshold_bytes) {
++      if ((nr_pages << PAGE_SHIFT) > threshold_bytes) {
+               mem_size_mb = memblock_phys_mem_size() >> 20;
+               pr_err("NUMA: no nodes coverage for %luMB of %luMB RAM\n",
+                      (nr_pages << PAGE_SHIFT) >> 20, mem_size_mb);
+-- 
+2.39.5
+
diff --git a/queue-6.6/memblock-make-memblock_set_node-also-warn-about-use-.patch b/queue-6.6/memblock-make-memblock_set_node-also-warn-about-use-.patch
new file mode 100644 (file)
index 0000000..6d9ff83
--- /dev/null
@@ -0,0 +1,59 @@
+From 270445a91055004fc3c93507fb72aa18bc500622 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 May 2024 09:39:10 +0200
+Subject: memblock: make memblock_set_node() also warn about use of
+ MAX_NUMNODES
+
+From: Jan Beulich <jbeulich@suse.com>
+
+[ Upstream commit e0eec24e2e199873f43df99ec39773ad3af2bff7 ]
+
+On an (old) x86 system with SRAT just covering space above 4Gb:
+
+    ACPI: SRAT: Node 0 PXM 0 [mem 0x100000000-0xfffffffff] hotplug
+
+the commit referenced below leads to this NUMA configuration no longer
+being refused by a CONFIG_NUMA=y kernel (previously
+
+    NUMA: nodes only cover 6144MB of your 8185MB e820 RAM. Not used.
+    No NUMA configuration found
+    Faking a node at [mem 0x0000000000000000-0x000000027fffffff]
+
+was seen in the log directly after the message quoted above), because of
+memblock_validate_numa_coverage() checking for NUMA_NO_NODE (only). This
+in turn led to memblock_alloc_range_nid()'s warning about MAX_NUMNODES
+triggering, followed by a NULL deref in memmap_init() when trying to
+access node 64's (NODE_SHIFT=6) node data.
+
+To compensate said change, make memblock_set_node() warn on and adjust
+a passed in value of MAX_NUMNODES, just like various other functions
+already do.
+
+Fixes: ff6c3d81f2e8 ("NUMA: optimize detection of memory with no node id assigned by firmware")
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/1c8a058c-5365-4f27-a9f1-3aeb7fb3e7b2@suse.com
+Signed-off-by: Mike Rapoport (IBM) <rppt@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/memblock.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/mm/memblock.c b/mm/memblock.c
+index 87a2b4340ce4..ba64b47b7c3b 100644
+--- a/mm/memblock.c
++++ b/mm/memblock.c
+@@ -1321,6 +1321,10 @@ int __init_memblock memblock_set_node(phys_addr_t base, phys_addr_t size,
+       int start_rgn, end_rgn;
+       int i, ret;
++      if (WARN_ONCE(nid == MAX_NUMNODES,
++                    "Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead\n"))
++              nid = NUMA_NO_NODE;
++
+       ret = memblock_isolate_range(type, base, size, &start_rgn, &end_rgn);
+       if (ret)
+               return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.6/net-mlx5-unique-names-for-per-device-caches.patch b/queue-6.6/net-mlx5-unique-names-for-per-device-caches.patch
new file mode 100644 (file)
index 0000000..98215de
--- /dev/null
@@ -0,0 +1,53 @@
+From 721f3e5169b81d063d4ad9b7da713fd6c327e9e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Oct 2024 15:41:46 +0200
+Subject: net/mlx5: unique names for per device caches
+
+From: Sebastian Ott <sebott@redhat.com>
+
+[ Upstream commit 25872a079bbbe952eb660249cc9f40fa75623e68 ]
+
+Add the device name to the per device kmem_cache names to
+ensure their uniqueness. This fixes warnings like this:
+"kmem_cache of name 'mlx5_fs_fgs' already exists".
+
+Signed-off-by: Sebastian Ott <sebott@redhat.com>
+Reviewed-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/20241023134146.28448-1-sebott@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+index 991250f44c2e..474e63d02ba4 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+@@ -3478,6 +3478,7 @@ void mlx5_fs_core_free(struct mlx5_core_dev *dev)
+ int mlx5_fs_core_alloc(struct mlx5_core_dev *dev)
+ {
+       struct mlx5_flow_steering *steering;
++      char name[80];
+       int err = 0;
+       err = mlx5_init_fc_stats(dev);
+@@ -3502,10 +3503,12 @@ int mlx5_fs_core_alloc(struct mlx5_core_dev *dev)
+       else
+               steering->mode = MLX5_FLOW_STEERING_MODE_DMFS;
+-      steering->fgs_cache = kmem_cache_create("mlx5_fs_fgs",
++      snprintf(name, sizeof(name), "%s-mlx5_fs_fgs", dev_name(dev->device));
++      steering->fgs_cache = kmem_cache_create(name,
+                                               sizeof(struct mlx5_flow_group), 0,
+                                               0, NULL);
+-      steering->ftes_cache = kmem_cache_create("mlx5_fs_ftes", sizeof(struct fs_fte), 0,
++      snprintf(name, sizeof(name), "%s-mlx5_fs_ftes", dev_name(dev->device));
++      steering->ftes_cache = kmem_cache_create(name, sizeof(struct fs_fte), 0,
+                                                0, NULL);
+       if (!steering->ftes_cache || !steering->fgs_cache) {
+               err = -ENOMEM;
+-- 
+2.39.5
+
diff --git a/queue-6.6/net-renesas-rswitch-fix-possible-early-skb-release.patch b/queue-6.6/net-renesas-rswitch-fix-possible-early-skb-release.patch
new file mode 100644 (file)
index 0000000..5774fdd
--- /dev/null
@@ -0,0 +1,55 @@
+From 57cbeb68793bc58579168fd56ad00fc64cf6178e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Dec 2024 14:50:01 +0500
+Subject: net: renesas: rswitch: fix possible early skb release
+
+From: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+
+[ Upstream commit 5cb099902b6b6292b3a85ffa1bb844e0ba195945 ]
+
+When sending frame split into multiple descriptors, hardware processes
+descriptors one by one, including writing back DT values. The first
+descriptor could be already marked as completed when processing of
+next descriptors for the same frame is still in progress.
+
+Although only the last descriptor is configured to generate interrupt,
+completion of the first descriptor could be noticed by the driver when
+handling interrupt for the previous frame.
+
+Currently, driver stores skb in the entry that corresponds to the first
+descriptor. This results into skb could be unmapped and freed when
+hardware did not complete the send yet. This opens a window for
+corrupting the data being sent.
+
+Fix this by saving skb in the entry that corresponds to the last
+descriptor used to send the frame.
+
+Fixes: d2c96b9d5f83 ("net: rswitch: Add jumbo frames handling for TX")
+Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Link: https://patch.msgid.link/20241208095004.69468-2-nikita.yoush@cogentembedded.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/renesas/rswitch.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/renesas/rswitch.c b/drivers/net/ethernet/renesas/rswitch.c
+index 54aa56c84133..2f483531d95c 100644
+--- a/drivers/net/ethernet/renesas/rswitch.c
++++ b/drivers/net/ethernet/renesas/rswitch.c
+@@ -1632,8 +1632,9 @@ static netdev_tx_t rswitch_start_xmit(struct sk_buff *skb, struct net_device *nd
+       if (dma_mapping_error(ndev->dev.parent, dma_addr_orig))
+               goto err_kfree;
+-      gq->skbs[gq->cur] = skb;
+-      gq->unmap_addrs[gq->cur] = dma_addr_orig;
++      /* Stored the skb at the last descriptor to avoid skb free before hardware completes send */
++      gq->skbs[(gq->cur + nr_desc - 1) % gq->ring_size] = skb;
++      gq->unmap_addrs[(gq->cur + nr_desc - 1) % gq->ring_size] = dma_addr_orig;
+       dma_wmb();
+-- 
+2.39.5
+
diff --git a/queue-6.6/numa-optimize-detection-of-memory-with-no-node-id-as.patch b/queue-6.6/numa-optimize-detection-of-memory-with-no-node-id-as.patch
new file mode 100644 (file)
index 0000000..096c6ef
--- /dev/null
@@ -0,0 +1,208 @@
+From bb76e557e6106339bddd8a8e0bc858e8d46d9702 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Oct 2023 10:03:29 +0800
+Subject: NUMA: optimize detection of memory with no node id assigned by
+ firmware
+
+From: Liam Ni <zhiguangni01@gmail.com>
+
+[ Upstream commit ff6c3d81f2e86b63a3a530683f89ef393882782a ]
+
+Sanity check that makes sure the nodes cover all memory loops over
+numa_meminfo to count the pages that have node id assigned by the
+firmware, then loops again over memblock.memory to find the total amount
+of memory and in the end checks that the difference between the total
+memory and memory that covered by nodes is less than some threshold.
+Worse, the loop over numa_meminfo calls __absent_pages_in_range() that
+also partially traverses memblock.memory.
+
+It's much simpler and more efficient to have a single traversal of
+memblock.memory that verifies that amount of memory not covered by nodes
+is less than a threshold.
+
+Introduce memblock_validate_numa_coverage() that does exactly that and use
+it instead of numa_meminfo_cover_memory().
+
+Link: https://lkml.kernel.org/r/20231026020329.327329-1-zhiguangni01@gmail.com
+Signed-off-by: Liam Ni <zhiguangni01@gmail.com>
+Reviewed-by: Mike Rapoport (IBM) <rppt@kernel.org>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Bibo Mao <maobibo@loongson.cn>
+Cc: Binbin Zhou <zhoubinbin@loongson.cn>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: Feiyang Chen <chenfeiyang@loongson.cn>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: Huacai Chen <chenhuacai@kernel.org>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: WANG Xuerui <kernel@xen0n.name>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: 9cdc6423acb4 ("memblock: allow zero threshold in validate_numa_converage()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/loongarch/kernel/numa.c | 28 +---------------------------
+ arch/x86/mm/numa.c           | 34 ++--------------------------------
+ include/linux/memblock.h     |  1 +
+ mm/memblock.c                | 34 ++++++++++++++++++++++++++++++++++
+ 4 files changed, 38 insertions(+), 59 deletions(-)
+
+diff --git a/arch/loongarch/kernel/numa.c b/arch/loongarch/kernel/numa.c
+index 6e65ff12d5c7..8fe21f868f72 100644
+--- a/arch/loongarch/kernel/numa.c
++++ b/arch/loongarch/kernel/numa.c
+@@ -226,32 +226,6 @@ static void __init node_mem_init(unsigned int node)
+ #ifdef CONFIG_ACPI_NUMA
+-/*
+- * Sanity check to catch more bad NUMA configurations (they are amazingly
+- * common).  Make sure the nodes cover all memory.
+- */
+-static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi)
+-{
+-      int i;
+-      u64 numaram, biosram;
+-
+-      numaram = 0;
+-      for (i = 0; i < mi->nr_blks; i++) {
+-              u64 s = mi->blk[i].start >> PAGE_SHIFT;
+-              u64 e = mi->blk[i].end >> PAGE_SHIFT;
+-
+-              numaram += e - s;
+-              numaram -= __absent_pages_in_range(mi->blk[i].nid, s, e);
+-              if ((s64)numaram < 0)
+-                      numaram = 0;
+-      }
+-      max_pfn = max_low_pfn;
+-      biosram = max_pfn - absent_pages_in_range(0, max_pfn);
+-
+-      BUG_ON((s64)(biosram - numaram) >= (1 << (20 - PAGE_SHIFT)));
+-      return true;
+-}
+-
+ static void __init add_node_intersection(u32 node, u64 start, u64 size, u32 type)
+ {
+       static unsigned long num_physpages;
+@@ -396,7 +370,7 @@ int __init init_numa_memory(void)
+               return -EINVAL;
+       init_node_memblock();
+-      if (numa_meminfo_cover_memory(&numa_meminfo) == false)
++      if (!memblock_validate_numa_coverage(SZ_1M))
+               return -EINVAL;
+       for_each_node_mask(node, node_possible_map) {
+diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
+index c7fa5396c0f0..2c67bfc3cf32 100644
+--- a/arch/x86/mm/numa.c
++++ b/arch/x86/mm/numa.c
+@@ -448,37 +448,6 @@ int __node_distance(int from, int to)
+ }
+ EXPORT_SYMBOL(__node_distance);
+-/*
+- * Sanity check to catch more bad NUMA configurations (they are amazingly
+- * common).  Make sure the nodes cover all memory.
+- */
+-static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi)
+-{
+-      u64 numaram, e820ram;
+-      int i;
+-
+-      numaram = 0;
+-      for (i = 0; i < mi->nr_blks; i++) {
+-              u64 s = mi->blk[i].start >> PAGE_SHIFT;
+-              u64 e = mi->blk[i].end >> PAGE_SHIFT;
+-              numaram += e - s;
+-              numaram -= __absent_pages_in_range(mi->blk[i].nid, s, e);
+-              if ((s64)numaram < 0)
+-                      numaram = 0;
+-      }
+-
+-      e820ram = max_pfn - absent_pages_in_range(0, max_pfn);
+-
+-      /* We seem to lose 3 pages somewhere. Allow 1M of slack. */
+-      if ((s64)(e820ram - numaram) >= (1 << (20 - PAGE_SHIFT))) {
+-              printk(KERN_ERR "NUMA: nodes only cover %LuMB of your %LuMB e820 RAM. Not used.\n",
+-                     (numaram << PAGE_SHIFT) >> 20,
+-                     (e820ram << PAGE_SHIFT) >> 20);
+-              return false;
+-      }
+-      return true;
+-}
+-
+ /*
+  * Mark all currently memblock-reserved physical memory (which covers the
+  * kernel's own memory ranges) as hot-unswappable.
+@@ -584,7 +553,8 @@ static int __init numa_register_memblks(struct numa_meminfo *mi)
+                       return -EINVAL;
+               }
+       }
+-      if (!numa_meminfo_cover_memory(mi))
++
++      if (!memblock_validate_numa_coverage(SZ_1M))
+               return -EINVAL;
+       /* Finally register nodes. */
+diff --git a/include/linux/memblock.h b/include/linux/memblock.h
+index ed57c23f80ac..ed64240041e8 100644
+--- a/include/linux/memblock.h
++++ b/include/linux/memblock.h
+@@ -122,6 +122,7 @@ unsigned long memblock_addrs_overlap(phys_addr_t base1, phys_addr_t size1,
+                                    phys_addr_t base2, phys_addr_t size2);
+ bool memblock_overlaps_region(struct memblock_type *type,
+                             phys_addr_t base, phys_addr_t size);
++bool memblock_validate_numa_coverage(unsigned long threshold_bytes);
+ int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size);
+ int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size);
+ int memblock_mark_mirror(phys_addr_t base, phys_addr_t size);
+diff --git a/mm/memblock.c b/mm/memblock.c
+index d630f5c2bdb9..3a3ab73546f5 100644
+--- a/mm/memblock.c
++++ b/mm/memblock.c
+@@ -735,6 +735,40 @@ int __init_memblock memblock_add(phys_addr_t base, phys_addr_t size)
+       return memblock_add_range(&memblock.memory, base, size, MAX_NUMNODES, 0);
+ }
++/**
++ * memblock_validate_numa_coverage - check if amount of memory with
++ * no node ID assigned is less than a threshold
++ * @threshold_bytes: maximal number of pages that can have unassigned node
++ * ID (in bytes).
++ *
++ * A buggy firmware may report memory that does not belong to any node.
++ * Check if amount of such memory is below @threshold_bytes.
++ *
++ * Return: true on success, false on failure.
++ */
++bool __init_memblock memblock_validate_numa_coverage(unsigned long threshold_bytes)
++{
++      unsigned long nr_pages = 0;
++      unsigned long start_pfn, end_pfn, mem_size_mb;
++      int nid, i;
++
++      /* calculate lose page */
++      for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, &nid) {
++              if (nid == NUMA_NO_NODE)
++                      nr_pages += end_pfn - start_pfn;
++      }
++
++      if ((nr_pages << PAGE_SHIFT) >= threshold_bytes) {
++              mem_size_mb = memblock_phys_mem_size() >> 20;
++              pr_err("NUMA: no nodes coverage for %luMB of %luMB RAM\n",
++                     (nr_pages << PAGE_SHIFT) >> 20, mem_size_mb);
++              return false;
++      }
++
++      return true;
++}
++
++
+ /**
+  * memblock_isolate_range - isolate given range into disjoint memblocks
+  * @type: memblock type to isolate range for
+-- 
+2.39.5
+
diff --git a/queue-6.6/nvme-use-helper-nvme_ctrl_state-in-nvme_keep_alive_f.patch b/queue-6.6/nvme-use-helper-nvme_ctrl_state-in-nvme_keep_alive_f.patch
new file mode 100644 (file)
index 0000000..4686dd1
--- /dev/null
@@ -0,0 +1,56 @@
+From 0593b941bfb886c405a1b7a3d239ab75814b1405 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Oct 2024 08:33:16 +0530
+Subject: nvme: use helper nvme_ctrl_state in nvme_keep_alive_finish function
+
+From: Nilay Shroff <nilay@linux.ibm.com>
+
+[ Upstream commit 599d9f3a10eec69ef28a90161763e4bd7c9c02bf ]
+
+We no more need acquiring ctrl->lock before accessing the
+NVMe controller state and instead we can now use the helper
+nvme_ctrl_state. So replace the use of ctrl->lock from
+nvme_keep_alive_finish function with nvme_ctrl_state call.
+
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Stable-dep-of: 84488282166d ("Revert "nvme: make keep-alive synchronous operation"")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 5b6a6bd4e6e8..ae494c799fc5 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -1181,10 +1181,9 @@ static void nvme_queue_keep_alive_work(struct nvme_ctrl *ctrl)
+ static void nvme_keep_alive_finish(struct request *rq,
+               blk_status_t status, struct nvme_ctrl *ctrl)
+ {
+-      unsigned long flags;
+-      bool startka = false;
+       unsigned long rtt = jiffies - (rq->deadline - rq->timeout);
+       unsigned long delay = nvme_keep_alive_work_period(ctrl);
++      enum nvme_ctrl_state state = nvme_ctrl_state(ctrl);
+       /*
+        * Subtract off the keepalive RTT so nvme_keep_alive_work runs
+@@ -1207,12 +1206,7 @@ static void nvme_keep_alive_finish(struct request *rq,
+       ctrl->ka_last_check_time = jiffies;
+       ctrl->comp_seen = false;
+-      spin_lock_irqsave(&ctrl->lock, flags);
+-      if (ctrl->state == NVME_CTRL_LIVE ||
+-          ctrl->state == NVME_CTRL_CONNECTING)
+-              startka = true;
+-      spin_unlock_irqrestore(&ctrl->lock, flags);
+-      if (startka)
++      if (state == NVME_CTRL_LIVE || state == NVME_CTRL_CONNECTING)
+               queue_delayed_work(nvme_wq, &ctrl->ka_work, delay);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.6/of-address-preserve-the-flags-portion-on-1-1-dma-ran.patch b/queue-6.6/of-address-preserve-the-flags-portion-on-1-1-dma-ran.patch
new file mode 100644 (file)
index 0000000..30c495d
--- /dev/null
@@ -0,0 +1,50 @@
+From ddef21a3f2ca63aa185b216767d52a9a0f63592f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Nov 2024 11:05:37 +0100
+Subject: of: address: Preserve the flags portion on 1:1 dma-ranges mapping
+
+From: Andrea della Porta <andrea.porta@suse.com>
+
+[ Upstream commit 7f05e20b989ac33c9c0f8c2028ec0a566493548f ]
+
+A missing or empty dma-ranges in a DT node implies a 1:1 mapping for dma
+translations. In this specific case, the current behaviour is to zero out
+the entire specifier so that the translation could be carried on as an
+offset from zero. This includes address specifier that has flags (e.g.
+PCI ranges).
+
+Once the flags portion has been zeroed, the translation chain is broken
+since the mapping functions will check the upcoming address specifier
+against mismatching flags, always failing the 1:1 mapping and its entire
+purpose of always succeeding.
+
+Set to zero only the address portion while passing the flags through.
+
+Fixes: dbbdee94734b ("of/address: Merge all of the bus translation code")
+Cc: stable@vger.kernel.org
+Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
+Tested-by: Herve Codina <herve.codina@bootlin.com>
+Link: https://lore.kernel.org/r/e51ae57874e58a9b349c35e2e877425ebc075d7a.1732441813.git.andrea.porta@suse.com
+Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/address.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/of/address.c b/drivers/of/address.c
+index cdefe5a89e5d..34d880a1be0a 100644
+--- a/drivers/of/address.c
++++ b/drivers/of/address.c
+@@ -476,7 +476,8 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
+       }
+       if (ranges == NULL || rlen == 0) {
+               offset = of_read_number(addr, na);
+-              memset(addr, 0, pna * 4);
++              /* set address to zero, pass flags through */
++              memset(addr + pbus->flag_cells, 0, (pna - pbus->flag_cells) * 4);
+               pr_debug("empty ranges; 1:1 translation\n");
+               goto finish;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.6/of-address-remove-duplicated-functions.patch b/queue-6.6/of-address-remove-duplicated-functions.patch
new file mode 100644 (file)
index 0000000..47f2e95
--- /dev/null
@@ -0,0 +1,72 @@
+From fccccf70fc3626e9ba04199a02b3b3bcf75b751d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Oct 2023 13:02:17 +0200
+Subject: of: address: Remove duplicated functions
+
+From: Herve Codina <herve.codina@bootlin.com>
+
+[ Upstream commit 3eb030c60835668997d5763b1a0c7938faf169f6 ]
+
+The recently added of_bus_default_flags_translate() performs the exact
+same operation as of_bus_pci_translate() and of_bus_isa_translate().
+
+Avoid duplicated code replacing both of_bus_pci_translate() and
+of_bus_isa_translate() with of_bus_default_flags_translate().
+
+Signed-off-by: Herve Codina <herve.codina@bootlin.com>
+Link: https://lore.kernel.org/r/20231017110221.189299-3-herve.codina@bootlin.com
+Signed-off-by: Rob Herring <robh@kernel.org>
+Stable-dep-of: 7f05e20b989a ("of: address: Preserve the flags portion on 1:1 dma-ranges mapping")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/address.c | 13 ++-----------
+ 1 file changed, 2 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/of/address.c b/drivers/of/address.c
+index dfd05cb2b2fc..cfe5a11b620a 100644
+--- a/drivers/of/address.c
++++ b/drivers/of/address.c
+@@ -217,10 +217,6 @@ static u64 of_bus_pci_map(__be32 *addr, const __be32 *range, int na, int ns,
+       return da - cp;
+ }
+-static int of_bus_pci_translate(__be32 *addr, u64 offset, int na)
+-{
+-      return of_bus_default_translate(addr + 1, offset, na - 1);
+-}
+ #endif /* CONFIG_PCI */
+ /*
+@@ -344,11 +340,6 @@ static u64 of_bus_isa_map(__be32 *addr, const __be32 *range, int na, int ns,
+       return da - cp;
+ }
+-static int of_bus_isa_translate(__be32 *addr, u64 offset, int na)
+-{
+-      return of_bus_default_translate(addr + 1, offset, na - 1);
+-}
+-
+ static unsigned int of_bus_isa_get_flags(const __be32 *addr)
+ {
+       unsigned int flags = 0;
+@@ -379,7 +370,7 @@ static struct of_bus of_busses[] = {
+               .match = of_bus_pci_match,
+               .count_cells = of_bus_pci_count_cells,
+               .map = of_bus_pci_map,
+-              .translate = of_bus_pci_translate,
++              .translate = of_bus_default_flags_translate,
+               .has_flags = true,
+               .get_flags = of_bus_pci_get_flags,
+       },
+@@ -391,7 +382,7 @@ static struct of_bus of_busses[] = {
+               .match = of_bus_isa_match,
+               .count_cells = of_bus_isa_count_cells,
+               .map = of_bus_isa_map,
+-              .translate = of_bus_isa_translate,
++              .translate = of_bus_default_flags_translate,
+               .has_flags = true,
+               .get_flags = of_bus_isa_get_flags,
+       },
+-- 
+2.39.5
+
diff --git a/queue-6.6/of-address-store-number-of-bus-flag-cells-rather-tha.patch b/queue-6.6/of-address-store-number-of-bus-flag-cells-rather-tha.patch
new file mode 100644 (file)
index 0000000..6c11cd3
--- /dev/null
@@ -0,0 +1,85 @@
+From f74e92b6f2a72b7613a15cb3338b34e5e65a5246 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Oct 2023 08:53:58 -0500
+Subject: of: address: Store number of bus flag cells rather than bool
+
+From: Rob Herring <robh@kernel.org>
+
+[ Upstream commit 88696db08b7efa3b6bb722014ea7429e78f6be32 ]
+
+It is more useful to know how many flags cells a bus has rather than
+whether a bus has flags or not as ultimately the number of cells is the
+information used. Replace 'has_flags' boolean with 'flag_cells' count.
+
+Acked-by: Herve Codina <herve.codina@bootlin.com>
+Link: https://lore.kernel.org/r/20231026135358.3564307-2-robh@kernel.org
+Signed-off-by: Rob Herring <robh@kernel.org>
+Stable-dep-of: 7f05e20b989a ("of: address: Preserve the flags portion on 1:1 dma-ranges mapping")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/address.c | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/of/address.c b/drivers/of/address.c
+index cfe5a11b620a..cdefe5a89e5d 100644
+--- a/drivers/of/address.c
++++ b/drivers/of/address.c
+@@ -46,7 +46,7 @@ struct of_bus {
+       u64             (*map)(__be32 *addr, const __be32 *range,
+                               int na, int ns, int pna);
+       int             (*translate)(__be32 *addr, u64 offset, int na);
+-      bool    has_flags;
++      int             flag_cells;
+       unsigned int    (*get_flags)(const __be32 *addr);
+ };
+@@ -371,7 +371,7 @@ static struct of_bus of_busses[] = {
+               .count_cells = of_bus_pci_count_cells,
+               .map = of_bus_pci_map,
+               .translate = of_bus_default_flags_translate,
+-              .has_flags = true,
++              .flag_cells = 1,
+               .get_flags = of_bus_pci_get_flags,
+       },
+ #endif /* CONFIG_PCI */
+@@ -383,7 +383,7 @@ static struct of_bus of_busses[] = {
+               .count_cells = of_bus_isa_count_cells,
+               .map = of_bus_isa_map,
+               .translate = of_bus_default_flags_translate,
+-              .has_flags = true,
++              .flag_cells = 1,
+               .get_flags = of_bus_isa_get_flags,
+       },
+       /* Default with flags cell */
+@@ -394,7 +394,7 @@ static struct of_bus of_busses[] = {
+               .count_cells = of_bus_default_count_cells,
+               .map = of_bus_default_flags_map,
+               .translate = of_bus_default_flags_translate,
+-              .has_flags = true,
++              .flag_cells = 1,
+               .get_flags = of_bus_default_flags_get_flags,
+       },
+       /* Default */
+@@ -827,7 +827,7 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
+       int na = parser->na;
+       int ns = parser->ns;
+       int np = parser->pna + na + ns;
+-      int busflag_na = 0;
++      int busflag_na = parser->bus->flag_cells;
+       if (!range)
+               return NULL;
+@@ -837,10 +837,6 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
+       range->flags = parser->bus->get_flags(parser->range);
+-      /* A extra cell for resource flags */
+-      if (parser->bus->has_flags)
+-              busflag_na = 1;
+-
+       range->bus_addr = of_read_number(parser->range + busflag_na, na - busflag_na);
+       if (parser->dma)
+-- 
+2.39.5
+
diff --git a/queue-6.6/platform-x86-mlx-platform-call-pci_dev_put-to-balanc.patch b/queue-6.6/platform-x86-mlx-platform-call-pci_dev_put-to-balanc.patch
new file mode 100644 (file)
index 0000000..cd9b904
--- /dev/null
@@ -0,0 +1,54 @@
+From d7d7a8f08e8fcffaa1277464649e556e30942d4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Dec 2024 11:25:38 +0900
+Subject: platform/x86: mlx-platform: call pci_dev_put() to balance the
+ refcount
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Joe Hattori <joe@pf.is.s.u-tokyo.ac.jp>
+
+[ Upstream commit 185e1b1d91e419445d3fd99c1c0376a970438acf ]
+
+mlxplat_pci_fpga_device_init() calls pci_get_device() but does not
+release the refcount on error path. Call pci_dev_put() on the error path
+and in mlxplat_pci_fpga_device_exit() to fix this.
+
+This bug was found by an experimental static analysis tool that I am
+developing.
+
+Fixes: 02daa222fbdd ("platform: mellanox: Add initial support for PCIe based programming logic device")
+Signed-off-by: Joe Hattori <joe@pf.is.s.u-tokyo.ac.jp>
+Reviewed-by: Vadim Pasternak <vadimp@nvidia.com>
+Link: https://lore.kernel.org/r/20241216022538.381209-1-joe@pf.is.s.u-tokyo.ac.jp
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/mlx-platform.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c
+index a2ffe4157df1..b8d77adc9ea1 100644
+--- a/drivers/platform/x86/mlx-platform.c
++++ b/drivers/platform/x86/mlx-platform.c
+@@ -6237,6 +6237,7 @@ mlxplat_pci_fpga_device_init(unsigned int device, const char *res_name, struct p
+ fail_pci_request_regions:
+       pci_disable_device(pci_dev);
+ fail_pci_enable_device:
++      pci_dev_put(pci_dev);
+       return err;
+ }
+@@ -6247,6 +6248,7 @@ mlxplat_pci_fpga_device_exit(struct pci_dev *pci_bridge,
+       iounmap(pci_bridge_addr);
+       pci_release_regions(pci_bridge);
+       pci_disable_device(pci_bridge);
++      pci_dev_put(pci_bridge);
+ }
+ static int
+-- 
+2.39.5
+
diff --git a/queue-6.6/remoteproc-qcom-pas-add-sc7180-adsp.patch b/queue-6.6/remoteproc-qcom-pas-add-sc7180-adsp.patch
new file mode 100644 (file)
index 0000000..e84a4d4
--- /dev/null
@@ -0,0 +1,38 @@
+From e63b122e3dfca70e98f792a1d553123515930966 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Sep 2023 15:02:35 +0500
+Subject: remoteproc: qcom: pas: Add sc7180 adsp
+
+From: Nikita Travkin <nikita@trvn.ru>
+
+[ Upstream commit 8de60bbab994bf8165d7d10e974872852da47aa7 ]
+
+sc7180 has a dedicated ADSP similar to the one found in sm8250.
+Add it's compatible to the driver reusing the existing config so
+the devices that use the adsp can probe it.
+
+Signed-off-by: Nikita Travkin <nikita@trvn.ru>
+Reviewed-by: Stephen Boyd <swboyd@chromium.org>
+Link: https://lore.kernel.org/r/20230907-sc7180-adsp-rproc-v3-2-6515c3fbe0a3@trvn.ru
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: 009e288c989b ("remoteproc: qcom: pas: enable SAR2130P audio DSP support")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_q6v5_pas.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
+index 6235721f2c1a..fd66bb8b23f8 100644
+--- a/drivers/remoteproc/qcom_q6v5_pas.c
++++ b/drivers/remoteproc/qcom_q6v5_pas.c
+@@ -1163,6 +1163,7 @@ static const struct of_device_id adsp_of_match[] = {
+       { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init },
+       { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init },
+       { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init },
++      { .compatible = "qcom,sc7180-adsp-pas", .data = &sm8250_adsp_resource},
+       { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init},
+       { .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init},
+       { .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource},
+-- 
+2.39.5
+
diff --git a/queue-6.6/remoteproc-qcom-pas-add-support-for-sa8775p-adsp-cds.patch b/queue-6.6/remoteproc-qcom-pas-add-support-for-sa8775p-adsp-cds.patch
new file mode 100644 (file)
index 0000000..80f3f49
--- /dev/null
@@ -0,0 +1,150 @@
+From b55068851314683a621ff59dca7d402cc961d28b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Aug 2024 19:08:04 +0200
+Subject: remoteproc: qcom: pas: Add support for SA8775p ADSP, CDSP and GPDSP
+
+From: Tengfei Fan <quic_tengfan@quicinc.com>
+
+[ Upstream commit 9091225ba28c0106d3cd041c7abf5551a94bb524 ]
+
+Add support for PIL loading on ADSP, CDSP0, CDSP1, GPDSP0 and GPDSP1 on
+SA8775p SoCs.
+
+Signed-off-by: Tengfei Fan <quic_tengfan@quicinc.com>
+Co-developed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Link: https://lore.kernel.org/r/20240805-topic-sa8775p-iot-remoteproc-v4-3-86affdc72c04@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: 009e288c989b ("remoteproc: qcom: pas: enable SAR2130P audio DSP support")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_q6v5_pas.c | 92 ++++++++++++++++++++++++++++++
+ 1 file changed, 92 insertions(+)
+
+diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
+index fd66bb8b23f8..4a73723e375a 100644
+--- a/drivers/remoteproc/qcom_q6v5_pas.c
++++ b/drivers/remoteproc/qcom_q6v5_pas.c
+@@ -786,6 +786,23 @@ static const struct adsp_data adsp_resource_init = {
+               .ssctl_id = 0x14,
+ };
++static const struct adsp_data sa8775p_adsp_resource = {
++      .crash_reason_smem = 423,
++      .firmware_name = "adsp.mbn",
++      .pas_id = 1,
++      .minidump_id = 5,
++      .auto_boot = true,
++      .proxy_pd_names = (char*[]){
++              "lcx",
++              "lmx",
++              NULL
++      },
++      .load_state = "adsp",
++      .ssr_name = "lpass",
++      .sysmon_name = "adsp",
++      .ssctl_id = 0x14,
++};
++
+ static const struct adsp_data sdm845_adsp_resource_init = {
+               .crash_reason_smem = 423,
+               .firmware_name = "adsp.mdt",
+@@ -885,6 +902,42 @@ static const struct adsp_data cdsp_resource_init = {
+       .ssctl_id = 0x17,
+ };
++static const struct adsp_data sa8775p_cdsp0_resource = {
++      .crash_reason_smem = 601,
++      .firmware_name = "cdsp0.mbn",
++      .pas_id = 18,
++      .minidump_id = 7,
++      .auto_boot = true,
++      .proxy_pd_names = (char*[]){
++              "cx",
++              "mxc",
++              "nsp",
++              NULL
++      },
++      .load_state = "cdsp",
++      .ssr_name = "cdsp",
++      .sysmon_name = "cdsp",
++      .ssctl_id = 0x17,
++};
++
++static const struct adsp_data sa8775p_cdsp1_resource = {
++      .crash_reason_smem = 633,
++      .firmware_name = "cdsp1.mbn",
++      .pas_id = 30,
++      .minidump_id = 20,
++      .auto_boot = true,
++      .proxy_pd_names = (char*[]){
++              "cx",
++              "mxc",
++              "nsp",
++              NULL
++      },
++      .load_state = "nsp",
++      .ssr_name = "cdsp1",
++      .sysmon_name = "cdsp1",
++      .ssctl_id = 0x20,
++};
++
+ static const struct adsp_data sdm845_cdsp_resource_init = {
+       .crash_reason_smem = 601,
+       .firmware_name = "cdsp.mdt",
+@@ -987,6 +1040,40 @@ static const struct adsp_data sm8350_cdsp_resource = {
+       .ssctl_id = 0x17,
+ };
++static const struct adsp_data sa8775p_gpdsp0_resource = {
++      .crash_reason_smem = 640,
++      .firmware_name = "gpdsp0.mbn",
++      .pas_id = 39,
++      .minidump_id = 21,
++      .auto_boot = true,
++      .proxy_pd_names = (char*[]){
++              "cx",
++              "mxc",
++              NULL
++      },
++      .load_state = "gpdsp0",
++      .ssr_name = "gpdsp0",
++      .sysmon_name = "gpdsp0",
++      .ssctl_id = 0x21,
++};
++
++static const struct adsp_data sa8775p_gpdsp1_resource = {
++      .crash_reason_smem = 641,
++      .firmware_name = "gpdsp1.mbn",
++      .pas_id = 40,
++      .minidump_id = 22,
++      .auto_boot = true,
++      .proxy_pd_names = (char*[]){
++              "cx",
++              "mxc",
++              NULL
++      },
++      .load_state = "gpdsp1",
++      .ssr_name = "gpdsp1",
++      .sysmon_name = "gpdsp1",
++      .ssctl_id = 0x22,
++};
++
+ static const struct adsp_data mpss_resource_init = {
+       .crash_reason_smem = 421,
+       .firmware_name = "modem.mdt",
+@@ -1163,6 +1250,11 @@ static const struct of_device_id adsp_of_match[] = {
+       { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init },
+       { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init },
+       { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init },
++      { .compatible = "qcom,sa8775p-adsp-pas", .data = &sa8775p_adsp_resource},
++      { .compatible = "qcom,sa8775p-cdsp0-pas", .data = &sa8775p_cdsp0_resource},
++      { .compatible = "qcom,sa8775p-cdsp1-pas", .data = &sa8775p_cdsp1_resource},
++      { .compatible = "qcom,sa8775p-gpdsp0-pas", .data = &sa8775p_gpdsp0_resource},
++      { .compatible = "qcom,sa8775p-gpdsp1-pas", .data = &sa8775p_gpdsp1_resource},
+       { .compatible = "qcom,sc7180-adsp-pas", .data = &sm8250_adsp_resource},
+       { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init},
+       { .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init},
+-- 
+2.39.5
+
diff --git a/queue-6.6/remoteproc-qcom-pas-enable-sar2130p-audio-dsp-suppor.patch b/queue-6.6/remoteproc-qcom-pas-enable-sar2130p-audio-dsp-suppor.patch
new file mode 100644 (file)
index 0000000..536169b
--- /dev/null
@@ -0,0 +1,36 @@
+From 416a3e630ca586e9f41280d78c3d431ce80dbdf0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 27 Oct 2024 01:09:45 +0300
+Subject: remoteproc: qcom: pas: enable SAR2130P audio DSP support
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 009e288c989b3fe548a45c82da407d7bd00418a9 ]
+
+Enable support for the Audio DSP on the Qualcomm SAR2130P platform,
+reusing the SM8350 resources.
+
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20241027-sar2130p-adsp-v1-3-bd204e39d24e@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_q6v5_pas.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
+index 4a73723e375a..fd6bf9e77afc 100644
+--- a/drivers/remoteproc/qcom_q6v5_pas.c
++++ b/drivers/remoteproc/qcom_q6v5_pas.c
+@@ -1255,6 +1255,7 @@ static const struct of_device_id adsp_of_match[] = {
+       { .compatible = "qcom,sa8775p-cdsp1-pas", .data = &sa8775p_cdsp1_resource},
+       { .compatible = "qcom,sa8775p-gpdsp0-pas", .data = &sa8775p_gpdsp0_resource},
+       { .compatible = "qcom,sa8775p-gpdsp1-pas", .data = &sa8775p_gpdsp1_resource},
++      { .compatible = "qcom,sar2130p-adsp-pas", .data = &sm8350_adsp_resource},
+       { .compatible = "qcom,sc7180-adsp-pas", .data = &sm8250_adsp_resource},
+       { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init},
+       { .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init},
+-- 
+2.39.5
+
diff --git a/queue-6.6/revert-drm-radeon-delay-connector-detecting-when-hpd.patch b/queue-6.6/revert-drm-radeon-delay-connector-detecting-when-hpd.patch
new file mode 100644 (file)
index 0000000..8b3929b
--- /dev/null
@@ -0,0 +1,47 @@
+From ed888cd3d1240ac7f5a6a6324f49f689967a9633 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Nov 2024 16:23:45 -0500
+Subject: Revert "drm/radeon: Delay Connector detecting when HPD singals is
+ unstable"
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 979bfe291b5b30a9132c2fd433247e677b24c6aa ]
+
+This reverts commit 949658cb9b69ab9d22a42a662b2fdc7085689ed8.
+
+This causes a blank screen on boot.
+
+Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3696
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: Shixiong Ou <oushixiong@kylinos.cn>
+Cc: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/radeon_connectors.c | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
+index cf0114ca59a4..b84b58926106 100644
+--- a/drivers/gpu/drm/radeon/radeon_connectors.c
++++ b/drivers/gpu/drm/radeon/radeon_connectors.c
+@@ -1267,16 +1267,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
+                       goto exit;
+               }
+       }
+-
+-      if (dret && radeon_connector->hpd.hpd != RADEON_HPD_NONE &&
+-          !radeon_hpd_sense(rdev, radeon_connector->hpd.hpd) &&
+-          connector->connector_type == DRM_MODE_CONNECTOR_HDMIA) {
+-              DRM_DEBUG_KMS("EDID is readable when HPD disconnected\n");
+-              schedule_delayed_work(&rdev->hotplug_work, msecs_to_jiffies(1000));
+-              ret = connector_status_disconnected;
+-              goto exit;
+-      }
+-
+       if (dret) {
+               radeon_connector->detected_by_load = false;
+               radeon_connector_free_edid(connector);
+-- 
+2.39.5
+
diff --git a/queue-6.6/revert-nvme-make-keep-alive-synchronous-operation.patch b/queue-6.6/revert-nvme-make-keep-alive-synchronous-operation.patch
new file mode 100644 (file)
index 0000000..7e47820
--- /dev/null
@@ -0,0 +1,94 @@
+From 97ef7fe1bdc1dbf712e06c443b46867a55e50235 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2024 11:42:08 +0530
+Subject: Revert "nvme: make keep-alive synchronous operation"
+
+From: Nilay Shroff <nilay@linux.ibm.com>
+
+[ Upstream commit 84488282166de6b6760ada8030e87aaa08bce3aa ]
+
+This reverts commit d06923670b5a5f609603d4a9fee4dec02d38de9c.
+
+It was realized that the fix implemented to contain the race condition
+among the keep alive task and the fabric shutdown code path in the commit
+d06923670b5ia ("nvme: make keep-alive synchronous operation") is not
+optimal. The reason being keep-alive runs under the workqueue and making
+it synchronous would waste a workqueue context.
+Furthermore, we later found that the above race condition is a regression
+caused due to the changes implemented in commit a54a93d0e359 ("nvme: move
+stopping keep-alive into nvme_uninit_ctrl()"). So we decided to revert the
+commit d06923670b5a ("nvme: make keep-alive synchronous operation") and
+then fix the regression.
+
+Link: https://lore.kernel.org/all/196f4013-3bbf-43ff-98b4-9cb2a96c20c2@grimberg.me/
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index ae494c799fc5..4aad16390d47 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -1178,9 +1178,10 @@ static void nvme_queue_keep_alive_work(struct nvme_ctrl *ctrl)
+                          nvme_keep_alive_work_period(ctrl));
+ }
+-static void nvme_keep_alive_finish(struct request *rq,
+-              blk_status_t status, struct nvme_ctrl *ctrl)
++static enum rq_end_io_ret nvme_keep_alive_end_io(struct request *rq,
++                                               blk_status_t status)
+ {
++      struct nvme_ctrl *ctrl = rq->end_io_data;
+       unsigned long rtt = jiffies - (rq->deadline - rq->timeout);
+       unsigned long delay = nvme_keep_alive_work_period(ctrl);
+       enum nvme_ctrl_state state = nvme_ctrl_state(ctrl);
+@@ -1197,17 +1198,20 @@ static void nvme_keep_alive_finish(struct request *rq,
+               delay = 0;
+       }
++      blk_mq_free_request(rq);
++
+       if (status) {
+               dev_err(ctrl->device,
+                       "failed nvme_keep_alive_end_io error=%d\n",
+                               status);
+-              return;
++              return RQ_END_IO_NONE;
+       }
+       ctrl->ka_last_check_time = jiffies;
+       ctrl->comp_seen = false;
+       if (state == NVME_CTRL_LIVE || state == NVME_CTRL_CONNECTING)
+               queue_delayed_work(nvme_wq, &ctrl->ka_work, delay);
++      return RQ_END_IO_NONE;
+ }
+ static void nvme_keep_alive_work(struct work_struct *work)
+@@ -1216,7 +1220,6 @@ static void nvme_keep_alive_work(struct work_struct *work)
+                       struct nvme_ctrl, ka_work);
+       bool comp_seen = ctrl->comp_seen;
+       struct request *rq;
+-      blk_status_t status;
+       ctrl->ka_last_check_time = jiffies;
+@@ -1239,9 +1242,9 @@ static void nvme_keep_alive_work(struct work_struct *work)
+       nvme_init_request(rq, &ctrl->ka_cmd);
+       rq->timeout = ctrl->kato * HZ;
+-      status = blk_execute_rq(rq, false);
+-      nvme_keep_alive_finish(rq, status, ctrl);
+-      blk_mq_free_request(rq);
++      rq->end_io = nvme_keep_alive_end_io;
++      rq->end_io_data = ctrl;
++      blk_execute_rq_nowait(rq, false);
+ }
+ static void nvme_start_keep_alive(struct nvme_ctrl *ctrl)
+-- 
+2.39.5
+
diff --git a/queue-6.6/revert-watchdog-s3c2410_wdt-use-exynos_get_pmu_regma.patch b/queue-6.6/revert-watchdog-s3c2410_wdt-use-exynos_get_pmu_regma.patch
new file mode 100644 (file)
index 0000000..2684063
--- /dev/null
@@ -0,0 +1,73 @@
+From 67cff7dc957b3b9d13ad423d755d0788bac5f62e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Oct 2024 19:11:31 +0000
+Subject: Revert "watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle()
+ for PMU regs"
+
+From: Peter Griffin <peter.griffin@linaro.org>
+
+[ Upstream commit ccfb765944bb66813398958983cb8141e2624a6b ]
+
+This reverts commit 746f0770f916e6c48e422d6a34e67eae16707f0e.
+
+Now that we can register a SoC specific regmap with syscon using
+of_syscon_register_regmap() api we can switch back to using
+syscon_regmap_lookup_by_phandle() in the client drivers.
+
+Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
+Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20241029191131.2329414-1-peter.griffin@linaro.org
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/Kconfig       | 1 +
+ drivers/watchdog/s3c2410_wdt.c | 8 ++++----
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
+index 4ecf701abe5f..751458959411 100644
+--- a/drivers/watchdog/Kconfig
++++ b/drivers/watchdog/Kconfig
+@@ -512,6 +512,7 @@ config S3C2410_WATCHDOG
+       tristate "S3C6410/S5Pv210/Exynos Watchdog"
+       depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
+       select WATCHDOG_CORE
++      select MFD_SYSCON if ARCH_EXYNOS
+       help
+         Watchdog timer block in the Samsung S3C64xx, S5Pv210 and Exynos
+         SoCs. This will reboot the system when the timer expires with
+diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
+index 0c9c649583d4..0b4bd883ff28 100644
+--- a/drivers/watchdog/s3c2410_wdt.c
++++ b/drivers/watchdog/s3c2410_wdt.c
+@@ -23,9 +23,9 @@
+ #include <linux/slab.h>
+ #include <linux/err.h>
+ #include <linux/of.h>
++#include <linux/mfd/syscon.h>
+ #include <linux/regmap.h>
+ #include <linux/delay.h>
+-#include <linux/soc/samsung/exynos-pmu.h>
+ #define S3C2410_WTCON         0x00
+ #define S3C2410_WTDAT         0x04
+@@ -640,11 +640,11 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
+               return ret;
+       if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) {
+-              wdt->pmureg = exynos_get_pmu_regmap_by_phandle(dev->of_node,
+-                                               "samsung,syscon-phandle");
++              wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
++                                              "samsung,syscon-phandle");
+               if (IS_ERR(wdt->pmureg))
+                       return dev_err_probe(dev, PTR_ERR(wdt->pmureg),
+-                                           "PMU regmap lookup failed.\n");
++                                           "syscon regmap lookup failed.\n");
+       }
+       wdt_irq = platform_get_irq(pdev, 0);
+-- 
+2.39.5
+
diff --git a/queue-6.6/rust-allow-clippy-needless_lifetimes.patch b/queue-6.6/rust-allow-clippy-needless_lifetimes.patch
new file mode 100644 (file)
index 0000000..b5fff9f
--- /dev/null
@@ -0,0 +1,61 @@
+From b64fdc48b7eaeece3ef525bb3e950b314f93dcd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 Nov 2024 19:15:37 +0100
+Subject: rust: allow `clippy::needless_lifetimes`
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+[ Upstream commit 60fc1e6750133620e404d40b93df5afe32e3e6c6 ]
+
+In beta Clippy (i.e. Rust 1.83.0), the `needless_lifetimes` lint has
+been extended [1] to suggest eliding `impl` lifetimes, e.g.
+
+    error: the following explicit lifetimes could be elided: 'a
+    --> rust/kernel/list.rs:647:6
+        |
+    647 | impl<'a, T: ?Sized + ListItem<ID>, const ID: u64> FusedIterator for Iter<'a, T, ID> {}
+        |      ^^                                                                  ^^
+        |
+        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
+        = note: `-D clippy::needless-lifetimes` implied by `-D warnings`
+        = help: to override `-D warnings` add `#[allow(clippy::needless_lifetimes)]`
+    help: elide the lifetimes
+        |
+    647 - impl<'a, T: ?Sized + ListItem<ID>, const ID: u64> FusedIterator for Iter<'a, T, ID> {}
+    647 + impl<T: ?Sized + ListItem<ID>, const ID: u64> FusedIterator for Iter<'_, T, ID> {}
+
+A possibility would have been to clean them -- the RFC patch [2] did
+this, while asking if we wanted these cleanups. There is an open issue
+[3] in Clippy about being able to differentiate some of the new cases,
+e.g. those that do not involve introducing `'_`. Thus it seems others
+feel similarly.
+
+Thus, for the time being, we decided to `allow` the lint.
+
+Link: https://github.com/rust-lang/rust-clippy/pull/13286 [1]
+Link: https://lore.kernel.org/rust-for-linux/20241012231300.397010-1-ojeda@kernel.org/ [2]
+Link: https://github.com/rust-lang/rust-clippy/issues/13514 [3]
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
+Link: https://lore.kernel.org/r/20241116181538.369355-1-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Makefile | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Makefile b/Makefile
+index 0be58613bfe0..31b4fc9f5ccb 100644
+--- a/Makefile
++++ b/Makefile
+@@ -469,6 +469,7 @@ export rust_common_flags := --edition=2021 \
+                           -Wclippy::let_unit_value -Wclippy::mut_mut \
+                           -Wclippy::needless_bitwise_bool \
+                           -Wclippy::needless_continue \
++                          -Aclippy::needless_lifetimes \
+                           -Wclippy::no_mangle_with_rust_abi \
+                           -Wclippy::dbg_macro
+-- 
+2.39.5
+
diff --git a/queue-6.6/rust-relax-most-deny-level-lints-to-warnings.patch b/queue-6.6/rust-relax-most-deny-level-lints-to-warnings.patch
new file mode 100644 (file)
index 0000000..8441ec6
--- /dev/null
@@ -0,0 +1,116 @@
+From 0953c79b5a2e3eb9a0c0752e7d76bbaf0f6f8666 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jul 2024 18:05:59 +0200
+Subject: rust: relax most deny-level lints to warnings
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+[ Upstream commit f8f88aa25a03ce1e0fc8a9842840988b870f0c37 ]
+
+Since we are starting to support several Rust toolchains, lints (including
+Clippy ones) now may behave differently and lint groups may include
+new lints.
+
+Therefore, to maximize the chances a given version works, relax some
+deny-level lints to warnings. It may also make our lives a bit easier
+while developing new code or refactoring.
+
+To be clear, the requirements for in-tree code are still the same, since
+Rust code still needs to be warning-free (patches should be clean under
+`WERROR=y`) and the set of lints is not changed.
+
+`unsafe_op_in_unsafe_fn` is left unmodified, i.e. as an error, since it is
+becoming the default in the language (warn-by-default in Rust 2024 [1] and
+ideally an error later on) and thus it should also be very well tested. In
+addition, it is simple enough that it should not have false positives
+(unlike e.g. `rust_2018_idioms`'s `explicit_outlives_requirements`).
+
+`non_ascii_idents` is left unmodified as well, i.e. as an error, since
+it is unlikely one gains any productivity during development if it
+were a warning (in fact, it may be worse, since it is likely one made
+a typo). In addition, it should not have false positives.
+
+Finally, put the two `-D` ones at the top and take the chance to do one
+per line.
+
+Link: https://github.com/rust-lang/rust/pull/112038 [1]
+Reviewed-by: Finn Behrens <me@kloenk.dev>
+Tested-by: Benno Lossin <benno.lossin@proton.me>
+Tested-by: Andreas Hindborg <a.hindborg@samsung.com>
+Link: https://lore.kernel.org/r/20240709160615.998336-5-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Stable-dep-of: 60fc1e675013 ("rust: allow `clippy::needless_lifetimes`")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Makefile      | 24 +++++++++++++-----------
+ rust/Makefile |  4 ++--
+ 2 files changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index ec4d9d1d9b7a..0be58613bfe0 100644
+--- a/Makefile
++++ b/Makefile
+@@ -457,17 +457,19 @@ KBUILD_USERLDFLAGS := $(USERLDFLAGS)
+ # host programs.
+ export rust_common_flags := --edition=2021 \
+                           -Zbinary_dep_depinfo=y \
+-                          -Dunsafe_op_in_unsafe_fn -Drust_2018_idioms \
+-                          -Dunreachable_pub -Dnon_ascii_idents \
++                          -Dunsafe_op_in_unsafe_fn \
++                          -Dnon_ascii_idents \
++                          -Wrust_2018_idioms \
++                          -Wunreachable_pub \
+                           -Wmissing_docs \
+-                          -Drustdoc::missing_crate_level_docs \
+-                          -Dclippy::correctness -Dclippy::style \
+-                          -Dclippy::suspicious -Dclippy::complexity \
+-                          -Dclippy::perf \
+-                          -Dclippy::let_unit_value -Dclippy::mut_mut \
+-                          -Dclippy::needless_bitwise_bool \
+-                          -Dclippy::needless_continue \
+-                          -Dclippy::no_mangle_with_rust_abi \
++                          -Wrustdoc::missing_crate_level_docs \
++                          -Wclippy::correctness -Wclippy::style \
++                          -Wclippy::suspicious -Wclippy::complexity \
++                          -Wclippy::perf \
++                          -Wclippy::let_unit_value -Wclippy::mut_mut \
++                          -Wclippy::needless_bitwise_bool \
++                          -Wclippy::needless_continue \
++                          -Wclippy::no_mangle_with_rust_abi \
+                           -Wclippy::dbg_macro
+ KBUILD_HOSTCFLAGS   := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) $(HOSTCFLAGS)
+@@ -572,7 +574,7 @@ KBUILD_RUSTFLAGS := $(rust_common_flags) \
+                   -Csymbol-mangling-version=v0 \
+                   -Crelocation-model=static \
+                   -Zfunction-sections=n \
+-                  -Dclippy::float_arithmetic
++                  -Wclippy::float_arithmetic
+ KBUILD_AFLAGS_KERNEL :=
+ KBUILD_CFLAGS_KERNEL :=
+diff --git a/rust/Makefile b/rust/Makefile
+index 333b9a482473..12b9d78fd25c 100644
+--- a/rust/Makefile
++++ b/rust/Makefile
+@@ -422,7 +422,7 @@ ifneq ($(or $(CONFIG_ARM64),$(and $(CONFIG_RISCV),$(CONFIG_64BIT))),)
+ endif
+ $(obj)/core.o: private skip_clippy = 1
+-$(obj)/core.o: private skip_flags = -Dunreachable_pub
++$(obj)/core.o: private skip_flags = -Wunreachable_pub
+ $(obj)/core.o: private rustc_objcopy = $(foreach sym,$(redirect-intrinsics),--redefine-sym $(sym)=__rust$(sym))
+ $(obj)/core.o: private rustc_target_flags = $(core-cfgs)
+ $(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs scripts/target.json FORCE
+@@ -433,7 +433,7 @@ $(obj)/compiler_builtins.o: $(src)/compiler_builtins.rs $(obj)/core.o FORCE
+       $(call if_changed_dep,rustc_library)
+ $(obj)/alloc.o: private skip_clippy = 1
+-$(obj)/alloc.o: private skip_flags = -Dunreachable_pub
++$(obj)/alloc.o: private skip_flags = -Wunreachable_pub
+ $(obj)/alloc.o: private rustc_target_flags = $(alloc-cfgs)
+ $(obj)/alloc.o: $(src)/alloc/lib.rs $(obj)/compiler_builtins.o FORCE
+       $(call if_changed_dep,rustc_library)
+-- 
+2.39.5
+
diff --git a/queue-6.6/sched-initialize-idle-tasks-only-once.patch b/queue-6.6/sched-initialize-idle-tasks-only-once.patch
new file mode 100644 (file)
index 0000000..5b5de84
--- /dev/null
@@ -0,0 +1,83 @@
+From 1c68684e10d7b59244de0957982a8abfcc6fa994 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Oct 2024 11:43:42 +0100
+Subject: sched: Initialize idle tasks only once
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit b23decf8ac9102fc52c4de5196f4dc0a5f3eb80b ]
+
+Idle tasks are initialized via __sched_fork() twice:
+
+     fork_idle()
+        copy_process()
+         sched_fork()
+             __sched_fork()
+       init_idle()
+          __sched_fork()
+
+Instead of cleaning this up, sched_ext hacked around it. Even when analyis
+and solution were provided in a discussion, nobody cared to clean this up.
+
+init_idle() is also invoked from sched_init() to initialize the boot CPU's
+idle task, which requires the __sched_fork() invocation. But this can be
+trivially solved by invoking __sched_fork() before init_idle() in
+sched_init() and removing the __sched_fork() invocation from init_idle().
+
+Do so and clean up the comments explaining this historical leftover.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20241028103142.359584747@linutronix.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/core.c | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 228f7c07da72..86606fb9e6bc 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -4488,7 +4488,8 @@ int wake_up_state(struct task_struct *p, unsigned int state)
+  * Perform scheduler related setup for a newly forked process p.
+  * p is forked by current.
+  *
+- * __sched_fork() is basic setup used by init_idle() too:
++ * __sched_fork() is basic setup which is also used by sched_init() to
++ * initialize the boot CPU's idle task.
+  */
+ static void __sched_fork(unsigned long clone_flags, struct task_struct *p)
+ {
+@@ -9257,8 +9258,6 @@ void __init init_idle(struct task_struct *idle, int cpu)
+       struct rq *rq = cpu_rq(cpu);
+       unsigned long flags;
+-      __sched_fork(0, idle);
+-
+       raw_spin_lock_irqsave(&idle->pi_lock, flags);
+       raw_spin_rq_lock(rq);
+@@ -9273,10 +9272,8 @@ void __init init_idle(struct task_struct *idle, int cpu)
+ #ifdef CONFIG_SMP
+       /*
+-       * It's possible that init_idle() gets called multiple times on a task,
+-       * in that case do_set_cpus_allowed() will not do the right thing.
+-       *
+-       * And since this is boot we can forgo the serialization.
++       * No validation and serialization required at boot time and for
++       * setting up the idle tasks of not yet online CPUs.
+        */
+       set_cpus_allowed_common(idle, &ac);
+ #endif
+@@ -10105,6 +10102,7 @@ void __init sched_init(void)
+        * but because we are the idle thread, we just pick up running again
+        * when this runqueue becomes "idle".
+        */
++      __sched_fork(0, current);
+       init_idle(current, smp_processor_id());
+       calc_load_update = jiffies + LOAD_FREQ;
+-- 
+2.39.5
+
diff --git a/queue-6.6/scsi-hisi_sas-allocate-dfx-memory-during-dump-trigge.patch b/queue-6.6/scsi-hisi_sas-allocate-dfx-memory-during-dump-trigge.patch
new file mode 100644 (file)
index 0000000..2684ad8
--- /dev/null
@@ -0,0 +1,218 @@
+From 79e22c0c4b2a961b8942f2f788cbf3c7dda7017d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Sep 2023 10:15:27 +0800
+Subject: scsi: hisi_sas: Allocate DFX memory during dump trigger
+
+From: Yihang Li <liyihang9@huawei.com>
+
+[ Upstream commit 63f0733d07ce60252e885602b39571ade0441015 ]
+
+Currently, if CONFIG_SCSI_HISI_SAS_DEBUGFS_DEFAULT_ENABLE is enabled, the
+memory space used by DFX is allocated during device initialization, which
+occupies a large number of memory resources. The memory usage before and
+after the driver is loaded is as follows:
+
+Memory usage before the driver is loaded:
+$ free -m
+         total        used        free      shared  buff/cache   available
+Mem:     867352        2578      864037          11         735  861681
+Swap:    4095           0        4095
+
+Memory usage after the driver which include 4 HBAs is loaded:
+$ insmod hisi_sas_v3_hw.ko
+$ free -m
+         total        used        free      shared  buff/cache available
+Mem:     867352        4760      861848          11      743   859495
+Swap:    4095           0        4095
+
+The driver with 4 HBAs connected will allocate about 110 MB of memory
+without enabling debugfs.
+
+Therefore, to avoid wasting memory resources, DFX memory is allocated
+during dump triggering. The dump may fail due to memory allocation
+failure. After this change, each dump costs about 10 MB of memory, and each
+dump lasts about 100 ms.
+
+Signed-off-by: Yihang Li <liyihang9@huawei.com>
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Link: https://lore.kernel.org/r/1694571327-78697-4-git-send-email-chenxiang66@hisilicon.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Stable-dep-of: 9f564f15f884 ("scsi: hisi_sas: Create all dump files during debugfs initialization")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h       |  2 +-
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 93 +++++++++++++-------------
+ 2 files changed, 46 insertions(+), 49 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index 3d511c44c02d..1e4550156b73 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -343,7 +343,7 @@ struct hisi_sas_hw {
+                               u8 reg_index, u8 reg_count, u8 *write_data);
+       void (*wait_cmds_complete_timeout)(struct hisi_hba *hisi_hba,
+                                          int delay_ms, int timeout_ms);
+-      void (*debugfs_snapshot_regs)(struct hisi_hba *hisi_hba);
++      int (*debugfs_snapshot_regs)(struct hisi_hba *hisi_hba);
+       int complete_hdr_size;
+       const struct scsi_host_template *sht;
+ };
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 10f048b5a489..cea548655629 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -558,7 +558,7 @@ static int experimental_iopoll_q_cnt;
+ module_param(experimental_iopoll_q_cnt, int, 0444);
+ MODULE_PARM_DESC(experimental_iopoll_q_cnt, "number of queues to be used as poll mode, def=0");
+-static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba);
++static int debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba);
+ static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
+ {
+@@ -3867,37 +3867,6 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
+                           &debugfs_ras_v3_hw_fops);
+ }
+-static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba)
+-{
+-      int debugfs_dump_index = hisi_hba->debugfs_dump_index;
+-      struct device *dev = hisi_hba->dev;
+-      u64 timestamp = local_clock();
+-
+-      if (debugfs_dump_index >= hisi_sas_debugfs_dump_count) {
+-              dev_warn(dev, "dump count exceeded!\n");
+-              return;
+-      }
+-
+-      do_div(timestamp, NSEC_PER_MSEC);
+-      hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp;
+-
+-      debugfs_snapshot_prepare_v3_hw(hisi_hba);
+-
+-      debugfs_snapshot_global_reg_v3_hw(hisi_hba);
+-      debugfs_snapshot_port_reg_v3_hw(hisi_hba);
+-      debugfs_snapshot_axi_reg_v3_hw(hisi_hba);
+-      debugfs_snapshot_ras_reg_v3_hw(hisi_hba);
+-      debugfs_snapshot_cq_reg_v3_hw(hisi_hba);
+-      debugfs_snapshot_dq_reg_v3_hw(hisi_hba);
+-      debugfs_snapshot_itct_reg_v3_hw(hisi_hba);
+-      debugfs_snapshot_iost_reg_v3_hw(hisi_hba);
+-
+-      debugfs_create_files_v3_hw(hisi_hba);
+-
+-      debugfs_snapshot_restore_v3_hw(hisi_hba);
+-      hisi_hba->debugfs_dump_index++;
+-}
+-
+ static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file,
+                                               const char __user *user_buf,
+                                               size_t count, loff_t *ppos)
+@@ -3905,9 +3874,6 @@ static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file,
+       struct hisi_hba *hisi_hba = file->f_inode->i_private;
+       char buf[8];
+-      if (hisi_hba->debugfs_dump_index >= hisi_sas_debugfs_dump_count)
+-              return -EFAULT;
+-
+       if (count > 8)
+               return -EFAULT;
+@@ -3918,7 +3884,10 @@ static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file,
+               return -EFAULT;
+       down(&hisi_hba->sem);
+-      debugfs_snapshot_regs_v3_hw(hisi_hba);
++      if (debugfs_snapshot_regs_v3_hw(hisi_hba)) {
++              up(&hisi_hba->sem);
++              return -EFAULT;
++      }
+       up(&hisi_hba->sem);
+       return count;
+@@ -4704,7 +4673,7 @@ static int debugfs_alloc_v3_hw(struct hisi_hba *hisi_hba, int dump_index)
+ {
+       const struct hisi_sas_hw *hw = hisi_hba->hw;
+       struct device *dev = hisi_hba->dev;
+-      int p, c, d, r, i;
++      int p, c, d, r;
+       size_t sz;
+       for (r = 0; r < DEBUGFS_REGS_NUM; r++) {
+@@ -4784,11 +4753,48 @@ static int debugfs_alloc_v3_hw(struct hisi_hba *hisi_hba, int dump_index)
+       return 0;
+ fail:
+-      for (i = 0; i < hisi_sas_debugfs_dump_count; i++)
+-              debugfs_release_v3_hw(hisi_hba, i);
++      debugfs_release_v3_hw(hisi_hba, dump_index);
+       return -ENOMEM;
+ }
++static int debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba)
++{
++      int debugfs_dump_index = hisi_hba->debugfs_dump_index;
++      struct device *dev = hisi_hba->dev;
++      u64 timestamp = local_clock();
++
++      if (debugfs_dump_index >= hisi_sas_debugfs_dump_count) {
++              dev_warn(dev, "dump count exceeded!\n");
++              return -EINVAL;
++      }
++
++      if (debugfs_alloc_v3_hw(hisi_hba, debugfs_dump_index)) {
++              dev_warn(dev, "failed to alloc memory\n");
++              return -ENOMEM;
++      }
++
++      do_div(timestamp, NSEC_PER_MSEC);
++      hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp;
++
++      debugfs_snapshot_prepare_v3_hw(hisi_hba);
++
++      debugfs_snapshot_global_reg_v3_hw(hisi_hba);
++      debugfs_snapshot_port_reg_v3_hw(hisi_hba);
++      debugfs_snapshot_axi_reg_v3_hw(hisi_hba);
++      debugfs_snapshot_ras_reg_v3_hw(hisi_hba);
++      debugfs_snapshot_cq_reg_v3_hw(hisi_hba);
++      debugfs_snapshot_dq_reg_v3_hw(hisi_hba);
++      debugfs_snapshot_itct_reg_v3_hw(hisi_hba);
++      debugfs_snapshot_iost_reg_v3_hw(hisi_hba);
++
++      debugfs_create_files_v3_hw(hisi_hba);
++
++      debugfs_snapshot_restore_v3_hw(hisi_hba);
++      hisi_hba->debugfs_dump_index++;
++
++      return 0;
++}
++
+ static void debugfs_phy_down_cnt_init_v3_hw(struct hisi_hba *hisi_hba)
+ {
+       struct dentry *dir = debugfs_create_dir("phy_down_cnt",
+@@ -4875,7 +4881,6 @@ static void debugfs_exit_v3_hw(struct hisi_hba *hisi_hba)
+ static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba)
+ {
+       struct device *dev = hisi_hba->dev;
+-      int i;
+       hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev),
+                                                  hisi_sas_debugfs_dir);
+@@ -4892,14 +4897,6 @@ static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba)
+       debugfs_phy_down_cnt_init_v3_hw(hisi_hba);
+       debugfs_fifo_init_v3_hw(hisi_hba);
+-
+-      for (i = 0; i < hisi_sas_debugfs_dump_count; i++) {
+-              if (debugfs_alloc_v3_hw(hisi_hba, i)) {
+-                      debugfs_exit_v3_hw(hisi_hba);
+-                      dev_dbg(dev, "failed to init debugfs!\n");
+-                      break;
+-              }
+-      }
+ }
+ static int
+-- 
+2.39.5
+
diff --git a/queue-6.6/scsi-hisi_sas-create-all-dump-files-during-debugfs-i.patch b/queue-6.6/scsi-hisi_sas-create-all-dump-files-during-debugfs-i.patch
new file mode 100644 (file)
index 0000000..99fc88c
--- /dev/null
@@ -0,0 +1,367 @@
+From 0cc7a12acc537f05cbb27a4d4630a0117826440d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Oct 2024 10:18:21 +0800
+Subject: scsi: hisi_sas: Create all dump files during debugfs initialization
+
+From: Yihang Li <liyihang9@huawei.com>
+
+[ Upstream commit 9f564f15f88490b484e02442dc4c4b11640ea172 ]
+
+For the current debugfs of hisi_sas, after user triggers dump, the
+driver allocate memory space to save the register information and create
+debugfs files to display the saved information. In this process, the
+debugfs files created after each dump.
+
+Therefore, when the dump is triggered while the driver is unbind, the
+following hang occurs:
+
+[67840.853907] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000a0
+[67840.862947] Mem abort info:
+[67840.865855]   ESR = 0x0000000096000004
+[67840.869713]   EC = 0x25: DABT (current EL), IL = 32 bits
+[67840.875125]   SET = 0, FnV = 0
+[67840.878291]   EA = 0, S1PTW = 0
+[67840.881545]   FSC = 0x04: level 0 translation fault
+[67840.886528] Data abort info:
+[67840.889524]   ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
+[67840.895117]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
+[67840.900284]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+[67840.905709] user pgtable: 4k pages, 48-bit VAs, pgdp=0000002803a1f000
+[67840.912263] [00000000000000a0] pgd=0000000000000000, p4d=0000000000000000
+[67840.919177] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
+[67840.996435] pstate: 80400009 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+[67841.003628] pc : down_write+0x30/0x98
+[67841.007546] lr : start_creating.part.0+0x60/0x198
+[67841.012495] sp : ffff8000b979ba20
+[67841.016046] x29: ffff8000b979ba20 x28: 0000000000000010 x27: 0000000000024b40
+[67841.023412] x26: 0000000000000012 x25: ffff20202b355ae8 x24: ffff20202b35a8c8
+[67841.030779] x23: ffffa36877928208 x22: ffffa368b4972240 x21: ffff8000b979bb18
+[67841.038147] x20: ffff00281dc1e3c0 x19: fffffffffffffffe x18: 0000000000000020
+[67841.045515] x17: 0000000000000000 x16: ffffa368b128a530 x15: ffffffffffffffff
+[67841.052888] x14: ffff8000b979bc18 x13: ffffffffffffffff x12: ffff8000b979bb18
+[67841.060263] x11: 0000000000000000 x10: 0000000000000000 x9 : ffffa368b1289b18
+[67841.067640] x8 : 0000000000000012 x7 : 0000000000000000 x6 : 00000000000003a9
+[67841.075014] x5 : 0000000000000000 x4 : ffff002818c5cb00 x3 : 0000000000000001
+[67841.082388] x2 : 0000000000000000 x1 : ffff002818c5cb00 x0 : 00000000000000a0
+[67841.089759] Call trace:
+[67841.092456]  down_write+0x30/0x98
+[67841.096017]  start_creating.part.0+0x60/0x198
+[67841.100613]  debugfs_create_dir+0x48/0x1f8
+[67841.104950]  debugfs_create_files_v3_hw+0x88/0x348 [hisi_sas_v3_hw]
+[67841.111447]  debugfs_snapshot_regs_v3_hw+0x708/0x798 [hisi_sas_v3_hw]
+[67841.118111]  debugfs_trigger_dump_v3_hw_write+0x9c/0x120 [hisi_sas_v3_hw]
+[67841.125115]  full_proxy_write+0x68/0xc8
+[67841.129175]  vfs_write+0xd8/0x3f0
+[67841.132708]  ksys_write+0x70/0x108
+[67841.136317]  __arm64_sys_write+0x24/0x38
+[67841.140440]  invoke_syscall+0x50/0x128
+[67841.144385]  el0_svc_common.constprop.0+0xc8/0xf0
+[67841.149273]  do_el0_svc+0x24/0x38
+[67841.152773]  el0_svc+0x38/0xd8
+[67841.156009]  el0t_64_sync_handler+0xc0/0xc8
+[67841.160361]  el0t_64_sync+0x1a4/0x1a8
+[67841.164189] Code: b9000882 d2800002 d2800023 f9800011 (c85ffc05)
+[67841.170443] ---[ end trace 0000000000000000 ]---
+
+To fix this issue, create all directories and files during debugfs
+initialization. In this way, the driver only needs to allocate memory
+space to save information each time the user triggers dumping.
+
+Signed-off-by: Yihang Li <liyihang9@huawei.com>
+Link: https://lore.kernel.org/r/20241008021822.2617339-13-liyihang9@huawei.com
+Reviewed-by: Xingui Yang <yangxingui@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 99 ++++++++++++++++++++------
+ 1 file changed, 77 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index cea548655629..ff5f86867dbf 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -3560,6 +3560,11 @@ debugfs_to_reg_name_v3_hw(int off, int base_off,
+       return NULL;
+ }
++static bool debugfs_dump_is_generated_v3_hw(void *p)
++{
++      return p ? true : false;
++}
++
+ static void debugfs_print_reg_v3_hw(u32 *regs_val, struct seq_file *s,
+                                   const struct hisi_sas_debugfs_reg *reg)
+ {
+@@ -3585,6 +3590,9 @@ static int debugfs_global_v3_hw_show(struct seq_file *s, void *p)
+ {
+       struct hisi_sas_debugfs_regs *global = s->private;
++      if (!debugfs_dump_is_generated_v3_hw(global->data))
++              return -EPERM;
++
+       debugfs_print_reg_v3_hw(global->data, s,
+                               &debugfs_global_reg);
+@@ -3596,6 +3604,9 @@ static int debugfs_axi_v3_hw_show(struct seq_file *s, void *p)
+ {
+       struct hisi_sas_debugfs_regs *axi = s->private;
++      if (!debugfs_dump_is_generated_v3_hw(axi->data))
++              return -EPERM;
++
+       debugfs_print_reg_v3_hw(axi->data, s,
+                               &debugfs_axi_reg);
+@@ -3607,6 +3618,9 @@ static int debugfs_ras_v3_hw_show(struct seq_file *s, void *p)
+ {
+       struct hisi_sas_debugfs_regs *ras = s->private;
++      if (!debugfs_dump_is_generated_v3_hw(ras->data))
++              return -EPERM;
++
+       debugfs_print_reg_v3_hw(ras->data, s,
+                               &debugfs_ras_reg);
+@@ -3619,6 +3633,9 @@ static int debugfs_port_v3_hw_show(struct seq_file *s, void *p)
+       struct hisi_sas_debugfs_port *port = s->private;
+       const struct hisi_sas_debugfs_reg *reg_port = &debugfs_port_reg;
++      if (!debugfs_dump_is_generated_v3_hw(port->data))
++              return -EPERM;
++
+       debugfs_print_reg_v3_hw(port->data, s, reg_port);
+       return 0;
+@@ -3674,6 +3691,9 @@ static int debugfs_cq_v3_hw_show(struct seq_file *s, void *p)
+       struct hisi_sas_debugfs_cq *debugfs_cq = s->private;
+       int slot;
++      if (!debugfs_dump_is_generated_v3_hw(debugfs_cq->complete_hdr))
++              return -EPERM;
++
+       for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++)
+               debugfs_cq_show_slot_v3_hw(s, slot, debugfs_cq);
+@@ -3695,8 +3715,12 @@ static void debugfs_dq_show_slot_v3_hw(struct seq_file *s, int slot,
+ static int debugfs_dq_v3_hw_show(struct seq_file *s, void *p)
+ {
++      struct hisi_sas_debugfs_dq *debugfs_dq = s->private;
+       int slot;
++      if (!debugfs_dump_is_generated_v3_hw(debugfs_dq->hdr))
++              return -EPERM;
++
+       for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++)
+               debugfs_dq_show_slot_v3_hw(s, slot, s->private);
+@@ -3710,6 +3734,9 @@ static int debugfs_iost_v3_hw_show(struct seq_file *s, void *p)
+       struct hisi_sas_iost *iost = debugfs_iost->iost;
+       int i, max_command_entries = HISI_SAS_MAX_COMMANDS;
++      if (!debugfs_dump_is_generated_v3_hw(iost))
++              return -EPERM;
++
+       for (i = 0; i < max_command_entries; i++, iost++) {
+               __le64 *data = &iost->qw0;
+@@ -3729,6 +3756,9 @@ static int debugfs_iost_cache_v3_hw_show(struct seq_file *s, void *p)
+       int i, tab_idx;
+       __le64 *iost;
++      if (!debugfs_dump_is_generated_v3_hw(iost_cache))
++              return -EPERM;
++
+       for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, iost_cache++) {
+               /*
+                * Data struct of IOST cache:
+@@ -3752,6 +3782,9 @@ static int debugfs_itct_v3_hw_show(struct seq_file *s, void *p)
+       struct hisi_sas_debugfs_itct *debugfs_itct = s->private;
+       struct hisi_sas_itct *itct = debugfs_itct->itct;
++      if (!debugfs_dump_is_generated_v3_hw(itct))
++              return -EPERM;
++
+       for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, itct++) {
+               __le64 *data = &itct->qw0;
+@@ -3771,6 +3804,9 @@ static int debugfs_itct_cache_v3_hw_show(struct seq_file *s, void *p)
+       int i, tab_idx;
+       __le64 *itct;
++      if (!debugfs_dump_is_generated_v3_hw(itct_cache))
++              return -EPERM;
++
+       for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, itct_cache++) {
+               /*
+                * Data struct of ITCT cache:
+@@ -3788,10 +3824,9 @@ static int debugfs_itct_cache_v3_hw_show(struct seq_file *s, void *p)
+ }
+ DEFINE_SHOW_ATTRIBUTE(debugfs_itct_cache_v3_hw);
+-static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
++static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index)
+ {
+       u64 *debugfs_timestamp;
+-      int dump_index = hisi_hba->debugfs_dump_index;
+       struct dentry *dump_dentry;
+       struct dentry *dentry;
+       char name[256];
+@@ -3799,17 +3834,17 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
+       int c;
+       int d;
+-      snprintf(name, 256, "%d", dump_index);
++      snprintf(name, 256, "%d", index);
+       dump_dentry = debugfs_create_dir(name, hisi_hba->debugfs_dump_dentry);
+-      debugfs_timestamp = &hisi_hba->debugfs_timestamp[dump_index];
++      debugfs_timestamp = &hisi_hba->debugfs_timestamp[index];
+       debugfs_create_u64("timestamp", 0400, dump_dentry,
+                          debugfs_timestamp);
+       debugfs_create_file("global", 0400, dump_dentry,
+-                          &hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL],
++                          &hisi_hba->debugfs_regs[index][DEBUGFS_GLOBAL],
+                           &debugfs_global_v3_hw_fops);
+       /* Create port dir and files */
+@@ -3818,7 +3853,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
+               snprintf(name, 256, "%d", p);
+               debugfs_create_file(name, 0400, dentry,
+-                                  &hisi_hba->debugfs_port_reg[dump_index][p],
++                                  &hisi_hba->debugfs_port_reg[index][p],
+                                   &debugfs_port_v3_hw_fops);
+       }
+@@ -3828,7 +3863,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
+               snprintf(name, 256, "%d", c);
+               debugfs_create_file(name, 0400, dentry,
+-                                  &hisi_hba->debugfs_cq[dump_index][c],
++                                  &hisi_hba->debugfs_cq[index][c],
+                                   &debugfs_cq_v3_hw_fops);
+       }
+@@ -3838,32 +3873,32 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
+               snprintf(name, 256, "%d", d);
+               debugfs_create_file(name, 0400, dentry,
+-                                  &hisi_hba->debugfs_dq[dump_index][d],
++                                  &hisi_hba->debugfs_dq[index][d],
+                                   &debugfs_dq_v3_hw_fops);
+       }
+       debugfs_create_file("iost", 0400, dump_dentry,
+-                          &hisi_hba->debugfs_iost[dump_index],
++                          &hisi_hba->debugfs_iost[index],
+                           &debugfs_iost_v3_hw_fops);
+       debugfs_create_file("iost_cache", 0400, dump_dentry,
+-                          &hisi_hba->debugfs_iost_cache[dump_index],
++                          &hisi_hba->debugfs_iost_cache[index],
+                           &debugfs_iost_cache_v3_hw_fops);
+       debugfs_create_file("itct", 0400, dump_dentry,
+-                          &hisi_hba->debugfs_itct[dump_index],
++                          &hisi_hba->debugfs_itct[index],
+                           &debugfs_itct_v3_hw_fops);
+       debugfs_create_file("itct_cache", 0400, dump_dentry,
+-                          &hisi_hba->debugfs_itct_cache[dump_index],
++                          &hisi_hba->debugfs_itct_cache[index],
+                           &debugfs_itct_cache_v3_hw_fops);
+       debugfs_create_file("axi", 0400, dump_dentry,
+-                          &hisi_hba->debugfs_regs[dump_index][DEBUGFS_AXI],
++                          &hisi_hba->debugfs_regs[index][DEBUGFS_AXI],
+                           &debugfs_axi_v3_hw_fops);
+       debugfs_create_file("ras", 0400, dump_dentry,
+-                          &hisi_hba->debugfs_regs[dump_index][DEBUGFS_RAS],
++                          &hisi_hba->debugfs_regs[index][DEBUGFS_RAS],
+                           &debugfs_ras_v3_hw_fops);
+ }
+@@ -4645,22 +4680,34 @@ static void debugfs_release_v3_hw(struct hisi_hba *hisi_hba, int dump_index)
+       int i;
+       devm_kfree(dev, hisi_hba->debugfs_iost_cache[dump_index].cache);
++      hisi_hba->debugfs_iost_cache[dump_index].cache = NULL;
+       devm_kfree(dev, hisi_hba->debugfs_itct_cache[dump_index].cache);
++      hisi_hba->debugfs_itct_cache[dump_index].cache = NULL;
+       devm_kfree(dev, hisi_hba->debugfs_iost[dump_index].iost);
++      hisi_hba->debugfs_iost[dump_index].iost = NULL;
+       devm_kfree(dev, hisi_hba->debugfs_itct[dump_index].itct);
++      hisi_hba->debugfs_itct[dump_index].itct = NULL;
+-      for (i = 0; i < hisi_hba->queue_count; i++)
++      for (i = 0; i < hisi_hba->queue_count; i++) {
+               devm_kfree(dev, hisi_hba->debugfs_dq[dump_index][i].hdr);
++              hisi_hba->debugfs_dq[dump_index][i].hdr = NULL;
++      }
+-      for (i = 0; i < hisi_hba->queue_count; i++)
++      for (i = 0; i < hisi_hba->queue_count; i++) {
+               devm_kfree(dev,
+                          hisi_hba->debugfs_cq[dump_index][i].complete_hdr);
++              hisi_hba->debugfs_cq[dump_index][i].complete_hdr = NULL;
++      }
+-      for (i = 0; i < DEBUGFS_REGS_NUM; i++)
++      for (i = 0; i < DEBUGFS_REGS_NUM; i++) {
+               devm_kfree(dev, hisi_hba->debugfs_regs[dump_index][i].data);
++              hisi_hba->debugfs_regs[dump_index][i].data = NULL;
++      }
+-      for (i = 0; i < hisi_hba->n_phy; i++)
++      for (i = 0; i < hisi_hba->n_phy; i++) {
+               devm_kfree(dev, hisi_hba->debugfs_port_reg[dump_index][i].data);
++              hisi_hba->debugfs_port_reg[dump_index][i].data = NULL;
++      }
+ }
+ static const struct hisi_sas_debugfs_reg *debugfs_reg_array_v3_hw[DEBUGFS_REGS_NUM] = {
+@@ -4787,8 +4834,6 @@ static int debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba)
+       debugfs_snapshot_itct_reg_v3_hw(hisi_hba);
+       debugfs_snapshot_iost_reg_v3_hw(hisi_hba);
+-      debugfs_create_files_v3_hw(hisi_hba);
+-
+       debugfs_snapshot_restore_v3_hw(hisi_hba);
+       hisi_hba->debugfs_dump_index++;
+@@ -4872,6 +4917,17 @@ static void debugfs_bist_init_v3_hw(struct hisi_hba *hisi_hba)
+       hisi_hba->debugfs_bist_linkrate = SAS_LINK_RATE_1_5_GBPS;
+ }
++static void debugfs_dump_init_v3_hw(struct hisi_hba *hisi_hba)
++{
++      int i;
++
++      hisi_hba->debugfs_dump_dentry =
++                      debugfs_create_dir("dump", hisi_hba->debugfs_dir);
++
++      for (i = 0; i < hisi_sas_debugfs_dump_count; i++)
++              debugfs_create_files_v3_hw(hisi_hba, i);
++}
++
+ static void debugfs_exit_v3_hw(struct hisi_hba *hisi_hba)
+ {
+       debugfs_remove_recursive(hisi_hba->debugfs_dir);
+@@ -4892,8 +4948,7 @@ static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba)
+       /* create bist structures */
+       debugfs_bist_init_v3_hw(hisi_hba);
+-      hisi_hba->debugfs_dump_dentry =
+-                      debugfs_create_dir("dump", hisi_hba->debugfs_dir);
++      debugfs_dump_init_v3_hw(hisi_hba);
+       debugfs_phy_down_cnt_init_v3_hw(hisi_hba);
+       debugfs_fifo_init_v3_hw(hisi_hba);
+-- 
+2.39.5
+
diff --git a/queue-6.6/scsi-hisi_sas-directly-call-register-snapshot-instea.patch b/queue-6.6/scsi-hisi_sas-directly-call-register-snapshot-instea.patch
new file mode 100644 (file)
index 0000000..bc50a57
--- /dev/null
@@ -0,0 +1,108 @@
+From 2887d53cae84d6f45259c6ad9a1bb4cadfa32e18 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Sep 2023 10:15:26 +0800
+Subject: scsi: hisi_sas: Directly call register snapshot instead of using
+ workqueue
+
+From: Yihang Li <liyihang9@huawei.com>
+
+[ Upstream commit 2ff07b5c6fe9173e7a7de3b23f300d71ad4d8fde ]
+
+Currently, register information dump is performed via workqueue, regardless
+of the trigger mode (automatic or manual). There is a delay in dumping
+register through workqueue, the exact register information at trigger time
+cannot be obtained.
+
+Call register snapshot directly instead of through a workqueue.
+
+Signed-off-by: Yihang Li <liyihang9@huawei.com>
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Link: https://lore.kernel.org/r/1694571327-78697-3-git-send-email-chenxiang66@hisilicon.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Stable-dep-of: 9f564f15f884 ("scsi: hisi_sas: Create all dump files during debugfs initialization")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h       |  1 -
+ drivers/scsi/hisi_sas/hisi_sas_main.c  |  7 +++++--
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 14 +++-----------
+ 3 files changed, 8 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index 9e73e9cbbcfc..3d511c44c02d 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -451,7 +451,6 @@ struct hisi_hba {
+       const struct hisi_sas_hw *hw;   /* Low level hw interface */
+       unsigned long sata_dev_bitmap[BITS_TO_LONGS(HISI_SAS_MAX_DEVICES)];
+       struct work_struct rst_work;
+-      struct work_struct debugfs_work;
+       u32 phy_state;
+       u32 intr_coal_ticks;    /* Time of interrupt coalesce in us */
+       u32 intr_coal_count;    /* Interrupt count to coalesce */
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index db9ae206974c..5fdba7b39a1b 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1967,8 +1967,11 @@ static bool hisi_sas_internal_abort_timeout(struct sas_task *task,
+       struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
+       struct hisi_sas_internal_abort_data *timeout = data;
+-      if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct)
+-              queue_work(hisi_hba->wq, &hisi_hba->debugfs_work);
++      if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) {
++              down(&hisi_hba->sem);
++              hisi_hba->hw->debugfs_snapshot_regs(hisi_hba);
++              up(&hisi_hba->sem);
++      }
+       if (task->task_state_flags & SAS_TASK_STATE_DONE) {
+               pr_err("Internal abort: timeout %016llx\n",
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 4054659d48f7..10f048b5a489 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -558,7 +558,6 @@ static int experimental_iopoll_q_cnt;
+ module_param(experimental_iopoll_q_cnt, int, 0444);
+ MODULE_PARM_DESC(experimental_iopoll_q_cnt, "number of queues to be used as poll mode, def=0");
+-static void debugfs_work_handler_v3_hw(struct work_struct *work);
+ static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba);
+ static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
+@@ -3397,7 +3396,6 @@ hisi_sas_shost_alloc_pci(struct pci_dev *pdev)
+       hisi_hba = shost_priv(shost);
+       INIT_WORK(&hisi_hba->rst_work, hisi_sas_rst_work_handler);
+-      INIT_WORK(&hisi_hba->debugfs_work, debugfs_work_handler_v3_hw);
+       hisi_hba->hw = &hisi_sas_v3_hw;
+       hisi_hba->pci_dev = pdev;
+       hisi_hba->dev = dev;
+@@ -3919,7 +3917,9 @@ static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file,
+       if (buf[0] != '1')
+               return -EFAULT;
+-      queue_work(hisi_hba->wq, &hisi_hba->debugfs_work);
++      down(&hisi_hba->sem);
++      debugfs_snapshot_regs_v3_hw(hisi_hba);
++      up(&hisi_hba->sem);
+       return count;
+ }
+@@ -4670,14 +4670,6 @@ static void debugfs_fifo_init_v3_hw(struct hisi_hba *hisi_hba)
+       }
+ }
+-static void debugfs_work_handler_v3_hw(struct work_struct *work)
+-{
+-      struct hisi_hba *hisi_hba =
+-              container_of(work, struct hisi_hba, debugfs_work);
+-
+-      debugfs_snapshot_regs_v3_hw(hisi_hba);
+-}
+-
+ static void debugfs_release_v3_hw(struct hisi_hba *hisi_hba, int dump_index)
+ {
+       struct device *dev = hisi_hba->dev;
+-- 
+2.39.5
+
diff --git a/queue-6.6/scsi-hisi_sas-fix-a-deadlock-issue-related-to-automa.patch b/queue-6.6/scsi-hisi_sas-fix-a-deadlock-issue-related-to-automa.patch
new file mode 100644 (file)
index 0000000..d549419
--- /dev/null
@@ -0,0 +1,125 @@
+From 0f2f7ea319f6a532f8336eca9a7846846e6d70a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jan 2024 14:25:44 +0800
+Subject: scsi: hisi_sas: Fix a deadlock issue related to automatic dump
+
+From: Yihang Li <liyihang9@huawei.com>
+
+[ Upstream commit 3c4f53b2c341ec6428b98cb51a89a09b025d0953 ]
+
+If we issue a disabling PHY command, the device attached with it will go
+offline, if a 2 bit ECC error occurs at the same time, a hung task may be
+found:
+
+[ 4613.652388] INFO: task kworker/u256:0:165233 blocked for more than 120 seconds.
+[ 4613.666297] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+[ 4613.674809] task:kworker/u256:0  state:D stack:    0 pid:165233 ppid:     2 flags:0x00000208
+[ 4613.683959] Workqueue: 0000:74:02.0_disco_q sas_revalidate_domain [libsas]
+[ 4613.691518] Call trace:
+[ 4613.694678]  __switch_to+0xf8/0x17c
+[ 4613.698872]  __schedule+0x660/0xee0
+[ 4613.703063]  schedule+0xac/0x240
+[ 4613.706994]  schedule_timeout+0x500/0x610
+[ 4613.711705]  __down+0x128/0x36c
+[ 4613.715548]  down+0x240/0x2d0
+[ 4613.719221]  hisi_sas_internal_abort_timeout+0x1bc/0x260 [hisi_sas_main]
+[ 4613.726618]  sas_execute_internal_abort+0x144/0x310 [libsas]
+[ 4613.732976]  sas_execute_internal_abort_dev+0x44/0x60 [libsas]
+[ 4613.739504]  hisi_sas_internal_task_abort_dev.isra.0+0xbc/0x1b0 [hisi_sas_main]
+[ 4613.747499]  hisi_sas_dev_gone+0x174/0x250 [hisi_sas_main]
+[ 4613.753682]  sas_notify_lldd_dev_gone+0xec/0x2e0 [libsas]
+[ 4613.759781]  sas_unregister_common_dev+0x4c/0x7a0 [libsas]
+[ 4613.765962]  sas_destruct_devices+0xb8/0x120 [libsas]
+[ 4613.771709]  sas_do_revalidate_domain.constprop.0+0x1b8/0x31c [libsas]
+[ 4613.778930]  sas_revalidate_domain+0x60/0xa4 [libsas]
+[ 4613.784716]  process_one_work+0x248/0x950
+[ 4613.789424]  worker_thread+0x318/0x934
+[ 4613.793878]  kthread+0x190/0x200
+[ 4613.797810]  ret_from_fork+0x10/0x18
+[ 4613.802121] INFO: task kworker/u256:4:316722 blocked for more than 120 seconds.
+[ 4613.816026] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+[ 4613.824538] task:kworker/u256:4  state:D stack:    0 pid:316722 ppid:     2 flags:0x00000208
+[ 4613.833670] Workqueue: 0000:74:02.0 hisi_sas_rst_work_handler [hisi_sas_main]
+[ 4613.841491] Call trace:
+[ 4613.844647]  __switch_to+0xf8/0x17c
+[ 4613.848852]  __schedule+0x660/0xee0
+[ 4613.853052]  schedule+0xac/0x240
+[ 4613.856984]  schedule_timeout+0x500/0x610
+[ 4613.861695]  __down+0x128/0x36c
+[ 4613.865542]  down+0x240/0x2d0
+[ 4613.869216]  hisi_sas_controller_prereset+0x58/0x1fc [hisi_sas_main]
+[ 4613.876324]  hisi_sas_rst_work_handler+0x40/0x8c [hisi_sas_main]
+[ 4613.883019]  process_one_work+0x248/0x950
+[ 4613.887732]  worker_thread+0x318/0x934
+[ 4613.892204]  kthread+0x190/0x200
+[ 4613.896118]  ret_from_fork+0x10/0x18
+[ 4613.900423] INFO: task kworker/u256:1:348985 blocked for more than 121 seconds.
+[ 4613.914341] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+[ 4613.922852] task:kworker/u256:1  state:D stack:    0 pid:348985 ppid:     2 flags:0x00000208
+[ 4613.931984] Workqueue: 0000:74:02.0_event_q sas_port_event_worker [libsas]
+[ 4613.939549] Call trace:
+[ 4613.942702]  __switch_to+0xf8/0x17c
+[ 4613.946892]  __schedule+0x660/0xee0
+[ 4613.951083]  schedule+0xac/0x240
+[ 4613.955015]  schedule_timeout+0x500/0x610
+[ 4613.959725]  wait_for_common+0x200/0x610
+[ 4613.964349]  wait_for_completion+0x3c/0x5c
+[ 4613.969146]  flush_workqueue+0x198/0x790
+[ 4613.973776]  sas_porte_broadcast_rcvd+0x1e8/0x320 [libsas]
+[ 4613.979960]  sas_port_event_worker+0x54/0xa0 [libsas]
+[ 4613.985708]  process_one_work+0x248/0x950
+[ 4613.990420]  worker_thread+0x318/0x934
+[ 4613.994868]  kthread+0x190/0x200
+[ 4613.998800]  ret_from_fork+0x10/0x18
+
+This is because when the device goes offline, we obtain the hisi_hba
+semaphore and send the ABORT_DEV command to the device. However, the
+internal abort timed out due to the 2 bit ECC error and triggers automatic
+dump. In addition, since the hisi_hba semaphore has been obtained, the dump
+cannot be executed and the controller cannot be reset.
+
+Therefore, the deadlocks occur on the following circular dependencies:
+hisi_sas_dev_gone() -> down() -> hisi_sas_internal_task_abort_dev() -> ...
+-> hisi_sas_internal_abort_timeout() -> down().
+
+The deadlock is triggered only when the timeout occurs during device goes
+offline. To fix this issue, use .rst_ha_timeout to distinguish the scenario
+where a device goes offline from other scenarios.
+
+Fixes: 2ff07b5c6fe9 ("scsi: hisi_sas: Directly call register snapshot instead of using workqueue")
+Signed-off-by: Yihang Li <liyihang9@huawei.com>
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Link: https://lore.kernel.org/r/1705904747-62186-2-git-send-email-chenxiang66@hisilicon.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 5fdba7b39a1b..4ce737ddb058 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1968,9 +1968,17 @@ static bool hisi_sas_internal_abort_timeout(struct sas_task *task,
+       struct hisi_sas_internal_abort_data *timeout = data;
+       if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) {
+-              down(&hisi_hba->sem);
++              /*
++               * If timeout occurs in device gone scenario, to avoid
++               * circular dependency like:
++               * hisi_sas_dev_gone() -> down() -> ... ->
++               * hisi_sas_internal_abort_timeout() -> down().
++               */
++              if (!timeout->rst_ha_timeout)
++                      down(&hisi_hba->sem);
+               hisi_hba->hw->debugfs_snapshot_regs(hisi_hba);
+-              up(&hisi_hba->sem);
++              if (!timeout->rst_ha_timeout)
++                      up(&hisi_hba->sem);
+       }
+       if (task->task_state_flags & SAS_TASK_STATE_DONE) {
+-- 
+2.39.5
+
diff --git a/queue-6.6/scsi-mpi3mr-start-controller-indexing-from-0.patch b/queue-6.6/scsi-mpi3mr-start-controller-indexing-from-0.patch
new file mode 100644 (file)
index 0000000..dddd875
--- /dev/null
@@ -0,0 +1,37 @@
+From f9197247180b4dda5db5de21bc2dfec937f8886f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Nov 2024 01:14:03 +0530
+Subject: scsi: mpi3mr: Start controller indexing from 0
+
+From: Ranjan Kumar <ranjan.kumar@broadcom.com>
+
+[ Upstream commit 0d32014f1e3e7a7adf1583c45387f26b9bb3a49d ]
+
+Instead of displaying the controller index starting from '1' make the
+driver display the controller index starting from '0'.
+
+Signed-off-by: Sumit Saxena <sumit.saxena@broadcom.com>
+Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
+Link: https://lore.kernel.org/r/20241110194405.10108-4-ranjan.kumar@broadcom.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/mpi3mr/mpi3mr_os.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
+index 3f86f1d0a9be..7880675a68db 100644
+--- a/drivers/scsi/mpi3mr/mpi3mr_os.c
++++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
+@@ -5066,7 +5066,7 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+       }
+       mrioc = shost_priv(shost);
+-      retval = ida_alloc_range(&mrioc_ida, 1, U8_MAX, GFP_KERNEL);
++      retval = ida_alloc_range(&mrioc_ida, 0, U8_MAX, GFP_KERNEL);
+       if (retval < 0)
+               goto id_alloc_failed;
+       mrioc->id = (u8)retval;
+-- 
+2.39.5
+
diff --git a/queue-6.6/scsi-mpi3mr-use-ida-to-manage-mrioc-id.patch b/queue-6.6/scsi-mpi3mr-use-ida-to-manage-mrioc-id.patch
new file mode 100644 (file)
index 0000000..6780344
--- /dev/null
@@ -0,0 +1,84 @@
+From 15ca434f10e4bed722e849cb5b3245e3c1a62ea4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Dec 2023 12:03:31 +0800
+Subject: scsi: mpi3mr: Use ida to manage mrioc ID
+
+From: Guixin Liu <kanie@linux.alibaba.com>
+
+[ Upstream commit 29b75184f721b16c51ef6e67eec0e40ed88381c7 ]
+
+To ensure that the same ID is not obtained during concurrent execution of
+the probe, an ida is used to manage the mrioc's ID.
+
+Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
+Link: https://lore.kernel.org/r/20231229040331.52518-1-kanie@linux.alibaba.com
+Reviewed-by: Lee Duncan <lduncan@suse.com>
+Reviewed-by: Martin Wilck <mwilck@suse.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Stable-dep-of: 0d32014f1e3e ("scsi: mpi3mr: Start controller indexing from 0")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/mpi3mr/mpi3mr_os.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
+index 7f3261923469..3f86f1d0a9be 100644
+--- a/drivers/scsi/mpi3mr/mpi3mr_os.c
++++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
+@@ -8,11 +8,12 @@
+  */
+ #include "mpi3mr.h"
++#include <linux/idr.h>
+ /* global driver scop variables */
+ LIST_HEAD(mrioc_list);
+ DEFINE_SPINLOCK(mrioc_list_lock);
+-static int mrioc_ids;
++static DEFINE_IDA(mrioc_ida);
+ static int warn_non_secure_ctlr;
+ atomic64_t event_counter;
+@@ -5065,7 +5066,10 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+       }
+       mrioc = shost_priv(shost);
+-      mrioc->id = mrioc_ids++;
++      retval = ida_alloc_range(&mrioc_ida, 1, U8_MAX, GFP_KERNEL);
++      if (retval < 0)
++              goto id_alloc_failed;
++      mrioc->id = (u8)retval;
+       sprintf(mrioc->driver_name, "%s", MPI3MR_DRIVER_NAME);
+       sprintf(mrioc->name, "%s%d", mrioc->driver_name, mrioc->id);
+       INIT_LIST_HEAD(&mrioc->list);
+@@ -5215,9 +5219,11 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ resource_alloc_failed:
+       destroy_workqueue(mrioc->fwevt_worker_thread);
+ fwevtthread_failed:
++      ida_free(&mrioc_ida, mrioc->id);
+       spin_lock(&mrioc_list_lock);
+       list_del(&mrioc->list);
+       spin_unlock(&mrioc_list_lock);
++id_alloc_failed:
+       scsi_host_put(shost);
+ shost_failed:
+       return retval;
+@@ -5303,6 +5309,7 @@ static void mpi3mr_remove(struct pci_dev *pdev)
+               mrioc->sas_hba.num_phys = 0;
+       }
++      ida_free(&mrioc_ida, mrioc->id);
+       spin_lock(&mrioc_list_lock);
+       list_del(&mrioc->list);
+       spin_unlock(&mrioc_list_lock);
+@@ -5518,6 +5525,7 @@ static void __exit mpi3mr_exit(void)
+                          &driver_attr_event_counter);
+       pci_unregister_driver(&mpi3mr_pci_driver);
+       sas_release_transport(mpi3mr_transport_template);
++      ida_destroy(&mrioc_ida);
+ }
+ module_init(mpi3mr_init);
+-- 
+2.39.5
+
diff --git a/queue-6.6/series b/queue-6.6/series
new file mode 100644 (file)
index 0000000..b9df4e3
--- /dev/null
@@ -0,0 +1,113 @@
+drm-amd-display-fix-dsc-re-computing.patch
+drm-amd-display-fix-incorrect-dsc-recompute-trigger.patch
+docs-media-update-location-of-the-media-patches.patch
+x86-mm-carve-out-invlpg-inline-asm-for-use-by-others.patch
+smb-client-rename-cifs_ntsd-to-smb_ntsd.patch
+smb-client-rename-cifs_sid-to-smb_sid.patch
+smb-client-rename-cifs_acl-to-smb_acl.patch
+smb-client-rename-cifs_ace-to-smb_ace.patch
+fs-smb-client-implement-chmod-for-smb3-posix-extensi.patch
+smb-client-stop-flooding-dmesg-in-smb2_calc_signatur.patch
+smb-client-fix-use-after-free-of-signing-key.patch
+usb-dwc3-gadget-add-missing-check-for-single-port-ra.patch
+sched-initialize-idle-tasks-only-once.patch
+drm-radeon-delay-connector-detecting-when-hpd-singal.patch
+revert-drm-radeon-delay-connector-detecting-when-hpd.patch
+rust-relax-most-deny-level-lints-to-warnings.patch
+rust-allow-clippy-needless_lifetimes.patch
+numa-optimize-detection-of-memory-with-no-node-id-as.patch
+memblock-allow-zero-threshold-in-validate_numa_conve.patch
+ext4-convert-to-new-timestamp-accessors.patch
+ext4-partial-zero-eof-block-on-unaligned-inode-size-.patch
+crypto-ecdsa-convert-byte-arrays-with-key-coordinate.patch
+crypto-ecdsa-rename-keylen-to-bufsize-where-necessar.patch
+crypto-ecdsa-use-ecc_digits_from_bytes-to-convert-si.patch
+crypto-ecdsa-avoid-signed-integer-overflow-on-signat.patch
+cleanup-add-conditional-guard-support.patch
+cleanup-adjust-scoped_guard-macros-to-avoid-potentia.patch
+media-uvcvideo-force-uvc-version-to-1.0a-for-0408-40.patch
+media-uvcvideo-force-uvc-version-to-1.0a-for-0408-40.patch-10342
+wifi-mac80211-export-ieee80211_purge_tx_queue-for-dr.patch
+wifi-rtw88-use-ieee80211_purge_tx_queue-to-purge-tx-.patch
+wifi-ath12k-optimize-the-mac80211-hw-data-access.patch
+wifi-mac80211-add-non-atomic-station-iterator.patch
+wifi-ath12k-fix-atomic-calls-in-ath12k_mac_op_set_bi.patch
+wifi-ath10k-update-qualcomm-innovation-center-inc.-c.patch
+wifi-ath10k-avoid-null-pointer-error-during-sdio-rem.patch
+i2c-i801-add-support-for-intel-arrow-lake-h.patch
+i2c-i801-add-support-for-intel-panther-lake.patch
+bluetooth-hci_conn-reduce-hci_conn_drop-calls-in-two.patch
+bluetooth-add-support-ittim-pe50-m75c.patch
+bluetooth-btusb-add-new-vid-pid-13d3-3602-for-mt7925.patch
+bluetooth-btusb-add-usb-hw-ids-for-mt7921-mt7922-mt7.patch
+bluetooth-btusb-add-new-vid-pid-0489-e111-for-mt7925.patch
+scsi-hisi_sas-directly-call-register-snapshot-instea.patch
+scsi-hisi_sas-allocate-dfx-memory-during-dump-trigge.patch
+scsi-hisi_sas-create-all-dump-files-during-debugfs-i.patch
+clk-qcom-clk-alpha-pll-add-support-for-zonda-ole-pll.patch
+clk-qcom-clk-alpha-pll-add-nss-huayra-alpha-pll-supp.patch
+mailbox-pcc-add-support-for-platform-notification-ha.patch
+mailbox-pcc-support-shared-interrupt-for-multiple-su.patch
+acpi-pcc-add-pcc-shared-memory-region-command-and-st.patch
+mailbox-pcc-check-before-sending-mctp-pcc-response-a.patch
+remoteproc-qcom-pas-add-sc7180-adsp.patch
+remoteproc-qcom-pas-add-support-for-sa8775p-adsp-cds.patch
+remoteproc-qcom-pas-enable-sar2130p-audio-dsp-suppor.patch
+fs-ntfs3-implement-fallocate-for-compressed-files.patch
+fs-ntfs3-fix-warning-in-ni_fiemap.patch
+usb-chipidea-add-ci_hdrc_force_vbus_active_always-fl.patch
+usb-chipidea-add-ci_hdrc_has_short_pkt_limit-flag.patch
+usb-chipidea-udc-limit-usb-request-length-to-max-16k.patch
+iio-adc-ad7192-convert-from-of-specific-to-fwnode-pr.patch
+iio-adc-ad7192-properly-check-spi_get_device_match_d.patch
+usb-typec-ucsi-add-callback-for-connector-status-upd.patch
+usb-typec-ucsi-glink-move-gpio-reading-into-connecto.patch
+usb-typec-ucsi-add-update_connector-callback.patch
+usb-typec-ucsi-glink-set-orientation-aware-if-suppor.patch
+usb-typec-ucsi-glink-be-more-precise-on-orientation-.patch
+nvme-use-helper-nvme_ctrl_state-in-nvme_keep_alive_f.patch
+revert-nvme-make-keep-alive-synchronous-operation.patch
+net-mlx5-unique-names-for-per-device-caches.patch
+softirq-allow-raising-sched_softirq-from-smp-call-fu.patch
+net-renesas-rswitch-fix-possible-early-skb-release.patch
+xhci-retry-stop-endpoint-on-buggy-nec-controllers.patch
+usb-xhci-limit-stop-endpoint-retries.patch
+xhci-turn-nec-specific-quirk-for-handling-stop-endpo.patch
+thunderbolt-add-support-for-intel-lunar-lake.patch
+thunderbolt-add-support-for-intel-panther-lake-m-p.patch
+thunderbolt-don-t-display-nvm_version-unless-upgrade.patch
+x86-crash-wrap-crash-dumping-code-into-crash-related.patch
+x86-hyperv-fix-hv-tsc-page-based-sched_clock-for-hib.patch
+of-address-remove-duplicated-functions.patch
+of-address-store-number-of-bus-flag-cells-rather-tha.patch
+of-address-preserve-the-flags-portion-on-1-1-dma-ran.patch
+watchdog-rzg2l_wdt-remove-reset-de-assert-from-probe.patch
+watchdog-rzg2l_wdt-rely-on-the-reset-driver-for-doin.patch
+watchdog-rzg2l_wdt-power-on-the-watchdog-domain-in-t.patch
+watchdog-s3c2410_wdt-use-exynos_get_pmu_regmap_by_ph.patch
+revert-watchdog-s3c2410_wdt-use-exynos_get_pmu_regma.patch
+udf_rename-only-access-the-child-content-on-cross-di.patch
+udf-verify-inode-link-counts-before-performing-renam.patch
+alsa-ump-use-guard-for-locking.patch
+alsa-ump-don-t-open-legacy-substream-for-an-inactive.patch
+alsa-ump-indicate-the-inactive-group-in-legacy-subst.patch
+alsa-ump-update-legacy-substream-names-upon-fb-info-.patch
+scsi-mpi3mr-use-ida-to-manage-mrioc-id.patch
+scsi-mpi3mr-start-controller-indexing-from-0.patch
+acpi-iort-add-pmcg-platform-information-for-hisilico.patch
+acpi-iort-add-pmcg-platform-information-for-hisilico.patch-10390
+x86-ptrace-cleanup-the-definition-of-the-pt_regs-str.patch
+x86-ptrace-add-fred-additional-information-to-the-pt.patch
+x86-fred-clear-wfe-in-missing-endbranch-cps.patch
+btrfs-rename-and-export-__btrfs_cow_block.patch
+btrfs-fix-use-after-free-when-cowing-tree-bock-and-t.patch
+bluetooth-btusb-add-callback-function-in-btusb-suspe.patch
+bluetooth-btusb-mediatek-add-callback-function-in-bt.patch
+memblock-make-memblock_set_node-also-warn-about-use-.patch
+crypto-ecc-prevent-ecc_digits_from_bytes-from-readin.patch
+cleanup-remove-address-space-of-returned-pointer.patch
+scsi-hisi_sas-fix-a-deadlock-issue-related-to-automa.patch
+usb-typec-ucsi-glink-fix-off-by-one-in-connector_sta.patch
+usb-xhci-avoid-queuing-redundant-stop-endpoint-comma.patch
+alsa-ump-shut-up-truncated-string-warning.patch
+platform-x86-mlx-platform-call-pci_dev_put-to-balanc.patch
diff --git a/queue-6.6/smb-client-fix-use-after-free-of-signing-key.patch b/queue-6.6/smb-client-fix-use-after-free-of-signing-key.patch
new file mode 100644 (file)
index 0000000..6155715
--- /dev/null
@@ -0,0 +1,165 @@
+From 2237cd152a146d8945e696c0246efe5a0aaa646c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Nov 2024 10:40:55 -0300
+Subject: smb: client: fix use-after-free of signing key
+
+From: Paulo Alcantara <pc@manguebit.com>
+
+[ Upstream commit 343d7fe6df9e247671440a932b6a73af4fa86d95 ]
+
+Customers have reported use-after-free in @ses->auth_key.response with
+SMB2.1 + sign mounts which occurs due to following race:
+
+task A                         task B
+cifs_mount()
+ dfs_mount_share()
+  get_session()
+   cifs_mount_get_session()    cifs_send_recv()
+    cifs_get_smb_ses()          compound_send_recv()
+     cifs_setup_session()        smb2_setup_request()
+      kfree_sensitive()           smb2_calc_signature()
+                                   crypto_shash_setkey() *UAF*
+
+Fix this by ensuring that we have a valid @ses->auth_key.response by
+checking whether @ses->ses_status is SES_GOOD or SES_EXITING with
+@ses->ses_lock held.  After commit 24a9799aa8ef ("smb: client: fix UAF
+in smb2_reconnect_server()"), we made sure to call ->logoff() only
+when @ses was known to be good (e.g. valid ->auth_key.response), so
+it's safe to access signing key when @ses->ses_status == SES_EXITING.
+
+Cc: stable@vger.kernel.org
+Reported-by: Jay Shin <jaeshin@redhat.com>
+Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/smb2proto.h     |  2 --
+ fs/smb/client/smb2transport.c | 56 +++++++++++++++++++++++++----------
+ 2 files changed, 40 insertions(+), 18 deletions(-)
+
+diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h
+index fd90d8e5a1d1..750e4e397b13 100644
+--- a/fs/smb/client/smb2proto.h
++++ b/fs/smb/client/smb2proto.h
+@@ -37,8 +37,6 @@ extern struct mid_q_entry *smb2_setup_request(struct cifs_ses *ses,
+                                             struct smb_rqst *rqst);
+ extern struct mid_q_entry *smb2_setup_async_request(
+                       struct TCP_Server_Info *server, struct smb_rqst *rqst);
+-extern struct cifs_ses *smb2_find_smb_ses(struct TCP_Server_Info *server,
+-                                         __u64 ses_id);
+ extern struct cifs_tcon *smb2_find_smb_tcon(struct TCP_Server_Info *server,
+                                               __u64 ses_id, __u32  tid);
+ extern int smb2_calc_signature(struct smb_rqst *rqst,
+diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c
+index 73eae1b16034..4a43802375b3 100644
+--- a/fs/smb/client/smb2transport.c
++++ b/fs/smb/client/smb2transport.c
+@@ -74,7 +74,7 @@ smb311_crypto_shash_allocate(struct TCP_Server_Info *server)
+ static
+-int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key)
++int smb3_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key)
+ {
+       struct cifs_chan *chan;
+       struct TCP_Server_Info *pserver;
+@@ -168,16 +168,41 @@ smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id)
+       return NULL;
+ }
+-struct cifs_ses *
+-smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id)
++static int smb2_get_sign_key(struct TCP_Server_Info *server,
++                           __u64 ses_id, u8 *key)
+ {
+       struct cifs_ses *ses;
++      int rc = -ENOENT;
++
++      if (SERVER_IS_CHAN(server))
++              server = server->primary_server;
+       spin_lock(&cifs_tcp_ses_lock);
+-      ses = smb2_find_smb_ses_unlocked(server, ses_id);
+-      spin_unlock(&cifs_tcp_ses_lock);
++      list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
++              if (ses->Suid != ses_id)
++                      continue;
+-      return ses;
++              rc = 0;
++              spin_lock(&ses->ses_lock);
++              switch (ses->ses_status) {
++              case SES_EXITING: /* SMB2_LOGOFF */
++              case SES_GOOD:
++                      if (likely(ses->auth_key.response)) {
++                              memcpy(key, ses->auth_key.response,
++                                     SMB2_NTLMV2_SESSKEY_SIZE);
++                      } else {
++                              rc = -EIO;
++                      }
++                      break;
++              default:
++                      rc = -EAGAIN;
++                      break;
++              }
++              spin_unlock(&ses->ses_lock);
++              break;
++      }
++      spin_unlock(&cifs_tcp_ses_lock);
++      return rc;
+ }
+ static struct cifs_tcon *
+@@ -236,14 +261,16 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
+       unsigned char *sigptr = smb2_signature;
+       struct kvec *iov = rqst->rq_iov;
+       struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base;
+-      struct cifs_ses *ses;
+       struct shash_desc *shash = NULL;
+       struct smb_rqst drqst;
++      __u64 sid = le64_to_cpu(shdr->SessionId);
++      u8 key[SMB2_NTLMV2_SESSKEY_SIZE];
+-      ses = smb2_find_smb_ses(server, le64_to_cpu(shdr->SessionId));
+-      if (unlikely(!ses)) {
+-              cifs_server_dbg(FYI, "%s: Could not find session\n", __func__);
+-              return -ENOENT;
++      rc = smb2_get_sign_key(server, sid, key);
++      if (unlikely(rc)) {
++              cifs_server_dbg(FYI, "%s: [sesid=0x%llx] couldn't find signing key: %d\n",
++                              __func__, sid, rc);
++              return rc;
+       }
+       memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
+@@ -260,8 +287,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
+               shash = server->secmech.hmacsha256;
+       }
+-      rc = crypto_shash_setkey(shash->tfm, ses->auth_key.response,
+-                      SMB2_NTLMV2_SESSKEY_SIZE);
++      rc = crypto_shash_setkey(shash->tfm, key, sizeof(key));
+       if (rc) {
+               cifs_server_dbg(VFS,
+                               "%s: Could not update with response\n",
+@@ -303,8 +329,6 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
+ out:
+       if (allocate_crypto)
+               cifs_free_hash(&shash);
+-      if (ses)
+-              cifs_put_smb_ses(ses);
+       return rc;
+ }
+@@ -570,7 +594,7 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
+       struct smb_rqst drqst;
+       u8 key[SMB3_SIGN_KEY_SIZE];
+-      rc = smb2_get_sign_key(le64_to_cpu(shdr->SessionId), server, key);
++      rc = smb3_get_sign_key(le64_to_cpu(shdr->SessionId), server, key);
+       if (unlikely(rc)) {
+               cifs_server_dbg(FYI, "%s: Could not get signing key\n", __func__);
+               return rc;
+-- 
+2.39.5
+
diff --git a/queue-6.6/smb-client-rename-cifs_ace-to-smb_ace.patch b/queue-6.6/smb-client-rename-cifs_ace-to-smb_ace.patch
new file mode 100644 (file)
index 0000000..303cc51
--- /dev/null
@@ -0,0 +1,362 @@
+From 5f856fdc5d8214ca2defc219f8f4f1b80db352c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Aug 2024 08:20:58 +0000
+Subject: smb/client: rename cifs_ace to smb_ace
+
+From: ChenXiaoSong <chenxiaosong@kylinos.cn>
+
+[ Upstream commit 09bedafc1e2c5c82aad3cbfe1359e2b0bf752f3a ]
+
+Preparation for moving acl definitions to new common header file.
+
+Use the following shell command to rename:
+
+  find fs/smb/client -type f -exec sed -i \
+    's/struct cifs_ace/struct smb_ace/g' {} +
+
+Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
+Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: d413eabff18d ("fs/smb/client: implement chmod() for SMB3 POSIX Extensions")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/cifsacl.c   | 62 +++++++++++++++++++--------------------
+ fs/smb/client/cifsacl.h   |  4 +--
+ fs/smb/client/cifsglob.h  |  2 +-
+ fs/smb/client/cifsproto.h |  6 ++--
+ fs/smb/client/smb2pdu.c   |  8 ++---
+ 5 files changed, 41 insertions(+), 41 deletions(-)
+
+diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c
+index 2e1c9b528dde..e2ec1d934335 100644
+--- a/fs/smb/client/cifsacl.c
++++ b/fs/smb/client/cifsacl.c
+@@ -666,7 +666,7 @@ static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
+       return;
+ }
+-static __u16 cifs_copy_ace(struct cifs_ace *dst, struct cifs_ace *src, struct smb_sid *psid)
++static __u16 cifs_copy_ace(struct smb_ace *dst, struct smb_ace *src, struct smb_sid *psid)
+ {
+       __u16 size = 1 + 1 + 2 + 4;
+@@ -685,7 +685,7 @@ static __u16 cifs_copy_ace(struct cifs_ace *dst, struct cifs_ace *src, struct sm
+       return size;
+ }
+-static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
++static __u16 fill_ace_for_sid(struct smb_ace *pntace,
+                       const struct smb_sid *psid, __u64 nmode,
+                       umode_t bits, __u8 access_type,
+                       bool allow_delete_child)
+@@ -723,7 +723,7 @@ static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
+ #ifdef CONFIG_CIFS_DEBUG2
+-static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
++static void dump_ace(struct smb_ace *pace, char *end_of_acl)
+ {
+       int num_subauth;
+@@ -766,7 +766,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
+       int num_aces = 0;
+       int acl_size;
+       char *acl_base;
+-      struct cifs_ace **ppace;
++      struct smb_ace **ppace;
+       /* BB need to add parm so we can store the SID BB */
+@@ -799,15 +799,15 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
+       if (num_aces > 0) {
+               umode_t denied_mode = 0;
+-              if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
++              if (num_aces > ULONG_MAX / sizeof(struct smb_ace *))
+                       return;
+-              ppace = kmalloc_array(num_aces, sizeof(struct cifs_ace *),
++              ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *),
+                                     GFP_KERNEL);
+               if (!ppace)
+                       return;
+               for (i = 0; i < num_aces; ++i) {
+-                      ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
++                      ppace[i] = (struct smb_ace *) (acl_base + acl_size);
+ #ifdef CONFIG_CIFS_DEBUG2
+                       dump_ace(ppace[i], end_of_acl);
+ #endif
+@@ -849,7 +849,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
+ /*                    memcpy((void *)(&(cifscred->aces[i])),
+                               (void *)ppace[i],
+-                              sizeof(struct cifs_ace)); */
++                              sizeof(struct smb_ace)); */
+                       acl_base = (char *)ppace[i];
+                       acl_size = le16_to_cpu(ppace[i]->size);
+@@ -861,7 +861,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
+       return;
+ }
+-unsigned int setup_authusers_ACE(struct cifs_ace *pntace)
++unsigned int setup_authusers_ACE(struct smb_ace *pntace)
+ {
+       int i;
+       unsigned int ace_size = 20;
+@@ -885,7 +885,7 @@ unsigned int setup_authusers_ACE(struct cifs_ace *pntace)
+  * Fill in the special SID based on the mode. See
+  * https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
+  */
+-unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode)
++unsigned int setup_special_mode_ACE(struct smb_ace *pntace, __u64 nmode)
+ {
+       int i;
+       unsigned int ace_size = 28;
+@@ -907,7 +907,7 @@ unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode)
+       return ace_size;
+ }
+-unsigned int setup_special_user_owner_ACE(struct cifs_ace *pntace)
++unsigned int setup_special_user_owner_ACE(struct smb_ace *pntace)
+ {
+       int i;
+       unsigned int ace_size = 28;
+@@ -944,17 +944,17 @@ static void populate_new_aces(char *nacl_base,
+       __u64 deny_user_mode = 0;
+       __u64 deny_group_mode = 0;
+       bool sticky_set = false;
+-      struct cifs_ace *pnntace = NULL;
++      struct smb_ace *pnntace = NULL;
+       nmode = *pnmode;
+       num_aces = *pnum_aces;
+       nsize = *pnsize;
+       if (modefromsid) {
+-              pnntace = (struct cifs_ace *) (nacl_base + nsize);
++              pnntace = (struct smb_ace *) (nacl_base + nsize);
+               nsize += setup_special_mode_ACE(pnntace, nmode);
+               num_aces++;
+-              pnntace = (struct cifs_ace *) (nacl_base + nsize);
++              pnntace = (struct smb_ace *) (nacl_base + nsize);
+               nsize += setup_authusers_ACE(pnntace);
+               num_aces++;
+               goto set_size;
+@@ -992,7 +992,7 @@ static void populate_new_aces(char *nacl_base,
+               sticky_set = true;
+       if (deny_user_mode) {
+-              pnntace = (struct cifs_ace *) (nacl_base + nsize);
++              pnntace = (struct smb_ace *) (nacl_base + nsize);
+               nsize += fill_ace_for_sid(pnntace, pownersid, deny_user_mode,
+                               0700, ACCESS_DENIED, false);
+               num_aces++;
+@@ -1000,31 +1000,31 @@ static void populate_new_aces(char *nacl_base,
+       /* Group DENY ACE does not conflict with owner ALLOW ACE. Keep in preferred order*/
+       if (deny_group_mode && !(deny_group_mode & (user_mode >> 3))) {
+-              pnntace = (struct cifs_ace *) (nacl_base + nsize);
++              pnntace = (struct smb_ace *) (nacl_base + nsize);
+               nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
+                               0070, ACCESS_DENIED, false);
+               num_aces++;
+       }
+-      pnntace = (struct cifs_ace *) (nacl_base + nsize);
++      pnntace = (struct smb_ace *) (nacl_base + nsize);
+       nsize += fill_ace_for_sid(pnntace, pownersid, user_mode,
+                       0700, ACCESS_ALLOWED, true);
+       num_aces++;
+       /* Group DENY ACE conflicts with owner ALLOW ACE. So keep it after. */
+       if (deny_group_mode && (deny_group_mode & (user_mode >> 3))) {
+-              pnntace = (struct cifs_ace *) (nacl_base + nsize);
++              pnntace = (struct smb_ace *) (nacl_base + nsize);
+               nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
+                               0070, ACCESS_DENIED, false);
+               num_aces++;
+       }
+-      pnntace = (struct cifs_ace *) (nacl_base + nsize);
++      pnntace = (struct smb_ace *) (nacl_base + nsize);
+       nsize += fill_ace_for_sid(pnntace, pgrpsid, group_mode,
+                       0070, ACCESS_ALLOWED, !sticky_set);
+       num_aces++;
+-      pnntace = (struct cifs_ace *) (nacl_base + nsize);
++      pnntace = (struct smb_ace *) (nacl_base + nsize);
+       nsize += fill_ace_for_sid(pnntace, &sid_everyone, other_mode,
+                       0007, ACCESS_ALLOWED, !sticky_set);
+       num_aces++;
+@@ -1040,11 +1040,11 @@ static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *p
+ {
+       int i;
+       u16 size = 0;
+-      struct cifs_ace *pntace = NULL;
++      struct smb_ace *pntace = NULL;
+       char *acl_base = NULL;
+       u32 src_num_aces = 0;
+       u16 nsize = 0;
+-      struct cifs_ace *pnntace = NULL;
++      struct smb_ace *pnntace = NULL;
+       char *nacl_base = NULL;
+       u16 ace_size = 0;
+@@ -1057,8 +1057,8 @@ static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *p
+       /* Go through all the ACEs */
+       for (i = 0; i < src_num_aces; ++i) {
+-              pntace = (struct cifs_ace *) (acl_base + size);
+-              pnntace = (struct cifs_ace *) (nacl_base + nsize);
++              pntace = (struct smb_ace *) (acl_base + size);
++              pnntace = (struct smb_ace *) (nacl_base + nsize);
+               if (pnownersid && compare_sids(&pntace->sid, pownersid) == 0)
+                       ace_size = cifs_copy_ace(pnntace, pntace, pnownersid);
+@@ -1080,11 +1080,11 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
+ {
+       int i;
+       u16 size = 0;
+-      struct cifs_ace *pntace = NULL;
++      struct smb_ace *pntace = NULL;
+       char *acl_base = NULL;
+       u32 src_num_aces = 0;
+       u16 nsize = 0;
+-      struct cifs_ace *pnntace = NULL;
++      struct smb_ace *pnntace = NULL;
+       char *nacl_base = NULL;
+       u32 num_aces = 0;
+       bool new_aces_set = false;
+@@ -1108,7 +1108,7 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
+       /* Retain old ACEs which we can retain */
+       for (i = 0; i < src_num_aces; ++i) {
+-              pntace = (struct cifs_ace *) (acl_base + size);
++              pntace = (struct smb_ace *) (acl_base + size);
+               if (!new_aces_set && (pntace->flags & INHERITED_ACE)) {
+                       /* Place the new ACEs in between existing explicit and inherited */
+@@ -1130,7 +1130,7 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
+               }
+               /* update the pointer to the next ACE to populate*/
+-              pnntace = (struct cifs_ace *) (nacl_base + nsize);
++              pnntace = (struct smb_ace *) (nacl_base + nsize);
+               nsize += cifs_copy_ace(pnntace, pntace, NULL);
+               num_aces++;
+@@ -1625,9 +1625,9 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
+       nsecdesclen = secdesclen;
+       if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
+               if (mode_from_sid)
+-                      nsecdesclen += 2 * sizeof(struct cifs_ace);
++                      nsecdesclen += 2 * sizeof(struct smb_ace);
+               else /* cifsacl */
+-                      nsecdesclen += 5 * sizeof(struct cifs_ace);
++                      nsecdesclen += 5 * sizeof(struct smb_ace);
+       } else { /* chown */
+               /* When ownership changes, changes new owner sid length could be different */
+               nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct smb_sid) * 2);
+@@ -1636,7 +1636,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
+                       dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
+                       if (mode_from_sid)
+                               nsecdesclen +=
+-                                      le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct cifs_ace);
++                                      le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace);
+                       else /* cifsacl */
+                               nsecdesclen += le16_to_cpu(dacl_ptr->size);
+               }
+diff --git a/fs/smb/client/cifsacl.h b/fs/smb/client/cifsacl.h
+index a23d59987828..cbaed8038e36 100644
+--- a/fs/smb/client/cifsacl.h
++++ b/fs/smb/client/cifsacl.h
+@@ -35,7 +35,7 @@
+  */
+ #define DEFAULT_SEC_DESC_LEN (sizeof(struct smb_ntsd) + \
+                             sizeof(struct smb_acl) + \
+-                            (sizeof(struct cifs_ace) * 4))
++                            (sizeof(struct smb_ace) * 4))
+ /*
+  * Maximum size of a string representation of a SID:
+@@ -111,7 +111,7 @@ struct smb_acl {
+ #define SUCCESSFUL_ACCESS_ACE_FLAG 0x40
+ #define FAILED_ACCESS_ACE_FLAG        0x80
+-struct cifs_ace {
++struct smb_ace {
+       __u8 type; /* see above and MS-DTYP 2.4.4.1 */
+       __u8 flags;
+       __le16 size;
+diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
+index 69d850b6b37f..43b42eca6780 100644
+--- a/fs/smb/client/cifsglob.h
++++ b/fs/smb/client/cifsglob.h
+@@ -205,7 +205,7 @@ struct cifs_cred {
+       struct smb_sid osid;
+       struct smb_sid gsid;
+       struct cifs_ntace *ntaces;
+-      struct cifs_ace *aces;
++      struct smb_ace *aces;
+ };
+ struct cifs_open_info_data {
+diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
+index 059e506ccf5b..6399dbd04625 100644
+--- a/fs/smb/client/cifsproto.h
++++ b/fs/smb/client/cifsproto.h
+@@ -241,9 +241,9 @@ extern int cifs_set_acl(struct mnt_idmap *idmap,
+                       struct dentry *dentry, struct posix_acl *acl, int type);
+ extern int set_cifs_acl(struct smb_ntsd *pntsd, __u32 len, struct inode *ino,
+                               const char *path, int flag);
+-extern unsigned int setup_authusers_ACE(struct cifs_ace *pace);
+-extern unsigned int setup_special_mode_ACE(struct cifs_ace *pace, __u64 nmode);
+-extern unsigned int setup_special_user_owner_ACE(struct cifs_ace *pace);
++extern unsigned int setup_authusers_ACE(struct smb_ace *pace);
++extern unsigned int setup_special_mode_ACE(struct smb_ace *pace, __u64 nmode);
++extern unsigned int setup_special_user_owner_ACE(struct smb_ace *pace);
+ extern void dequeue_mid(struct mid_q_entry *mid, bool malformed);
+ extern int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
+diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
+index 42f950ae10fb..101c80f22d77 100644
+--- a/fs/smb/client/smb2pdu.c
++++ b/fs/smb/client/smb2pdu.c
+@@ -2623,7 +2623,7 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len)
+       unsigned int group_offset = 0;
+       struct smb3_acl acl = {};
+-      *len = round_up(sizeof(struct crt_sd_ctxt) + (sizeof(struct cifs_ace) * 4), 8);
++      *len = round_up(sizeof(struct crt_sd_ctxt) + (sizeof(struct smb_ace) * 4), 8);
+       if (set_owner) {
+               /* sizeof(struct owner_group_sids) is already multiple of 8 so no need to round */
+@@ -2672,21 +2672,21 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len)
+       ptr += sizeof(struct smb3_acl);
+       /* create one ACE to hold the mode embedded in reserved special SID */
+-      acelen = setup_special_mode_ACE((struct cifs_ace *)ptr, (__u64)mode);
++      acelen = setup_special_mode_ACE((struct smb_ace *)ptr, (__u64)mode);
+       ptr += acelen;
+       acl_size = acelen + sizeof(struct smb3_acl);
+       ace_count = 1;
+       if (set_owner) {
+               /* we do not need to reallocate buffer to add the two more ACEs. plenty of space */
+-              acelen = setup_special_user_owner_ACE((struct cifs_ace *)ptr);
++              acelen = setup_special_user_owner_ACE((struct smb_ace *)ptr);
+               ptr += acelen;
+               acl_size += acelen;
+               ace_count += 1;
+       }
+       /* and one more ACE to allow access for authenticated users */
+-      acelen = setup_authusers_ACE((struct cifs_ace *)ptr);
++      acelen = setup_authusers_ACE((struct smb_ace *)ptr);
+       ptr += acelen;
+       acl_size += acelen;
+       ace_count += 1;
+-- 
+2.39.5
+
diff --git a/queue-6.6/smb-client-rename-cifs_acl-to-smb_acl.patch b/queue-6.6/smb-client-rename-cifs_acl-to-smb_acl.patch
new file mode 100644 (file)
index 0000000..f2323c1
--- /dev/null
@@ -0,0 +1,195 @@
+From ae8d47f6ff4a57650599089653687582f98ce584 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Aug 2024 08:20:57 +0000
+Subject: smb/client: rename cifs_acl to smb_acl
+
+From: ChenXiaoSong <chenxiaosong@kylinos.cn>
+
+[ Upstream commit 251b93ae73805b216e84ed2190b525f319da4c87 ]
+
+Preparation for moving acl definitions to new common header file.
+
+Use the following shell command to rename:
+
+  find fs/smb/client -type f -exec sed -i \
+    's/struct cifs_acl/struct smb_acl/g' {} +
+
+Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
+Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: d413eabff18d ("fs/smb/client: implement chmod() for SMB3 POSIX Extensions")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/cifsacl.c | 34 +++++++++++++++++-----------------
+ fs/smb/client/cifsacl.h |  4 ++--
+ 2 files changed, 19 insertions(+), 19 deletions(-)
+
+diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c
+index dd399f9a7424..2e1c9b528dde 100644
+--- a/fs/smb/client/cifsacl.c
++++ b/fs/smb/client/cifsacl.c
+@@ -758,7 +758,7 @@ static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
+ }
+ #endif
+-static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
++static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
+                      struct smb_sid *pownersid, struct smb_sid *pgrpsid,
+                      struct cifs_fattr *fattr, bool mode_from_special_sid)
+ {
+@@ -793,7 +793,7 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
+       fattr->cf_mode &= ~(0777);
+       acl_base = (char *)pdacl;
+-      acl_size = sizeof(struct cifs_acl);
++      acl_size = sizeof(struct smb_acl);
+       num_aces = le32_to_cpu(pdacl->num_aces);
+       if (num_aces > 0) {
+@@ -1034,7 +1034,7 @@ static void populate_new_aces(char *nacl_base,
+       *pnsize = nsize;
+ }
+-static __u16 replace_sids_and_copy_aces(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
++static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *pndacl,
+               struct smb_sid *pownersid, struct smb_sid *pgrpsid,
+               struct smb_sid *pnownersid, struct smb_sid *pngrpsid)
+ {
+@@ -1049,11 +1049,11 @@ static __u16 replace_sids_and_copy_aces(struct cifs_acl *pdacl, struct cifs_acl
+       u16 ace_size = 0;
+       acl_base = (char *)pdacl;
+-      size = sizeof(struct cifs_acl);
++      size = sizeof(struct smb_acl);
+       src_num_aces = le32_to_cpu(pdacl->num_aces);
+       nacl_base = (char *)pndacl;
+-      nsize = sizeof(struct cifs_acl);
++      nsize = sizeof(struct smb_acl);
+       /* Go through all the ACEs */
+       for (i = 0; i < src_num_aces; ++i) {
+@@ -1074,7 +1074,7 @@ static __u16 replace_sids_and_copy_aces(struct cifs_acl *pdacl, struct cifs_acl
+       return nsize;
+ }
+-static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
++static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
+               struct smb_sid *pownersid,      struct smb_sid *pgrpsid,
+               __u64 *pnmode, bool mode_from_sid)
+ {
+@@ -1091,7 +1091,7 @@ static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
+       /* Assuming that pndacl and pnmode are never NULL */
+       nacl_base = (char *)pndacl;
+-      nsize = sizeof(struct cifs_acl);
++      nsize = sizeof(struct smb_acl);
+       /* If pdacl is NULL, we don't have a src. Simply populate new ACL. */
+       if (!pdacl) {
+@@ -1103,7 +1103,7 @@ static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
+       }
+       acl_base = (char *)pdacl;
+-      size = sizeof(struct cifs_acl);
++      size = sizeof(struct smb_acl);
+       src_num_aces = le32_to_cpu(pdacl->num_aces);
+       /* Retain old ACEs which we can retain */
+@@ -1196,7 +1196,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
+ {
+       int rc = 0;
+       struct smb_sid *owner_sid_ptr, *group_sid_ptr;
+-      struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
++      struct smb_acl *dacl_ptr; /* no need for SACL ptr */
+       char *end_of_acl = ((char *)pntsd) + acl_len;
+       __u32 dacloffset;
+@@ -1208,7 +1208,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
+       group_sid_ptr = (struct smb_sid *)((char *)pntsd +
+                               le32_to_cpu(pntsd->gsidoffset));
+       dacloffset = le32_to_cpu(pntsd->dacloffset);
+-      dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
++      dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
+       cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
+                pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
+                le32_to_cpu(pntsd->gsidoffset),
+@@ -1259,14 +1259,14 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
+       __u32 sidsoffset;
+       struct smb_sid *owner_sid_ptr, *group_sid_ptr;
+       struct smb_sid *nowner_sid_ptr = NULL, *ngroup_sid_ptr = NULL;
+-      struct cifs_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
+-      struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
++      struct smb_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
++      struct smb_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
+       char *end_of_acl = ((char *)pntsd) + secdesclen;
+       u16 size = 0;
+       dacloffset = le32_to_cpu(pntsd->dacloffset);
+       if (dacloffset) {
+-              dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
++              dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
+               if (end_of_acl < (char *)dacl_ptr + le16_to_cpu(dacl_ptr->size)) {
+                       cifs_dbg(VFS, "Server returned illegal ACL size\n");
+                       return -EINVAL;
+@@ -1280,7 +1280,7 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
+       if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
+               ndacloffset = sizeof(struct smb_ntsd);
+-              ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
++              ndacl_ptr = (struct smb_acl *)((char *)pnntsd + ndacloffset);
+               ndacl_ptr->revision =
+                       dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
+@@ -1298,7 +1298,7 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
+               *aclflag |= CIFS_ACL_DACL;
+       } else {
+               ndacloffset = sizeof(struct smb_ntsd);
+-              ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
++              ndacl_ptr = (struct smb_acl *)((char *)pnntsd + ndacloffset);
+               ndacl_ptr->revision =
+                       dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
+               ndacl_ptr->num_aces = dacl_ptr ? dacl_ptr->num_aces : 0;
+@@ -1580,7 +1580,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
+       __u32 secdesclen = 0;
+       __u32 nsecdesclen = 0;
+       __u32 dacloffset = 0;
+-      struct cifs_acl *dacl_ptr = NULL;
++      struct smb_acl *dacl_ptr = NULL;
+       struct smb_ntsd *pntsd = NULL; /* acl obtained from server */
+       struct smb_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
+       struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+@@ -1633,7 +1633,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
+               nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct smb_sid) * 2);
+               dacloffset = le32_to_cpu(pntsd->dacloffset);
+               if (dacloffset) {
+-                      dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
++                      dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
+                       if (mode_from_sid)
+                               nsecdesclen +=
+                                       le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct cifs_ace);
+diff --git a/fs/smb/client/cifsacl.h b/fs/smb/client/cifsacl.h
+index 6a38718220fc..a23d59987828 100644
+--- a/fs/smb/client/cifsacl.h
++++ b/fs/smb/client/cifsacl.h
+@@ -34,7 +34,7 @@
+  * owner, group and world).
+  */
+ #define DEFAULT_SEC_DESC_LEN (sizeof(struct smb_ntsd) + \
+-                            sizeof(struct cifs_acl) + \
++                            sizeof(struct smb_acl) + \
+                             (sizeof(struct cifs_ace) * 4))
+ /*
+@@ -74,7 +74,7 @@ struct smb_sid {
+ /* size of a struct smb_sid, sans sub_auth array */
+ #define CIFS_SID_BASE_SIZE (1 + 1 + NUM_AUTHS)
+-struct cifs_acl {
++struct smb_acl {
+       __le16 revision; /* revision level */
+       __le16 size;
+       __le32 num_aces;
+-- 
+2.39.5
+
diff --git a/queue-6.6/smb-client-rename-cifs_ntsd-to-smb_ntsd.patch b/queue-6.6/smb-client-rename-cifs_ntsd-to-smb_ntsd.patch
new file mode 100644 (file)
index 0000000..c5dbd37
--- /dev/null
@@ -0,0 +1,402 @@
+From 1f20539d1950f49230c561f4b4a82ced00410ee8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Aug 2024 08:20:55 +0000
+Subject: smb/client: rename cifs_ntsd to smb_ntsd
+
+From: ChenXiaoSong <chenxiaosong@kylinos.cn>
+
+[ Upstream commit 3651487607ae778df1051a0a38bb34a5bd34e3b7 ]
+
+Preparation for moving acl definitions to new common header file.
+
+Use the following shell command to rename:
+
+  find fs/smb/client -type f -exec sed -i \
+    's/struct cifs_ntsd/struct smb_ntsd/g' {} +
+
+Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
+Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: d413eabff18d ("fs/smb/client: implement chmod() for SMB3 POSIX Extensions")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/cifsacl.c   | 36 ++++++++++++++++++------------------
+ fs/smb/client/cifsacl.h   |  6 +++---
+ fs/smb/client/cifsglob.h  | 12 ++++++------
+ fs/smb/client/cifsproto.h | 16 ++++++++--------
+ fs/smb/client/cifssmb.c   |  6 +++---
+ fs/smb/client/smb2ops.c   | 14 +++++++-------
+ fs/smb/client/smb2pdu.c   |  2 +-
+ fs/smb/client/smb2proto.h |  2 +-
+ fs/smb/client/xattr.c     |  4 ++--
+ 9 files changed, 49 insertions(+), 49 deletions(-)
+
+diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c
+index f5b6df82e857..3f7657475cd9 100644
+--- a/fs/smb/client/cifsacl.c
++++ b/fs/smb/client/cifsacl.c
+@@ -515,8 +515,8 @@ exit_cifs_idmap(void)
+ }
+ /* copy ntsd, owner sid, and group sid from a security descriptor to another */
+-static __u32 copy_sec_desc(const struct cifs_ntsd *pntsd,
+-                              struct cifs_ntsd *pnntsd,
++static __u32 copy_sec_desc(const struct smb_ntsd *pntsd,
++                              struct smb_ntsd *pnntsd,
+                               __u32 sidsoffset,
+                               struct cifs_sid *pownersid,
+                               struct cifs_sid *pgrpsid)
+@@ -527,7 +527,7 @@ static __u32 copy_sec_desc(const struct cifs_ntsd *pntsd,
+       /* copy security descriptor control portion */
+       pnntsd->revision = pntsd->revision;
+       pnntsd->type = pntsd->type;
+-      pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
++      pnntsd->dacloffset = cpu_to_le32(sizeof(struct smb_ntsd));
+       pnntsd->sacloffset = 0;
+       pnntsd->osidoffset = cpu_to_le32(sidsoffset);
+       pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
+@@ -1191,7 +1191,7 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
+ /* Convert CIFS ACL to POSIX form */
+ static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
+-              struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
++              struct smb_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
+               bool get_mode_from_special_sid)
+ {
+       int rc = 0;
+@@ -1249,7 +1249,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
+ }
+ /* Convert permission bits from mode to equivalent CIFS ACL */
+-static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
++static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
+       __u32 secdesclen, __u32 *pnsecdesclen, __u64 *pnmode, kuid_t uid, kgid_t gid,
+       bool mode_from_sid, bool id_from_sid, int *aclflag)
+ {
+@@ -1279,7 +1279,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
+                       le32_to_cpu(pntsd->gsidoffset));
+       if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
+-              ndacloffset = sizeof(struct cifs_ntsd);
++              ndacloffset = sizeof(struct smb_ntsd);
+               ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
+               ndacl_ptr->revision =
+                       dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
+@@ -1297,7 +1297,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
+               *aclflag |= CIFS_ACL_DACL;
+       } else {
+-              ndacloffset = sizeof(struct cifs_ntsd);
++              ndacloffset = sizeof(struct smb_ntsd);
+               ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
+               ndacl_ptr->revision =
+                       dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
+@@ -1385,11 +1385,11 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
+ }
+ #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
+-struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
++struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
+                                     const struct cifs_fid *cifsfid, u32 *pacllen,
+                                     u32 __maybe_unused unused)
+ {
+-      struct cifs_ntsd *pntsd = NULL;
++      struct smb_ntsd *pntsd = NULL;
+       unsigned int xid;
+       int rc;
+       struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
+@@ -1410,10 +1410,10 @@ struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
+       return pntsd;
+ }
+-static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
++static struct smb_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
+               const char *path, u32 *pacllen)
+ {
+-      struct cifs_ntsd *pntsd = NULL;
++      struct smb_ntsd *pntsd = NULL;
+       int oplock = 0;
+       unsigned int xid;
+       int rc;
+@@ -1454,11 +1454,11 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
+ }
+ /* Retrieve an ACL from the server */
+-struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
++struct smb_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
+                                     struct inode *inode, const char *path,
+                              u32 *pacllen, u32 info)
+ {
+-      struct cifs_ntsd *pntsd = NULL;
++      struct smb_ntsd *pntsd = NULL;
+       struct cifsFileInfo *open_file = NULL;
+       if (inode)
+@@ -1472,7 +1472,7 @@ struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
+ }
+  /* Set an ACL on the server */
+-int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
++int set_cifs_acl(struct smb_ntsd *pnntsd, __u32 acllen,
+                       struct inode *inode, const char *path, int aclflag)
+ {
+       int oplock = 0;
+@@ -1528,7 +1528,7 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
+                 struct inode *inode, bool mode_from_special_sid,
+                 const char *path, const struct cifs_fid *pfid)
+ {
+-      struct cifs_ntsd *pntsd = NULL;
++      struct smb_ntsd *pntsd = NULL;
+       u32 acllen = 0;
+       int rc = 0;
+       struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
+@@ -1581,8 +1581,8 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
+       __u32 nsecdesclen = 0;
+       __u32 dacloffset = 0;
+       struct cifs_acl *dacl_ptr = NULL;
+-      struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
+-      struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
++      struct smb_ntsd *pntsd = NULL; /* acl obtained from server */
++      struct smb_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
+       struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+       struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
+       struct smb_version_operations *ops;
+@@ -1630,7 +1630,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
+                       nsecdesclen += 5 * sizeof(struct cifs_ace);
+       } else { /* chown */
+               /* When ownership changes, changes new owner sid length could be different */
+-              nsecdesclen = sizeof(struct cifs_ntsd) + (sizeof(struct cifs_sid) * 2);
++              nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct cifs_sid) * 2);
+               dacloffset = le32_to_cpu(pntsd->dacloffset);
+               if (dacloffset) {
+                       dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
+diff --git a/fs/smb/client/cifsacl.h b/fs/smb/client/cifsacl.h
+index ccbfc754bd3c..1516545d7f67 100644
+--- a/fs/smb/client/cifsacl.h
++++ b/fs/smb/client/cifsacl.h
+@@ -33,7 +33,7 @@
+  * Security Descriptor length containing DACL with 3 ACEs (one each for
+  * owner, group and world).
+  */
+-#define DEFAULT_SEC_DESC_LEN (sizeof(struct cifs_ntsd) + \
++#define DEFAULT_SEC_DESC_LEN (sizeof(struct smb_ntsd) + \
+                             sizeof(struct cifs_acl) + \
+                             (sizeof(struct cifs_ace) * 4))
+@@ -55,7 +55,7 @@
+ #define SID_STRING_BASE_SIZE (2 + 3 + 15 + 1)
+ #define SID_STRING_SUBAUTH_SIZE (11) /* size of a single subauth string */
+-struct cifs_ntsd {
++struct smb_ntsd {
+       __le16 revision; /* revision level */
+       __le16 type;
+       __le32 osidoffset;
+@@ -194,6 +194,6 @@ struct owner_group_sids {
+  * Minimum security descriptor can be one without any SACL and DACL and can
+  * consist of revision, type, and two sids of minimum size for owner and group
+  */
+-#define MIN_SEC_DESC_LEN  (sizeof(struct cifs_ntsd) + (2 * MIN_SID_LEN))
++#define MIN_SEC_DESC_LEN  (sizeof(struct smb_ntsd) + (2 * MIN_SID_LEN))
+ #endif /* _CIFSACL_H */
+diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
+index 6b57b167a49d..cf22629bf90b 100644
+--- a/fs/smb/client/cifsglob.h
++++ b/fs/smb/client/cifsglob.h
+@@ -539,12 +539,12 @@ struct smb_version_operations {
+       int (*set_EA)(const unsigned int, struct cifs_tcon *, const char *,
+                       const char *, const void *, const __u16,
+                       const struct nls_table *, struct cifs_sb_info *);
+-      struct cifs_ntsd * (*get_acl)(struct cifs_sb_info *, struct inode *,
+-                      const char *, u32 *, u32);
+-      struct cifs_ntsd * (*get_acl_by_fid)(struct cifs_sb_info *,
+-                      const struct cifs_fid *, u32 *, u32);
+-      int (*set_acl)(struct cifs_ntsd *, __u32, struct inode *, const char *,
+-                      int);
++      struct smb_ntsd * (*get_acl)(struct cifs_sb_info *cifssb, struct inode *ino,
++                      const char *patch, u32 *plen, u32 info);
++      struct smb_ntsd * (*get_acl_by_fid)(struct cifs_sb_info *cifssmb,
++                      const struct cifs_fid *pfid, u32 *plen, u32 info);
++      int (*set_acl)(struct smb_ntsd *pntsd, __u32 len, struct inode *ino, const char *path,
++                      int flag);
+       /* writepages retry size */
+       unsigned int (*wp_retry_size)(struct inode *);
+       /* get mtu credits */
+diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
+index 83692bf60007..f34c533efe49 100644
+--- a/fs/smb/client/cifsproto.h
++++ b/fs/smb/client/cifsproto.h
+@@ -231,16 +231,16 @@ extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb,
+                             const char *path, const struct cifs_fid *pfid);
+ extern int id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
+                                       kuid_t uid, kgid_t gid);
+-extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *,
+-                                    const char *, u32 *, u32);
+-extern struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *,
+-                              const struct cifs_fid *, u32 *, u32);
++extern struct smb_ntsd *get_cifs_acl(struct cifs_sb_info *cifssmb, struct inode *ino,
++                                    const char *path, u32 *plen, u32 info);
++extern struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifssb,
++                              const struct cifs_fid *pfid, u32 *plen, u32 info);
+ extern struct posix_acl *cifs_get_acl(struct mnt_idmap *idmap,
+                                     struct dentry *dentry, int type);
+ extern int cifs_set_acl(struct mnt_idmap *idmap,
+                       struct dentry *dentry, struct posix_acl *acl, int type);
+-extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *,
+-                              const char *, int);
++extern int set_cifs_acl(struct smb_ntsd *pntsd, __u32 len, struct inode *ino,
++                              const char *path, int flag);
+ extern unsigned int setup_authusers_ACE(struct cifs_ace *pace);
+ extern unsigned int setup_special_mode_ACE(struct cifs_ace *pace, __u64 nmode);
+ extern unsigned int setup_special_user_owner_ACE(struct cifs_ace *pace);
+@@ -568,9 +568,9 @@ extern int CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
+               const struct nls_table *nls_codepage,
+               struct cifs_sb_info *cifs_sb);
+ extern int CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon,
+-                      __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen);
++                      __u16 fid, struct smb_ntsd **acl_inf, __u32 *buflen);
+ extern int CIFSSMBSetCIFSACL(const unsigned int, struct cifs_tcon *, __u16,
+-                      struct cifs_ntsd *, __u32, int);
++                      struct smb_ntsd *pntsd, __u32 len, int aclflag);
+ extern int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
+                          const unsigned char *searchName,
+                          struct posix_acl **acl, const int acl_type,
+diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
+index a34db419e46f..2f8745736dbb 100644
+--- a/fs/smb/client/cifssmb.c
++++ b/fs/smb/client/cifssmb.c
+@@ -3385,7 +3385,7 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
+ /* Get Security Descriptor (by handle) from remote server for a file or dir */
+ int
+ CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
+-                struct cifs_ntsd **acl_inf, __u32 *pbuflen)
++                struct smb_ntsd **acl_inf, __u32 *pbuflen)
+ {
+       int rc = 0;
+       int buf_type = 0;
+@@ -3455,7 +3455,7 @@ CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
+               /* check if buffer is big enough for the acl
+                  header followed by the smallest SID */
+-              if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
++              if ((*pbuflen < sizeof(struct smb_ntsd) + 8) ||
+                   (*pbuflen >= 64 * 1024)) {
+                       cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
+                       rc = -EINVAL;
+@@ -3475,7 +3475,7 @@ CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
+ int
+ CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
+-                      struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
++                      struct smb_ntsd *pntsd, __u32 acllen, int aclflag)
+ {
+       __u16 byte_count, param_count, data_count, param_offset, data_offset;
+       int rc = 0;
+diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
+index 6645f147d57c..fc6d00344c50 100644
+--- a/fs/smb/client/smb2ops.c
++++ b/fs/smb/client/smb2ops.c
+@@ -3001,11 +3001,11 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
+       return rc;
+ }
+-static struct cifs_ntsd *
++static struct smb_ntsd *
+ get_smb2_acl_by_fid(struct cifs_sb_info *cifs_sb,
+                   const struct cifs_fid *cifsfid, u32 *pacllen, u32 info)
+ {
+-      struct cifs_ntsd *pntsd = NULL;
++      struct smb_ntsd *pntsd = NULL;
+       unsigned int xid;
+       int rc = -EOPNOTSUPP;
+       struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
+@@ -3030,11 +3030,11 @@ get_smb2_acl_by_fid(struct cifs_sb_info *cifs_sb,
+ }
+-static struct cifs_ntsd *
++static struct smb_ntsd *
+ get_smb2_acl_by_path(struct cifs_sb_info *cifs_sb,
+                    const char *path, u32 *pacllen, u32 info)
+ {
+-      struct cifs_ntsd *pntsd = NULL;
++      struct smb_ntsd *pntsd = NULL;
+       u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
+       unsigned int xid;
+       int rc;
+@@ -3097,7 +3097,7 @@ get_smb2_acl_by_path(struct cifs_sb_info *cifs_sb,
+ }
+ static int
+-set_smb2_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
++set_smb2_acl(struct smb_ntsd *pnntsd, __u32 acllen,
+               struct inode *inode, const char *path, int aclflag)
+ {
+       u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
+@@ -3155,12 +3155,12 @@ set_smb2_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
+ }
+ /* Retrieve an ACL from the server */
+-static struct cifs_ntsd *
++static struct smb_ntsd *
+ get_smb2_acl(struct cifs_sb_info *cifs_sb,
+            struct inode *inode, const char *path,
+            u32 *pacllen, u32 info)
+ {
+-      struct cifs_ntsd *pntsd = NULL;
++      struct smb_ntsd *pntsd = NULL;
+       struct cifsFileInfo *open_file = NULL;
+       if (inode && !(info & SACL_SECINFO))
+diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
+index 38b26468eb0c..0a4985bba55f 100644
+--- a/fs/smb/client/smb2pdu.c
++++ b/fs/smb/client/smb2pdu.c
+@@ -5626,7 +5626,7 @@ SMB2_set_eof(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
+ int
+ SMB2_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
+               u64 persistent_fid, u64 volatile_fid,
+-              struct cifs_ntsd *pnntsd, int pacllen, int aclflag)
++              struct smb_ntsd *pnntsd, int pacllen, int aclflag)
+ {
+       return send_set_info(xid, tcon, persistent_fid, volatile_fid,
+                       current->tgid, 0, SMB2_O_INFO_SECURITY, aclflag,
+diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h
+index 613667b46c58..fd90d8e5a1d1 100644
+--- a/fs/smb/client/smb2proto.h
++++ b/fs/smb/client/smb2proto.h
+@@ -247,7 +247,7 @@ extern int SMB2_set_info_init(struct cifs_tcon *tcon,
+ extern void SMB2_set_info_free(struct smb_rqst *rqst);
+ extern int SMB2_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
+                       u64 persistent_fid, u64 volatile_fid,
+-                      struct cifs_ntsd *pnntsd, int pacllen, int aclflag);
++                      struct smb_ntsd *pnntsd, int pacllen, int aclflag);
+ extern int SMB2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
+                      u64 persistent_fid, u64 volatile_fid,
+                      struct smb2_file_full_ea_info *buf, int len);
+diff --git a/fs/smb/client/xattr.c b/fs/smb/client/xattr.c
+index c2bf829310be..e8696ad4da99 100644
+--- a/fs/smb/client/xattr.c
++++ b/fs/smb/client/xattr.c
+@@ -162,7 +162,7 @@ static int cifs_xattr_set(const struct xattr_handler *handler,
+       case XATTR_CIFS_ACL:
+       case XATTR_CIFS_NTSD:
+       case XATTR_CIFS_NTSD_FULL: {
+-              struct cifs_ntsd *pacl;
++              struct smb_ntsd *pacl;
+               if (!value)
+                       goto out;
+@@ -315,7 +315,7 @@ static int cifs_xattr_get(const struct xattr_handler *handler,
+                * fetch owner and DACL otherwise
+                */
+               u32 acllen, extra_info;
+-              struct cifs_ntsd *pacl;
++              struct smb_ntsd *pacl;
+               if (pTcon->ses->server->ops->get_acl == NULL)
+                       goto out; /* rc already EOPNOTSUPP */
+-- 
+2.39.5
+
diff --git a/queue-6.6/smb-client-rename-cifs_sid-to-smb_sid.patch b/queue-6.6/smb-client-rename-cifs_sid-to-smb_sid.patch
new file mode 100644 (file)
index 0000000..ece7962
--- /dev/null
@@ -0,0 +1,486 @@
+From 1dfdf72170666c41e22d81705cc81bfd868208f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Aug 2024 08:20:56 +0000
+Subject: smb/client: rename cifs_sid to smb_sid
+
+From: ChenXiaoSong <chenxiaosong@kylinos.cn>
+
+[ Upstream commit 7f599d8fb3e087aff5be4e1392baaae3f8d42419 ]
+
+Preparation for moving acl definitions to new common header file.
+
+Use the following shell command to rename:
+
+  find fs/smb/client -type f -exec sed -i \
+    's/struct cifs_sid/struct smb_sid/g' {} +
+
+Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
+Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: d413eabff18d ("fs/smb/client: implement chmod() for SMB3 POSIX Extensions")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/cifsacl.c   | 96 +++++++++++++++++++--------------------
+ fs/smb/client/cifsacl.h   |  6 +--
+ fs/smb/client/cifsglob.h  |  8 ++--
+ fs/smb/client/cifsproto.h |  2 +-
+ fs/smb/client/smb2inode.c |  4 +-
+ fs/smb/client/smb2pdu.c   |  2 +-
+ fs/smb/client/smb2pdu.h   |  8 ++--
+ 7 files changed, 63 insertions(+), 63 deletions(-)
+
+diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c
+index 3f7657475cd9..dd399f9a7424 100644
+--- a/fs/smb/client/cifsacl.c
++++ b/fs/smb/client/cifsacl.c
+@@ -27,18 +27,18 @@
+ #include "cifs_unicode.h"
+ /* security id for everyone/world system group */
+-static const struct cifs_sid sid_everyone = {
++static const struct smb_sid sid_everyone = {
+       1, 1, {0, 0, 0, 0, 0, 1}, {0} };
+ /* security id for Authenticated Users system group */
+-static const struct cifs_sid sid_authusers = {
++static const struct smb_sid sid_authusers = {
+       1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
+ /* S-1-22-1 Unmapped Unix users */
+-static const struct cifs_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
++static const struct smb_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
+               {cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
+ /* S-1-22-2 Unmapped Unix groups */
+-static const struct cifs_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
++static const struct smb_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
+               {cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
+ /*
+@@ -48,17 +48,17 @@ static const struct cifs_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
+ /* S-1-5-88 MS NFS and Apple style UID/GID/mode */
+ /* S-1-5-88-1 Unix uid */
+-static const struct cifs_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
++static const struct smb_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
+       {cpu_to_le32(88),
+        cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
+ /* S-1-5-88-2 Unix gid */
+-static const struct cifs_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
++static const struct smb_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
+       {cpu_to_le32(88),
+        cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
+ /* S-1-5-88-3 Unix mode */
+-static const struct cifs_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
++static const struct smb_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
+       {cpu_to_le32(88),
+        cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
+@@ -106,7 +106,7 @@ static struct key_type cifs_idmap_key_type = {
+ };
+ static char *
+-sid_to_key_str(struct cifs_sid *sidptr, unsigned int type)
++sid_to_key_str(struct smb_sid *sidptr, unsigned int type)
+ {
+       int i, len;
+       unsigned int saval;
+@@ -158,7 +158,7 @@ sid_to_key_str(struct cifs_sid *sidptr, unsigned int type)
+  * the same returns zero, if they do not match returns non-zero.
+  */
+ static int
+-compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
++compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid)
+ {
+       int i;
+       int num_subauth, num_sat, num_saw;
+@@ -204,11 +204,11 @@ compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
+ }
+ static bool
+-is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group)
++is_well_known_sid(const struct smb_sid *psid, uint32_t *puid, bool is_group)
+ {
+       int i;
+       int num_subauth;
+-      const struct cifs_sid *pwell_known_sid;
++      const struct smb_sid *pwell_known_sid;
+       if (!psid || (puid == NULL))
+               return false;
+@@ -260,7 +260,7 @@ is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group)
+ }
+ static __u16
+-cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
++cifs_copy_sid(struct smb_sid *dst, const struct smb_sid *src)
+ {
+       int i;
+       __u16 size = 1 + 1 + 6;
+@@ -277,11 +277,11 @@ cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
+ }
+ static int
+-id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
++id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
+ {
+       int rc;
+       struct key *sidkey;
+-      struct cifs_sid *ksid;
++      struct smb_sid *ksid;
+       unsigned int ksid_size;
+       char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
+       const struct cred *saved_cred;
+@@ -312,8 +312,8 @@ id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
+        * it could be.
+        */
+       ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
+-              (struct cifs_sid *)&sidkey->payload :
+-              (struct cifs_sid *)sidkey->payload.data[0];
++              (struct smb_sid *)&sidkey->payload :
++              (struct smb_sid *)sidkey->payload.data[0];
+       ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
+       if (ksid_size > sidkey->datalen) {
+@@ -336,7 +336,7 @@ id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
+ }
+ int
+-sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
++sid_to_id(struct cifs_sb_info *cifs_sb, struct smb_sid *psid,
+               struct cifs_fattr *fattr, uint sidtype)
+ {
+       int rc = 0;
+@@ -518,11 +518,11 @@ exit_cifs_idmap(void)
+ static __u32 copy_sec_desc(const struct smb_ntsd *pntsd,
+                               struct smb_ntsd *pnntsd,
+                               __u32 sidsoffset,
+-                              struct cifs_sid *pownersid,
+-                              struct cifs_sid *pgrpsid)
++                              struct smb_sid *pownersid,
++                              struct smb_sid *pgrpsid)
+ {
+-      struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
+-      struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
++      struct smb_sid *owner_sid_ptr, *group_sid_ptr;
++      struct smb_sid *nowner_sid_ptr, *ngroup_sid_ptr;
+       /* copy security descriptor control portion */
+       pnntsd->revision = pntsd->revision;
+@@ -530,28 +530,28 @@ static __u32 copy_sec_desc(const struct smb_ntsd *pntsd,
+       pnntsd->dacloffset = cpu_to_le32(sizeof(struct smb_ntsd));
+       pnntsd->sacloffset = 0;
+       pnntsd->osidoffset = cpu_to_le32(sidsoffset);
+-      pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
++      pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct smb_sid));
+       /* copy owner sid */
+       if (pownersid)
+               owner_sid_ptr = pownersid;
+       else
+-              owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
++              owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
+                               le32_to_cpu(pntsd->osidoffset));
+-      nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
++      nowner_sid_ptr = (struct smb_sid *)((char *)pnntsd + sidsoffset);
+       cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
+       /* copy group sid */
+       if (pgrpsid)
+               group_sid_ptr = pgrpsid;
+       else
+-              group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
++              group_sid_ptr = (struct smb_sid *)((char *)pntsd +
+                               le32_to_cpu(pntsd->gsidoffset));
+-      ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
+-                                      sizeof(struct cifs_sid));
++      ngroup_sid_ptr = (struct smb_sid *)((char *)pnntsd + sidsoffset +
++                                      sizeof(struct smb_sid));
+       cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
+-      return sidsoffset + (2 * sizeof(struct cifs_sid));
++      return sidsoffset + (2 * sizeof(struct smb_sid));
+ }
+@@ -666,7 +666,7 @@ static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
+       return;
+ }
+-static __u16 cifs_copy_ace(struct cifs_ace *dst, struct cifs_ace *src, struct cifs_sid *psid)
++static __u16 cifs_copy_ace(struct cifs_ace *dst, struct cifs_ace *src, struct smb_sid *psid)
+ {
+       __u16 size = 1 + 1 + 2 + 4;
+@@ -686,7 +686,7 @@ static __u16 cifs_copy_ace(struct cifs_ace *dst, struct cifs_ace *src, struct ci
+ }
+ static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
+-                      const struct cifs_sid *psid, __u64 nmode,
++                      const struct smb_sid *psid, __u64 nmode,
+                       umode_t bits, __u8 access_type,
+                       bool allow_delete_child)
+ {
+@@ -759,7 +759,7 @@ static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
+ #endif
+ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
+-                     struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
++                     struct smb_sid *pownersid, struct smb_sid *pgrpsid,
+                      struct cifs_fattr *fattr, bool mode_from_special_sid)
+ {
+       int i;
+@@ -930,8 +930,8 @@ unsigned int setup_special_user_owner_ACE(struct cifs_ace *pntace)
+ }
+ static void populate_new_aces(char *nacl_base,
+-              struct cifs_sid *pownersid,
+-              struct cifs_sid *pgrpsid,
++              struct smb_sid *pownersid,
++              struct smb_sid *pgrpsid,
+               __u64 *pnmode, u32 *pnum_aces, u16 *pnsize,
+               bool modefromsid)
+ {
+@@ -967,7 +967,7 @@ static void populate_new_aces(char *nacl_base,
+        * updated in the inode.
+        */
+-      if (!memcmp(pownersid, pgrpsid, sizeof(struct cifs_sid))) {
++      if (!memcmp(pownersid, pgrpsid, sizeof(struct smb_sid))) {
+               /*
+                * Case when owner and group SIDs are the same.
+                * Set the more restrictive of the two modes.
+@@ -1035,8 +1035,8 @@ static void populate_new_aces(char *nacl_base,
+ }
+ static __u16 replace_sids_and_copy_aces(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
+-              struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
+-              struct cifs_sid *pnownersid, struct cifs_sid *pngrpsid)
++              struct smb_sid *pownersid, struct smb_sid *pgrpsid,
++              struct smb_sid *pnownersid, struct smb_sid *pngrpsid)
+ {
+       int i;
+       u16 size = 0;
+@@ -1075,7 +1075,7 @@ static __u16 replace_sids_and_copy_aces(struct cifs_acl *pdacl, struct cifs_acl
+ }
+ static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
+-              struct cifs_sid *pownersid,     struct cifs_sid *pgrpsid,
++              struct smb_sid *pownersid,      struct smb_sid *pgrpsid,
+               __u64 *pnmode, bool mode_from_sid)
+ {
+       int i;
+@@ -1156,7 +1156,7 @@ static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
+       return 0;
+ }
+-static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
++static int parse_sid(struct smb_sid *psid, char *end_of_acl)
+ {
+       /* BB need to add parm so we can store the SID BB */
+@@ -1195,7 +1195,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
+               bool get_mode_from_special_sid)
+ {
+       int rc = 0;
+-      struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
++      struct smb_sid *owner_sid_ptr, *group_sid_ptr;
+       struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
+       char *end_of_acl = ((char *)pntsd) + acl_len;
+       __u32 dacloffset;
+@@ -1203,9 +1203,9 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
+       if (pntsd == NULL)
+               return -EIO;
+-      owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
++      owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
+                               le32_to_cpu(pntsd->osidoffset));
+-      group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
++      group_sid_ptr = (struct smb_sid *)((char *)pntsd +
+                               le32_to_cpu(pntsd->gsidoffset));
+       dacloffset = le32_to_cpu(pntsd->dacloffset);
+       dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
+@@ -1257,8 +1257,8 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
+       __u32 dacloffset;
+       __u32 ndacloffset;
+       __u32 sidsoffset;
+-      struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
+-      struct cifs_sid *nowner_sid_ptr = NULL, *ngroup_sid_ptr = NULL;
++      struct smb_sid *owner_sid_ptr, *group_sid_ptr;
++      struct smb_sid *nowner_sid_ptr = NULL, *ngroup_sid_ptr = NULL;
+       struct cifs_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
+       struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
+       char *end_of_acl = ((char *)pntsd) + secdesclen;
+@@ -1273,9 +1273,9 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
+               }
+       }
+-      owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
++      owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
+                       le32_to_cpu(pntsd->osidoffset));
+-      group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
++      group_sid_ptr = (struct smb_sid *)((char *)pntsd +
+                       le32_to_cpu(pntsd->gsidoffset));
+       if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
+@@ -1305,7 +1305,7 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
+               if (uid_valid(uid)) { /* chown */
+                       uid_t id;
+-                      nowner_sid_ptr = kzalloc(sizeof(struct cifs_sid),
++                      nowner_sid_ptr = kzalloc(sizeof(struct smb_sid),
+                                                               GFP_KERNEL);
+                       if (!nowner_sid_ptr) {
+                               rc = -ENOMEM;
+@@ -1334,7 +1334,7 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
+               }
+               if (gid_valid(gid)) { /* chgrp */
+                       gid_t id;
+-                      ngroup_sid_ptr = kzalloc(sizeof(struct cifs_sid),
++                      ngroup_sid_ptr = kzalloc(sizeof(struct smb_sid),
+                                                               GFP_KERNEL);
+                       if (!ngroup_sid_ptr) {
+                               rc = -ENOMEM;
+@@ -1630,7 +1630,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
+                       nsecdesclen += 5 * sizeof(struct cifs_ace);
+       } else { /* chown */
+               /* When ownership changes, changes new owner sid length could be different */
+-              nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct cifs_sid) * 2);
++              nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct smb_sid) * 2);
+               dacloffset = le32_to_cpu(pntsd->dacloffset);
+               if (dacloffset) {
+                       dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
+diff --git a/fs/smb/client/cifsacl.h b/fs/smb/client/cifsacl.h
+index 1516545d7f67..6a38718220fc 100644
+--- a/fs/smb/client/cifsacl.h
++++ b/fs/smb/client/cifsacl.h
+@@ -64,14 +64,14 @@ struct smb_ntsd {
+       __le32 dacloffset;
+ } __attribute__((packed));
+-struct cifs_sid {
++struct smb_sid {
+       __u8 revision; /* revision level */
+       __u8 num_subauth;
+       __u8 authority[NUM_AUTHS];
+       __le32 sub_auth[SID_MAX_SUB_AUTHORITIES]; /* sub_auth[num_subauth] */
+ } __attribute__((packed));
+-/* size of a struct cifs_sid, sans sub_auth array */
++/* size of a struct smb_sid, sans sub_auth array */
+ #define CIFS_SID_BASE_SIZE (1 + 1 + NUM_AUTHS)
+ struct cifs_acl {
+@@ -116,7 +116,7 @@ struct cifs_ace {
+       __u8 flags;
+       __le16 size;
+       __le32 access_req;
+-      struct cifs_sid sid; /* ie UUID of user or group who gets these perms */
++      struct smb_sid sid; /* ie UUID of user or group who gets these perms */
+ } __attribute__((packed));
+ /*
+diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
+index cf22629bf90b..69d850b6b37f 100644
+--- a/fs/smb/client/cifsglob.h
++++ b/fs/smb/client/cifsglob.h
+@@ -202,8 +202,8 @@ struct cifs_cred {
+       int gid;
+       int mode;
+       int cecount;
+-      struct cifs_sid osid;
+-      struct cifs_sid gsid;
++      struct smb_sid osid;
++      struct smb_sid gsid;
+       struct cifs_ntace *ntaces;
+       struct cifs_ace *aces;
+ };
+@@ -231,8 +231,8 @@ struct cifs_open_info_data {
+               unsigned int    eas_len;
+       } wsl;
+       char *symlink_target;
+-      struct cifs_sid posix_owner;
+-      struct cifs_sid posix_group;
++      struct smb_sid posix_owner;
++      struct smb_sid posix_group;
+       union {
+               struct smb2_file_all_info fi;
+               struct smb311_posix_qinfo posix_fi;
+diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
+index f34c533efe49..059e506ccf5b 100644
+--- a/fs/smb/client/cifsproto.h
++++ b/fs/smb/client/cifsproto.h
+@@ -223,7 +223,7 @@ extern int cifs_set_file_info(struct inode *inode, struct iattr *attrs,
+ extern int cifs_rename_pending_delete(const char *full_path,
+                                     struct dentry *dentry,
+                                     const unsigned int xid);
+-extern int sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
++extern int sid_to_id(struct cifs_sb_info *cifs_sb, struct smb_sid *psid,
+                               struct cifs_fattr *fattr, uint sidtype);
+ extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb,
+                             struct cifs_fattr *fattr, struct inode *inode,
+diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c
+index 2a292736c89a..e695df1dbb23 100644
+--- a/fs/smb/client/smb2inode.c
++++ b/fs/smb/client/smb2inode.c
+@@ -315,7 +315,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
+                                                         SMB2_O_INFO_FILE, 0,
+                                                         sizeof(struct smb311_posix_qinfo *) +
+                                                         (PATH_MAX * 2) +
+-                                                        (sizeof(struct cifs_sid) * 2), 0, NULL);
++                                                        (sizeof(struct smb_sid) * 2), 0, NULL);
+                       } else {
+                               rc = SMB2_query_info_init(tcon, server,
+                                                         &rqst[num_rqst],
+@@ -325,7 +325,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
+                                                         SMB2_O_INFO_FILE, 0,
+                                                         sizeof(struct smb311_posix_qinfo *) +
+                                                         (PATH_MAX * 2) +
+-                                                        (sizeof(struct cifs_sid) * 2), 0, NULL);
++                                                        (sizeof(struct smb_sid) * 2), 0, NULL);
+                       }
+                       if (!rc && (!cfile || num_rqst > 1)) {
+                               smb2_set_next_command(tcon, &rqst[num_rqst]);
+diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
+index 0a4985bba55f..42f950ae10fb 100644
+--- a/fs/smb/client/smb2pdu.c
++++ b/fs/smb/client/smb2pdu.c
+@@ -3915,7 +3915,7 @@ SMB311_posix_query_info(const unsigned int xid, struct cifs_tcon *tcon,
+               u64 persistent_fid, u64 volatile_fid, struct smb311_posix_qinfo *data, u32 *plen)
+ {
+       size_t output_len = sizeof(struct smb311_posix_qinfo *) +
+-                      (sizeof(struct cifs_sid) * 2) + (PATH_MAX * 2);
++                      (sizeof(struct smb_sid) * 2) + (PATH_MAX * 2);
+       *plen = 0;
+       return query_info(xid, tcon, persistent_fid, volatile_fid,
+diff --git a/fs/smb/client/smb2pdu.h b/fs/smb/client/smb2pdu.h
+index 5c458ab3b05a..076d9e83e1a0 100644
+--- a/fs/smb/client/smb2pdu.h
++++ b/fs/smb/client/smb2pdu.h
+@@ -364,8 +364,8 @@ struct create_posix_rsp {
+       u32 nlink;
+       u32 reparse_tag;
+       u32 mode;
+-      struct cifs_sid owner; /* var-sized on the wire */
+-      struct cifs_sid group; /* var-sized on the wire */
++      struct smb_sid owner; /* var-sized on the wire */
++      struct smb_sid group; /* var-sized on the wire */
+ } __packed;
+ #define SMB2_QUERY_DIRECTORY_IOV_SIZE 2
+@@ -408,8 +408,8 @@ struct smb2_posix_info {
+ struct smb2_posix_info_parsed {
+       const struct smb2_posix_info *base;
+       size_t size;
+-      struct cifs_sid owner;
+-      struct cifs_sid group;
++      struct smb_sid owner;
++      struct smb_sid group;
+       int name_len;
+       const u8 *name;
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.6/smb-client-stop-flooding-dmesg-in-smb2_calc_signatur.patch b/queue-6.6/smb-client-stop-flooding-dmesg-in-smb2_calc_signatur.patch
new file mode 100644 (file)
index 0000000..d9e0fc5
--- /dev/null
@@ -0,0 +1,38 @@
+From 87c234693cf0285f61446a00e145084321fd5bc2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Sep 2024 02:04:01 -0300
+Subject: smb: client: stop flooding dmesg in smb2_calc_signature()
+
+From: Paulo Alcantara <pc@manguebit.com>
+
+[ Upstream commit a13ca780afab350f37f8be9eda2bf79d1aed9bdd ]
+
+When having several mounts that share same credential and the client
+couldn't re-establish an SMB session due to an expired kerberos ticket
+or rotated password, smb2_calc_signature() will end up flooding dmesg
+when not finding SMB sessions to calculate signatures.
+
+Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 343d7fe6df9e ("smb: client: fix use-after-free of signing key")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/smb2transport.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c
+index 4ca04e62a993..73eae1b16034 100644
+--- a/fs/smb/client/smb2transport.c
++++ b/fs/smb/client/smb2transport.c
+@@ -242,7 +242,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
+       ses = smb2_find_smb_ses(server, le64_to_cpu(shdr->SessionId));
+       if (unlikely(!ses)) {
+-              cifs_server_dbg(VFS, "%s: Could not find session\n", __func__);
++              cifs_server_dbg(FYI, "%s: Could not find session\n", __func__);
+               return -ENOENT;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.6/softirq-allow-raising-sched_softirq-from-smp-call-fu.patch b/queue-6.6/softirq-allow-raising-sched_softirq-from-smp-call-fu.patch
new file mode 100644 (file)
index 0000000..577f2db
--- /dev/null
@@ -0,0 +1,91 @@
+From 1a1f81f97d609db67730370e56ba4733824136c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Nov 2024 05:44:29 +0000
+Subject: softirq: Allow raising SCHED_SOFTIRQ from SMP-call-function on RT
+ kernel
+
+From: K Prateek Nayak <kprateek.nayak@amd.com>
+
+[ Upstream commit 6675ce20046d149e1e1ffe7e9577947dee17aad5 ]
+
+do_softirq_post_smp_call_flush() on PREEMPT_RT kernels carries a
+WARN_ON_ONCE() for any SOFTIRQ being raised from an SMP-call-function.
+Since do_softirq_post_smp_call_flush() is called with preempt disabled,
+raising a SOFTIRQ during flush_smp_call_function_queue() can lead to
+longer preempt disabled sections.
+
+Since commit b2a02fc43a1f ("smp: Optimize
+send_call_function_single_ipi()") IPIs to an idle CPU in
+TIF_POLLING_NRFLAG mode can be optimized out by instead setting
+TIF_NEED_RESCHED bit in idle task's thread_info and relying on the
+flush_smp_call_function_queue() in the idle-exit path to run the
+SMP-call-function.
+
+To trigger an idle load balancing, the scheduler queues
+nohz_csd_function() responsible for triggering an idle load balancing on
+a target nohz idle CPU and sends an IPI. Only now, this IPI is optimized
+out and the SMP-call-function is executed from
+flush_smp_call_function_queue() in do_idle() which can raise a
+SCHED_SOFTIRQ to trigger the balancing.
+
+So far, this went undetected since, the need_resched() check in
+nohz_csd_function() would make it bail out of idle load balancing early
+as the idle thread does not clear TIF_POLLING_NRFLAG before calling
+flush_smp_call_function_queue(). The need_resched() check was added with
+the intent to catch a new task wakeup, however, it has recently
+discovered to be unnecessary and will be removed in the subsequent
+commit after which nohz_csd_function() can raise a SCHED_SOFTIRQ from
+flush_smp_call_function_queue() to trigger an idle load balance on an
+idle target in TIF_POLLING_NRFLAG mode.
+
+nohz_csd_function() bails out early if "idle_cpu()" check for the
+target CPU, and does not lock the target CPU's rq until the very end,
+once it has found tasks to run on the CPU and will not inhibit the
+wakeup of, or running of a newly woken up higher priority task. Account
+for this and prevent a WARN_ON_ONCE() when SCHED_SOFTIRQ is raised from
+flush_smp_call_function_queue().
+
+Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20241119054432.6405-2-kprateek.nayak@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/softirq.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/kernel/softirq.c b/kernel/softirq.c
+index bd9716d7bb63..f24d80cf20bd 100644
+--- a/kernel/softirq.c
++++ b/kernel/softirq.c
+@@ -279,17 +279,24 @@ static inline void invoke_softirq(void)
+               wakeup_softirqd();
+ }
++#define SCHED_SOFTIRQ_MASK    BIT(SCHED_SOFTIRQ)
++
+ /*
+  * flush_smp_call_function_queue() can raise a soft interrupt in a function
+- * call. On RT kernels this is undesired and the only known functionality
+- * in the block layer which does this is disabled on RT. If soft interrupts
+- * get raised which haven't been raised before the flush, warn so it can be
++ * call. On RT kernels this is undesired and the only known functionalities
++ * are in the block layer which is disabled on RT, and in the scheduler for
++ * idle load balancing. If soft interrupts get raised which haven't been
++ * raised before the flush, warn if it is not a SCHED_SOFTIRQ so it can be
+  * investigated.
+  */
+ void do_softirq_post_smp_call_flush(unsigned int was_pending)
+ {
+-      if (WARN_ON_ONCE(was_pending != local_softirq_pending()))
++      unsigned int is_pending = local_softirq_pending();
++
++      if (unlikely(was_pending != is_pending)) {
++              WARN_ON_ONCE(was_pending != (is_pending & ~SCHED_SOFTIRQ_MASK));
+               invoke_softirq();
++      }
+ }
+ #else /* CONFIG_PREEMPT_RT */
+-- 
+2.39.5
+
diff --git a/queue-6.6/thunderbolt-add-support-for-intel-lunar-lake.patch b/queue-6.6/thunderbolt-add-support-for-intel-lunar-lake.patch
new file mode 100644 (file)
index 0000000..e01cb5d
--- /dev/null
@@ -0,0 +1,54 @@
+From abeb580d38a04ac82eb79aaae31aeadb4299943c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 May 2022 13:47:11 +0300
+Subject: thunderbolt: Add support for Intel Lunar Lake
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+[ Upstream commit 2cd3da4e37453019e21a486d9de3144f46b4fdf7 ]
+
+Intel Lunar Lake has similar integrated Thunderbolt/USB4 controller as
+Intel Meteor Lake with some small differences in the host router (it has
+3 DP IN adapters for instance). Add the Intel Lunar Lake PCI IDs to the
+driver list of supported devices.
+
+Tested-by: Pengfei Xu <pengfei.xu@intel.com>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Stable-dep-of: 8644b48714dc ("thunderbolt: Add support for Intel Panther Lake-M/P")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thunderbolt/nhi.c | 4 ++++
+ drivers/thunderbolt/nhi.h | 2 ++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
+index 1ec6f9c82aef..b22023fae60d 100644
+--- a/drivers/thunderbolt/nhi.c
++++ b/drivers/thunderbolt/nhi.c
+@@ -1524,6 +1524,10 @@ static struct pci_device_id nhi_ids[] = {
+         .driver_data = (kernel_ulong_t)&icl_nhi_ops },
+       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MTL_P_NHI1),
+         .driver_data = (kernel_ulong_t)&icl_nhi_ops },
++      { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_LNL_NHI0),
++        .driver_data = (kernel_ulong_t)&icl_nhi_ops },
++      { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_LNL_NHI1),
++        .driver_data = (kernel_ulong_t)&icl_nhi_ops },
+       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_80G_NHI) },
+       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_40G_NHI) },
+diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h
+index 0f029ce75882..7a07c7c1a9c2 100644
+--- a/drivers/thunderbolt/nhi.h
++++ b/drivers/thunderbolt/nhi.h
+@@ -90,6 +90,8 @@ extern const struct tb_nhi_ops icl_nhi_ops;
+ #define PCI_DEVICE_ID_INTEL_TGL_H_NHI1                        0x9a21
+ #define PCI_DEVICE_ID_INTEL_RPL_NHI0                  0xa73e
+ #define PCI_DEVICE_ID_INTEL_RPL_NHI1                  0xa76d
++#define PCI_DEVICE_ID_INTEL_LNL_NHI0                  0xa833
++#define PCI_DEVICE_ID_INTEL_LNL_NHI1                  0xa834
+ #define PCI_CLASS_SERIAL_USB_USB4                     0x0c0340
+-- 
+2.39.5
+
diff --git a/queue-6.6/thunderbolt-add-support-for-intel-panther-lake-m-p.patch b/queue-6.6/thunderbolt-add-support-for-intel-panther-lake-m-p.patch
new file mode 100644 (file)
index 0000000..abb3503
--- /dev/null
@@ -0,0 +1,58 @@
+From be1f09403ebe8713bef6bba0b61e50f24fd5559d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 May 2024 10:15:14 +0300
+Subject: thunderbolt: Add support for Intel Panther Lake-M/P
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+[ Upstream commit 8644b48714dca8bf2f42a4ff8311de8efc9bd8c3 ]
+
+Intel Panther Lake-M/P has the same integrated Thunderbolt/USB4
+controller as Lunar Lake. Add these PCI IDs to the driver list of
+supported devices.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thunderbolt/nhi.c | 8 ++++++++
+ drivers/thunderbolt/nhi.h | 4 ++++
+ 2 files changed, 12 insertions(+)
+
+diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
+index b22023fae60d..79f2bf5df19a 100644
+--- a/drivers/thunderbolt/nhi.c
++++ b/drivers/thunderbolt/nhi.c
+@@ -1528,6 +1528,14 @@ static struct pci_device_id nhi_ids[] = {
+         .driver_data = (kernel_ulong_t)&icl_nhi_ops },
+       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_LNL_NHI1),
+         .driver_data = (kernel_ulong_t)&icl_nhi_ops },
++      { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_PTL_M_NHI0),
++        .driver_data = (kernel_ulong_t)&icl_nhi_ops },
++      { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_PTL_M_NHI1),
++        .driver_data = (kernel_ulong_t)&icl_nhi_ops },
++      { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_PTL_P_NHI0),
++        .driver_data = (kernel_ulong_t)&icl_nhi_ops },
++      { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_PTL_P_NHI1),
++        .driver_data = (kernel_ulong_t)&icl_nhi_ops },
+       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_80G_NHI) },
+       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_40G_NHI) },
+diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h
+index 7a07c7c1a9c2..16744f25a9a0 100644
+--- a/drivers/thunderbolt/nhi.h
++++ b/drivers/thunderbolt/nhi.h
+@@ -92,6 +92,10 @@ extern const struct tb_nhi_ops icl_nhi_ops;
+ #define PCI_DEVICE_ID_INTEL_RPL_NHI1                  0xa76d
+ #define PCI_DEVICE_ID_INTEL_LNL_NHI0                  0xa833
+ #define PCI_DEVICE_ID_INTEL_LNL_NHI1                  0xa834
++#define PCI_DEVICE_ID_INTEL_PTL_M_NHI0                        0xe333
++#define PCI_DEVICE_ID_INTEL_PTL_M_NHI1                        0xe334
++#define PCI_DEVICE_ID_INTEL_PTL_P_NHI0                        0xe433
++#define PCI_DEVICE_ID_INTEL_PTL_P_NHI1                        0xe434
+ #define PCI_CLASS_SERIAL_USB_USB4                     0x0c0340
+-- 
+2.39.5
+
diff --git a/queue-6.6/thunderbolt-don-t-display-nvm_version-unless-upgrade.patch b/queue-6.6/thunderbolt-don-t-display-nvm_version-unless-upgrade.patch
new file mode 100644 (file)
index 0000000..48bcd0d
--- /dev/null
@@ -0,0 +1,77 @@
+From 96ef200006965eee0b58f9e0184648a3f32256c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Dec 2024 10:25:51 -0600
+Subject: thunderbolt: Don't display nvm_version unless upgrade supported
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit e34f1717ef0632fcec5cb827e5e0e9f223d70c9b ]
+
+The read will never succeed if NVM wasn't initialized due to an unknown
+format.
+
+Add a new callback for visibility to only show when supported.
+
+Cc: stable@vger.kernel.org
+Fixes: aef9c693e7e5 ("thunderbolt: Move vendor specific NVM handling into nvm.c")
+Reported-by: Richard Hughes <hughsient@gmail.com>
+Closes: https://github.com/fwupd/fwupd/issues/8200
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thunderbolt/retimer.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/thunderbolt/retimer.c b/drivers/thunderbolt/retimer.c
+index 47becb363ada..2ee8c5ebca7c 100644
+--- a/drivers/thunderbolt/retimer.c
++++ b/drivers/thunderbolt/retimer.c
+@@ -98,6 +98,7 @@ static int tb_retimer_nvm_add(struct tb_retimer *rt)
+ err_nvm:
+       dev_dbg(&rt->dev, "NVM upgrade disabled\n");
++      rt->no_nvm_upgrade = true;
+       if (!IS_ERR(nvm))
+               tb_nvm_free(nvm);
+@@ -177,8 +178,6 @@ static ssize_t nvm_authenticate_show(struct device *dev,
+       if (!rt->nvm)
+               ret = -EAGAIN;
+-      else if (rt->no_nvm_upgrade)
+-              ret = -EOPNOTSUPP;
+       else
+               ret = sysfs_emit(buf, "%#x\n", rt->auth_status);
+@@ -331,6 +330,19 @@ static ssize_t vendor_show(struct device *dev, struct device_attribute *attr,
+ }
+ static DEVICE_ATTR_RO(vendor);
++static umode_t retimer_is_visible(struct kobject *kobj, struct attribute *attr,
++                                int n)
++{
++      struct device *dev = kobj_to_dev(kobj);
++      struct tb_retimer *rt = tb_to_retimer(dev);
++
++      if (attr == &dev_attr_nvm_authenticate.attr ||
++          attr == &dev_attr_nvm_version.attr)
++              return rt->no_nvm_upgrade ? 0 : attr->mode;
++
++      return attr->mode;
++}
++
+ static struct attribute *retimer_attrs[] = {
+       &dev_attr_device.attr,
+       &dev_attr_nvm_authenticate.attr,
+@@ -340,6 +352,7 @@ static struct attribute *retimer_attrs[] = {
+ };
+ static const struct attribute_group retimer_group = {
++      .is_visible = retimer_is_visible,
+       .attrs = retimer_attrs,
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.6/udf-verify-inode-link-counts-before-performing-renam.patch b/queue-6.6/udf-verify-inode-link-counts-before-performing-renam.patch
new file mode 100644 (file)
index 0000000..2dc3e98
--- /dev/null
@@ -0,0 +1,47 @@
+From 38e7b6d3ef558f9dcbb437d094ee2efc9fa2b784 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Nov 2024 12:55:12 +0100
+Subject: udf: Verify inode link counts before performing rename
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 6756af923e06aa33ad8894aaecbf9060953ba00f ]
+
+During rename, we are updating link counts of various inodes either when
+rename deletes target or when moving directory across directories.
+Verify involved link counts are sane so that we don't trip warnings in
+VFS.
+
+Reported-by: syzbot+3ff7365dc04a6bcafa66@syzkaller.appspotmail.com
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/udf/namei.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/fs/udf/namei.c b/fs/udf/namei.c
+index 0461a7b1e9b4..8ac73f41d6eb 100644
+--- a/fs/udf/namei.c
++++ b/fs/udf/namei.c
+@@ -792,8 +792,18 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir,
+                       retval = -ENOTEMPTY;
+                       if (!empty_dir(new_inode))
+                               goto out_oiter;
++                      retval = -EFSCORRUPTED;
++                      if (new_inode->i_nlink != 2)
++                              goto out_oiter;
+               }
++              retval = -EFSCORRUPTED;
++              if (old_dir->i_nlink < 3)
++                      goto out_oiter;
+               is_dir = true;
++      } else if (new_inode) {
++              retval = -EFSCORRUPTED;
++              if (new_inode->i_nlink < 1)
++                      goto out_oiter;
+       }
+       if (is_dir && old_dir != new_dir) {
+               retval = udf_fiiter_find_entry(old_inode, &dotdot_name,
+-- 
+2.39.5
+
diff --git a/queue-6.6/udf_rename-only-access-the-child-content-on-cross-di.patch b/queue-6.6/udf_rename-only-access-the-child-content-on-cross-di.patch
new file mode 100644 (file)
index 0000000..3386c46
--- /dev/null
@@ -0,0 +1,61 @@
+From 29df5c14514fcefbda1046b60119bf5d6b3119e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Oct 2023 14:44:23 -0400
+Subject: udf_rename(): only access the child content on cross-directory rename
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+[ Upstream commit 9d35cebb794bb7be93db76c3383979c7deacfef9 ]
+
+We can't really afford locking the source on same-directory rename;
+currently vfs_rename() tries to do that, but it will have to be
+changed.  The logics in udf_rename() is lazy and goes looking for
+".." in source even in same-directory case.  It's not hard to get
+rid of that, leaving that behaviour only for cross-directory case;
+that VFS can get locks safely (and will keep doing that after the
+coming changes).
+
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Stable-dep-of: 6756af923e06 ("udf: Verify inode link counts before performing rename")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/udf/namei.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/fs/udf/namei.c b/fs/udf/namei.c
+index b3f57ad2b869..0461a7b1e9b4 100644
+--- a/fs/udf/namei.c
++++ b/fs/udf/namei.c
+@@ -770,7 +770,7 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir,
+       struct inode *old_inode = d_inode(old_dentry);
+       struct inode *new_inode = d_inode(new_dentry);
+       struct udf_fileident_iter oiter, niter, diriter;
+-      bool has_diriter = false;
++      bool has_diriter = false, is_dir = false;
+       int retval;
+       struct kernel_lb_addr tloc;
+@@ -793,6 +793,9 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir,
+                       if (!empty_dir(new_inode))
+                               goto out_oiter;
+               }
++              is_dir = true;
++      }
++      if (is_dir && old_dir != new_dir) {
+               retval = udf_fiiter_find_entry(old_inode, &dotdot_name,
+                                              &diriter);
+               if (retval == -ENOENT) {
+@@ -880,7 +883,9 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir,
+                                       cpu_to_lelb(UDF_I(new_dir)->i_location);
+               udf_fiiter_write_fi(&diriter, NULL);
+               udf_fiiter_release(&diriter);
++      }
++      if (is_dir) {
+               inode_dec_link_count(old_dir);
+               if (new_inode)
+                       inode_dec_link_count(new_inode);
+-- 
+2.39.5
+
diff --git a/queue-6.6/usb-chipidea-add-ci_hdrc_force_vbus_active_always-fl.patch b/queue-6.6/usb-chipidea-add-ci_hdrc_force_vbus_active_always-fl.patch
new file mode 100644 (file)
index 0000000..62d8183
--- /dev/null
@@ -0,0 +1,56 @@
+From a4b96dd91bf254d63e2084e6c31c207c261a2bdb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Oct 2023 22:59:01 +0300
+Subject: usb: chipidea: add CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS flag
+
+From: Tomer Maimon <tmaimon77@gmail.com>
+
+[ Upstream commit 2978cc1f285390c1bd4d9bfc665747adc6e4b19c ]
+
+Adding CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS flag to modify the vbus_active
+parameter to active in case the ChipIdea USB IP role is device-only and
+there is no otgsc register.
+
+Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Link: https://lore.kernel.org/r/20231017195903.1665260-2-tmaimon77@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: ec841b8d73cf ("usb: chipidea: add CI_HDRC_HAS_SHORT_PKT_LIMIT flag")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/chipidea/otg.c   | 5 ++++-
+ include/linux/usb/chipidea.h | 1 +
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
+index f5490f2a5b6b..647e98f4e351 100644
+--- a/drivers/usb/chipidea/otg.c
++++ b/drivers/usb/chipidea/otg.c
+@@ -130,8 +130,11 @@ enum ci_role ci_otg_role(struct ci_hdrc *ci)
+ void ci_handle_vbus_change(struct ci_hdrc *ci)
+ {
+-      if (!ci->is_otg)
++      if (!ci->is_otg) {
++              if (ci->platdata->flags & CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS)
++                      usb_gadget_vbus_connect(&ci->gadget);
+               return;
++      }
+       if (hw_read_otgsc(ci, OTGSC_BSV) && !ci->vbus_active)
+               usb_gadget_vbus_connect(&ci->gadget);
+diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
+index 0b4f2d5faa08..5a7f96684ea2 100644
+--- a/include/linux/usb/chipidea.h
++++ b/include/linux/usb/chipidea.h
+@@ -64,6 +64,7 @@ struct ci_hdrc_platform_data {
+ #define CI_HDRC_PMQOS                 BIT(15)
+ #define CI_HDRC_PHY_VBUS_CONTROL      BIT(16)
+ #define CI_HDRC_HAS_PORTSC_PEC_MISSED BIT(17)
++#define CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS      BIT(18)
+       enum usb_dr_mode        dr_mode;
+ #define CI_HDRC_CONTROLLER_RESET_EVENT                0
+ #define CI_HDRC_CONTROLLER_STOPPED_EVENT      1
+-- 
+2.39.5
+
diff --git a/queue-6.6/usb-chipidea-add-ci_hdrc_has_short_pkt_limit-flag.patch b/queue-6.6/usb-chipidea-add-ci_hdrc_has_short_pkt_limit-flag.patch
new file mode 100644 (file)
index 0000000..6cd33c1
--- /dev/null
@@ -0,0 +1,90 @@
+From 3c006c4a9edd0b45f89187cf1d716a6c20d6e5c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Sep 2024 16:12:01 +0800
+Subject: usb: chipidea: add CI_HDRC_HAS_SHORT_PKT_LIMIT flag
+
+From: Xu Yang <xu.yang_2@nxp.com>
+
+[ Upstream commit ec841b8d73cff37f8960e209017efe1eb2fb21f2 ]
+
+Currently, the imx deivice controller has below limitations:
+
+1. can't generate short packet interrupt if IOC not set in dTD. So if one
+   request span more than one dTDs and only the last dTD set IOC, the usb
+   request will pending there if no more data comes.
+2. the controller can't accurately deliver data to differtent usb requests
+   in some cases due to short packet. For example: one usb request span 3
+   dTDs, then if the controller received a short packet the next packet
+   will go to 2nd dTD of current request rather than the first dTD of next
+   request.
+3. can't build a bus packet use multiple dTDs. For example: controller
+   needs to send one packet of 512 bytes use dTD1 (200 bytes) + dTD2
+   (312 bytes), actually the host side will see 200 bytes short packet.
+
+Based on these limits, add CI_HDRC_HAS_SHORT_PKT_LIMIT flag and use it on
+imx platforms.
+
+Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Link: https://lore.kernel.org/r/20240923081203.2851768-1-xu.yang_2@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/chipidea/ci.h          | 1 +
+ drivers/usb/chipidea/ci_hdrc_imx.c | 1 +
+ drivers/usb/chipidea/core.c        | 2 ++
+ include/linux/usb/chipidea.h       | 1 +
+ 4 files changed, 5 insertions(+)
+
+diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
+index 2a38e1eb6546..e4b003d060c2 100644
+--- a/drivers/usb/chipidea/ci.h
++++ b/drivers/usb/chipidea/ci.h
+@@ -260,6 +260,7 @@ struct ci_hdrc {
+       bool                            b_sess_valid_event;
+       bool                            imx28_write_fix;
+       bool                            has_portsc_pec_bug;
++      bool                            has_short_pkt_limit;
+       bool                            supports_runtime_pm;
+       bool                            in_lpm;
+       bool                            wakeup_int;
+diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
+index e28bb2f2612d..477af457c1a1 100644
+--- a/drivers/usb/chipidea/ci_hdrc_imx.c
++++ b/drivers/usb/chipidea/ci_hdrc_imx.c
+@@ -334,6 +334,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
+       struct ci_hdrc_platform_data pdata = {
+               .name           = dev_name(&pdev->dev),
+               .capoffset      = DEF_CAPOFFSET,
++              .flags          = CI_HDRC_HAS_SHORT_PKT_LIMIT,
+               .notify_event   = ci_hdrc_imx_notify_event,
+       };
+       int ret;
+diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
+index ca71df4f32e4..c161a4ee5290 100644
+--- a/drivers/usb/chipidea/core.c
++++ b/drivers/usb/chipidea/core.c
+@@ -1076,6 +1076,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)
+               CI_HDRC_SUPPORTS_RUNTIME_PM);
+       ci->has_portsc_pec_bug = !!(ci->platdata->flags &
+               CI_HDRC_HAS_PORTSC_PEC_MISSED);
++      ci->has_short_pkt_limit = !!(ci->platdata->flags &
++              CI_HDRC_HAS_SHORT_PKT_LIMIT);
+       platform_set_drvdata(pdev, ci);
+       ret = hw_device_init(ci, base);
+diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
+index 5a7f96684ea2..ebdfef124b2b 100644
+--- a/include/linux/usb/chipidea.h
++++ b/include/linux/usb/chipidea.h
+@@ -65,6 +65,7 @@ struct ci_hdrc_platform_data {
+ #define CI_HDRC_PHY_VBUS_CONTROL      BIT(16)
+ #define CI_HDRC_HAS_PORTSC_PEC_MISSED BIT(17)
+ #define CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS      BIT(18)
++#define       CI_HDRC_HAS_SHORT_PKT_LIMIT     BIT(19)
+       enum usb_dr_mode        dr_mode;
+ #define CI_HDRC_CONTROLLER_RESET_EVENT                0
+ #define CI_HDRC_CONTROLLER_STOPPED_EVENT      1
+-- 
+2.39.5
+
diff --git a/queue-6.6/usb-chipidea-udc-limit-usb-request-length-to-max-16k.patch b/queue-6.6/usb-chipidea-udc-limit-usb-request-length-to-max-16k.patch
new file mode 100644 (file)
index 0000000..951fe15
--- /dev/null
@@ -0,0 +1,58 @@
+From 3a2effe2072215a53d333ffca74fd3caf8a1a23b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Sep 2024 16:12:02 +0800
+Subject: usb: chipidea: udc: limit usb request length to max 16KB
+
+From: Xu Yang <xu.yang_2@nxp.com>
+
+[ Upstream commit ca8d18aa7b0f22d66a3ca9a90d8f73431b8eca89 ]
+
+To let the device controller work properly on short packet limitations,
+one usb request should only correspond to one dTD. Then every dTD will
+set IOC. In theory, each dTD support up to 20KB data transfer if the
+offset is 0. Due to we cannot predetermine the offset, this will limit
+the usb request length to max 16KB. This should be fine since most of
+the user transfer data based on this size policy.
+
+Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Link: https://lore.kernel.org/r/20240923081203.2851768-2-xu.yang_2@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/chipidea/ci.h  | 1 +
+ drivers/usb/chipidea/udc.c | 6 ++++++
+ 2 files changed, 7 insertions(+)
+
+diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
+index e4b003d060c2..97437de52ef6 100644
+--- a/drivers/usb/chipidea/ci.h
++++ b/drivers/usb/chipidea/ci.h
+@@ -25,6 +25,7 @@
+ #define TD_PAGE_COUNT      5
+ #define CI_HDRC_PAGE_SIZE  4096ul /* page size for TD's */
+ #define ENDPT_MAX          32
++#define CI_MAX_REQ_SIZE       (4 * CI_HDRC_PAGE_SIZE)
+ #define CI_MAX_BUF_SIZE       (TD_PAGE_COUNT * CI_HDRC_PAGE_SIZE)
+ /******************************************************************************
+diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
+index 9f7d003e467b..f2ae5f4c5828 100644
+--- a/drivers/usb/chipidea/udc.c
++++ b/drivers/usb/chipidea/udc.c
+@@ -959,6 +959,12 @@ static int _ep_queue(struct usb_ep *ep, struct usb_request *req,
+               return -EMSGSIZE;
+       }
++      if (ci->has_short_pkt_limit &&
++              hwreq->req.length > CI_MAX_REQ_SIZE) {
++              dev_err(hwep->ci->dev, "request length too big (max 16KB)\n");
++              return -EMSGSIZE;
++      }
++
+       /* first nuke then test link, e.g. previous status has not sent */
+       if (!list_empty(&hwreq->queue)) {
+               dev_err(hwep->ci->dev, "request already in queue\n");
+-- 
+2.39.5
+
diff --git a/queue-6.6/usb-dwc3-gadget-add-missing-check-for-single-port-ra.patch b/queue-6.6/usb-dwc3-gadget-add-missing-check-for-single-port-ra.patch
new file mode 100644 (file)
index 0000000..7a74f7b
--- /dev/null
@@ -0,0 +1,168 @@
+From b1f48b41c7dfb8ad06fdf37f2a118863125e4ab7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Nov 2024 10:18:02 +0530
+Subject: usb: dwc3: gadget: Add missing check for single port RAM in TxFIFO
+ resizing logic
+
+From: Selvarasu Ganesan <selvarasu.g@samsung.com>
+
+[ Upstream commit 61eb055cd3048ee01ca43d1be924167d33e16fdc ]
+
+The existing implementation of the TxFIFO resizing logic only supports
+scenarios where more than one port RAM is used. However, there is a need
+to resize the TxFIFO in USB2.0-only mode where only a single port RAM is
+available. This commit introduces the necessary changes to support
+TxFIFO resizing in such scenarios by adding a missing check for single
+port RAM.
+
+This fix addresses certain platform configurations where the existing
+TxFIFO resizing logic does not work properly due to the absence of
+support for single port RAM. By adding this missing check, we ensure
+that the TxFIFO resizing logic works correctly in all scenarios,
+including those with a single port RAM.
+
+Fixes: 9f607a309fbe ("usb: dwc3: Resize TX FIFOs to meet EP bursting requirements")
+Cc: stable@vger.kernel.org # 6.12.x: fad16c82: usb: dwc3: gadget: Refine the logic for resizing Tx FIFOs
+Signed-off-by: Selvarasu Ganesan <selvarasu.g@samsung.com>
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/20241112044807.623-1-selvarasu.g@samsung.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/core.h   |  4 +++
+ drivers/usb/dwc3/gadget.c | 54 +++++++++++++++++++++++++++++++++------
+ 2 files changed, 50 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
+index b118f4aab189..d00bf714a7cc 100644
+--- a/drivers/usb/dwc3/core.h
++++ b/drivers/usb/dwc3/core.h
+@@ -899,6 +899,7 @@ struct dwc3_hwparams {
+ #define DWC3_MODE(n)          ((n) & 0x7)
+ /* HWPARAMS1 */
++#define DWC3_SPRAM_TYPE(n)    (((n) >> 23) & 1)
+ #define DWC3_NUM_INT(n)               (((n) & (0x3f << 15)) >> 15)
+ /* HWPARAMS3 */
+@@ -909,6 +910,9 @@ struct dwc3_hwparams {
+ #define DWC3_NUM_IN_EPS(p)    (((p)->hwparams3 &              \
+                       (DWC3_NUM_IN_EPS_MASK)) >> 18)
++/* HWPARAMS6 */
++#define DWC3_RAM0_DEPTH(n)    (((n) & (0xffff0000)) >> 16)
++
+ /* HWPARAMS7 */
+ #define DWC3_RAM1_DEPTH(n)    ((n) & 0xffff)
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index b560996bd421..656460c0c1dd 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -687,6 +687,44 @@ static int dwc3_gadget_calc_tx_fifo_size(struct dwc3 *dwc, int mult)
+       return fifo_size;
+ }
++/**
++ * dwc3_gadget_calc_ram_depth - calculates the ram depth for txfifo
++ * @dwc: pointer to the DWC3 context
++ */
++static int dwc3_gadget_calc_ram_depth(struct dwc3 *dwc)
++{
++      int ram_depth;
++      int fifo_0_start;
++      bool is_single_port_ram;
++
++      /* Check supporting RAM type by HW */
++      is_single_port_ram = DWC3_SPRAM_TYPE(dwc->hwparams.hwparams1);
++
++      /*
++       * If a single port RAM is utilized, then allocate TxFIFOs from
++       * RAM0. otherwise, allocate them from RAM1.
++       */
++      ram_depth = is_single_port_ram ? DWC3_RAM0_DEPTH(dwc->hwparams.hwparams6) :
++                      DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7);
++
++      /*
++       * In a single port RAM configuration, the available RAM is shared
++       * between the RX and TX FIFOs. This means that the txfifo can begin
++       * at a non-zero address.
++       */
++      if (is_single_port_ram) {
++              u32 reg;
++
++              /* Check if TXFIFOs start at non-zero addr */
++              reg = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(0));
++              fifo_0_start = DWC3_GTXFIFOSIZ_TXFSTADDR(reg);
++
++              ram_depth -= (fifo_0_start >> 16);
++      }
++
++      return ram_depth;
++}
++
+ /**
+  * dwc3_gadget_clear_tx_fifos - Clears txfifo allocation
+  * @dwc: pointer to the DWC3 context
+@@ -753,7 +791,7 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep)
+ {
+       struct dwc3 *dwc = dep->dwc;
+       int fifo_0_start;
+-      int ram1_depth;
++      int ram_depth;
+       int fifo_size;
+       int min_depth;
+       int num_in_ep;
+@@ -773,7 +811,7 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep)
+       if (dep->flags & DWC3_EP_TXFIFO_RESIZED)
+               return 0;
+-      ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7);
++      ram_depth = dwc3_gadget_calc_ram_depth(dwc);
+       if ((dep->endpoint.maxburst > 1 &&
+            usb_endpoint_xfer_bulk(dep->endpoint.desc)) ||
+@@ -794,7 +832,7 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep)
+       /* Reserve at least one FIFO for the number of IN EPs */
+       min_depth = num_in_ep * (fifo + 1);
+-      remaining = ram1_depth - min_depth - dwc->last_fifo_depth;
++      remaining = ram_depth - min_depth - dwc->last_fifo_depth;
+       remaining = max_t(int, 0, remaining);
+       /*
+        * We've already reserved 1 FIFO per EP, so check what we can fit in
+@@ -820,9 +858,9 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep)
+               dwc->last_fifo_depth += DWC31_GTXFIFOSIZ_TXFDEP(fifo_size);
+       /* Check fifo size allocation doesn't exceed available RAM size. */
+-      if (dwc->last_fifo_depth >= ram1_depth) {
++      if (dwc->last_fifo_depth >= ram_depth) {
+               dev_err(dwc->dev, "Fifosize(%d) > RAM size(%d) %s depth:%d\n",
+-                      dwc->last_fifo_depth, ram1_depth,
++                      dwc->last_fifo_depth, ram_depth,
+                       dep->endpoint.name, fifo_size);
+               if (DWC3_IP_IS(DWC3))
+                       fifo_size = DWC3_GTXFIFOSIZ_TXFDEP(fifo_size);
+@@ -3078,7 +3116,7 @@ static int dwc3_gadget_check_config(struct usb_gadget *g)
+       struct dwc3 *dwc = gadget_to_dwc(g);
+       struct usb_ep *ep;
+       int fifo_size = 0;
+-      int ram1_depth;
++      int ram_depth;
+       int ep_num = 0;
+       if (!dwc->do_fifo_resize)
+@@ -3101,8 +3139,8 @@ static int dwc3_gadget_check_config(struct usb_gadget *g)
+       fifo_size += dwc->max_cfg_eps;
+       /* Check if we can fit a single fifo per endpoint */
+-      ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7);
+-      if (fifo_size > ram1_depth)
++      ram_depth = dwc3_gadget_calc_ram_depth(dwc);
++      if (fifo_size > ram_depth)
+               return -ENOMEM;
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.6/usb-typec-ucsi-add-callback-for-connector-status-upd.patch b/queue-6.6/usb-typec-ucsi-add-callback-for-connector-status-upd.patch
new file mode 100644 (file)
index 0000000..edfaabb
--- /dev/null
@@ -0,0 +1,83 @@
+From 8e5fa2737d76d60b931b656b66b9c9c4cb7abb69 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Apr 2024 07:49:53 +0300
+Subject: usb: typec: ucsi: add callback for connector status updates
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 24bce22d09ec8e67022aab9a888acb56fb7a996a ]
+
+Allow UCSI glue driver to perform addtional work to update connector
+status. For example, it might check the cable orientation.  This call is
+performed after reading new connector statatus, so the platform driver
+can peek at new connection status bits.
+
+The callback is called both when registering the port and when the
+connector change event is being handled.
+
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20240411-ucsi-orient-aware-v2-1-d4b1cb22a33f@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: de9df030ccb5 ("usb: typec: ucsi: glink: be more precise on orientation-aware ports")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/ucsi/ucsi.c | 6 ++++++
+ drivers/usb/typec/ucsi/ucsi.h | 3 +++
+ 2 files changed, 9 insertions(+)
+
+diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
+index f6fb5575d4f0..3f7039a711c7 100644
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -903,6 +903,9 @@ static void ucsi_handle_connector_change(struct work_struct *work)
+       trace_ucsi_connector_change(con->num, &con->status);
++      if (ucsi->ops->connector_status)
++              ucsi->ops->connector_status(con);
++
+       role = !!(con->status.flags & UCSI_CONSTAT_PWR_DIR);
+       if (con->status.change & UCSI_CONSTAT_POWER_DIR_CHANGE) {
+@@ -1322,6 +1325,9 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con)
+       }
+       ret = 0; /* ucsi_send_command() returns length on success */
++      if (ucsi->ops->connector_status)
++              ucsi->ops->connector_status(con);
++
+       switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) {
+       case UCSI_CONSTAT_PARTNER_TYPE_UFP:
+       case UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP:
+diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
+index 42c60eba5fb6..3d23b52cf5a9 100644
+--- a/drivers/usb/typec/ucsi/ucsi.h
++++ b/drivers/usb/typec/ucsi/ucsi.h
+@@ -15,6 +15,7 @@
+ struct ucsi;
+ struct ucsi_altmode;
++struct ucsi_connector;
+ struct dentry;
+ /* UCSI offsets (Bytes) */
+@@ -52,6 +53,7 @@ struct dentry;
+  * @sync_write: Blocking write operation
+  * @async_write: Non-blocking write operation
+  * @update_altmodes: Squashes duplicate DP altmodes
++ * @connector_status: Updates connector status, called holding connector lock
+  *
+  * Read and write routines for UCSI interface. @sync_write must wait for the
+  * Command Completion Event from the PPM before returning, and @async_write must
+@@ -66,6 +68,7 @@ struct ucsi_operations {
+                          const void *val, size_t val_len);
+       bool (*update_altmodes)(struct ucsi *ucsi, struct ucsi_altmode *orig,
+                               struct ucsi_altmode *updated);
++      void (*connector_status)(struct ucsi_connector *con);
+ };
+ struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops);
+-- 
+2.39.5
+
diff --git a/queue-6.6/usb-typec-ucsi-add-update_connector-callback.patch b/queue-6.6/usb-typec-ucsi-add-update_connector-callback.patch
new file mode 100644 (file)
index 0000000..7706e18
--- /dev/null
@@ -0,0 +1,62 @@
+From fcc56dec86949c2b7f814f2de8a1e702cefee01d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Apr 2024 07:49:56 +0300
+Subject: usb: typec: ucsi: add update_connector callback
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 62866465196228917f233aea68de73be6cdb9fae ]
+
+Add a callback to allow glue drivers to update the connector before
+registering corresponding power supply and Type-C port. In particular
+this is useful if glue drivers want to touch the connector's Type-C
+capabilities structure.
+
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20240411-ucsi-orient-aware-v2-4-d4b1cb22a33f@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: de9df030ccb5 ("usb: typec: ucsi: glink: be more precise on orientation-aware ports")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/ucsi/ucsi.c | 3 +++
+ drivers/usb/typec/ucsi/ucsi.h | 2 ++
+ 2 files changed, 5 insertions(+)
+
+diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
+index 3f7039a711c7..d6a3fd00c3a5 100644
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -1261,6 +1261,9 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con)
+       cap->driver_data = con;
+       cap->ops = &ucsi_ops;
++      if (ucsi->ops->update_connector)
++              ucsi->ops->update_connector(con);
++
+       ret = ucsi_register_port_psy(con);
+       if (ret)
+               goto out;
+diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
+index 3d23b52cf5a9..921ef0e115cf 100644
+--- a/drivers/usb/typec/ucsi/ucsi.h
++++ b/drivers/usb/typec/ucsi/ucsi.h
+@@ -53,6 +53,7 @@ struct dentry;
+  * @sync_write: Blocking write operation
+  * @async_write: Non-blocking write operation
+  * @update_altmodes: Squashes duplicate DP altmodes
++ * @update_connector: Update connector capabilities before registering
+  * @connector_status: Updates connector status, called holding connector lock
+  *
+  * Read and write routines for UCSI interface. @sync_write must wait for the
+@@ -68,6 +69,7 @@ struct ucsi_operations {
+                          const void *val, size_t val_len);
+       bool (*update_altmodes)(struct ucsi *ucsi, struct ucsi_altmode *orig,
+                               struct ucsi_altmode *updated);
++      void (*update_connector)(struct ucsi_connector *con);
+       void (*connector_status)(struct ucsi_connector *con);
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.6/usb-typec-ucsi-glink-be-more-precise-on-orientation-.patch b/queue-6.6/usb-typec-ucsi-glink-be-more-precise-on-orientation-.patch
new file mode 100644 (file)
index 0000000..2ed7927
--- /dev/null
@@ -0,0 +1,52 @@
+From dd216decafb23ae9a0497b94d65914afdd7de392 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 9 Nov 2024 02:04:15 +0200
+Subject: usb: typec: ucsi: glink: be more precise on orientation-aware ports
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit de9df030ccb5d3e31ee0c715d74cd77c619748f8 ]
+
+Instead of checking if any of the USB-C ports have orientation GPIO and
+thus is orientation-aware, check for the GPIO for the port being
+registered. There are no boards that are affected by this change at this
+moment, so the patch is not marked as a fix, but it might affect other
+boards in future.
+
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
+Tested-by: Johan Hovold <johan+linaro@kernel.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20241109-ucsi-glue-fixes-v2-2-8b21ff4f9fbe@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/ucsi/ucsi_glink.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c
+index f6c3af5846e6..f0b4d0a4bb19 100644
+--- a/drivers/usb/typec/ucsi/ucsi_glink.c
++++ b/drivers/usb/typec/ucsi/ucsi_glink.c
+@@ -189,12 +189,12 @@ static int pmic_glink_ucsi_sync_write(struct ucsi *__ucsi, unsigned int offset,
+ static void pmic_glink_ucsi_update_connector(struct ucsi_connector *con)
+ {
+       struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(con->ucsi);
+-      int i;
+-      for (i = 0; i < PMIC_GLINK_MAX_PORTS; i++) {
+-              if (ucsi->port_orientation[i])
+-                      con->typec_cap.orientation_aware = true;
+-      }
++      if (con->num > PMIC_GLINK_MAX_PORTS ||
++          !ucsi->port_orientation[con->num - 1])
++              return;
++
++      con->typec_cap.orientation_aware = true;
+ }
+ static void pmic_glink_ucsi_connector_status(struct ucsi_connector *con)
+-- 
+2.39.5
+
diff --git a/queue-6.6/usb-typec-ucsi-glink-fix-off-by-one-in-connector_sta.patch b/queue-6.6/usb-typec-ucsi-glink-fix-off-by-one-in-connector_sta.patch
new file mode 100644 (file)
index 0000000..09238a1
--- /dev/null
@@ -0,0 +1,44 @@
+From a133c18476098231cc3f082a93437920cc6dde7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 9 Nov 2024 02:04:14 +0200
+Subject: usb: typec: ucsi: glink: fix off-by-one in connector_status
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 4a22918810980897393fa1776ea3877e4baf8cca ]
+
+UCSI connector's indices start from 1 up to 3, PMIC_GLINK_MAX_PORTS.
+Correct the condition in the pmic_glink_ucsi_connector_status()
+callback, fixing Type-C orientation reporting for the third USB-C
+connector.
+
+Fixes: 76716fd5bf09 ("usb: typec: ucsi: glink: move GPIO reading into connector_status callback")
+Cc: stable@vger.kernel.org
+Reported-by: Abel Vesa <abel.vesa@linaro.org>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
+Tested-by: Johan Hovold <johan+linaro@kernel.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20241109-ucsi-glue-fixes-v2-1-8b21ff4f9fbe@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/ucsi/ucsi_glink.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c
+index f0b4d0a4bb19..82a1081d44f1 100644
+--- a/drivers/usb/typec/ucsi/ucsi_glink.c
++++ b/drivers/usb/typec/ucsi/ucsi_glink.c
+@@ -202,7 +202,7 @@ static void pmic_glink_ucsi_connector_status(struct ucsi_connector *con)
+       struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(con->ucsi);
+       int orientation;
+-      if (con->num >= PMIC_GLINK_MAX_PORTS ||
++      if (con->num > PMIC_GLINK_MAX_PORTS ||
+           !ucsi->port_orientation[con->num - 1])
+               return;
+-- 
+2.39.5
+
diff --git a/queue-6.6/usb-typec-ucsi-glink-move-gpio-reading-into-connecto.patch b/queue-6.6/usb-typec-ucsi-glink-move-gpio-reading-into-connecto.patch
new file mode 100644 (file)
index 0000000..215068a
--- /dev/null
@@ -0,0 +1,109 @@
+From c05054d97d08da8259a5d3186d28823b5893db92 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Apr 2024 07:49:54 +0300
+Subject: usb: typec: ucsi: glink: move GPIO reading into connector_status
+ callback
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 76716fd5bf09725c2c6825264147f16c21e56853 ]
+
+To simplify the platform code move Type-C orientation handling into the
+connector_status callback. As it is called both during connector
+registration and on connector change events, duplicated code from
+pmic_glink_ucsi_register() can be dropped.
+
+Also this moves operations that can sleep into a worker thread,
+removing the only sleeping operation from pmic_glink_ucsi_notify().
+
+Tested-by: Krishna Kurapati <quic_kriskura@quicinc.com>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Heikki Krogerus <heikki.krogeurs@linux.intel.com>
+Link: https://lore.kernel.org/r/20240411-ucsi-orient-aware-v2-2-d4b1cb22a33f@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: de9df030ccb5 ("usb: typec: ucsi: glink: be more precise on orientation-aware ports")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/ucsi/ucsi_glink.c | 48 ++++++++++++-----------------
+ 1 file changed, 20 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c
+index 94f2df02f06e..4c9352cdd641 100644
+--- a/drivers/usb/typec/ucsi/ucsi_glink.c
++++ b/drivers/usb/typec/ucsi/ucsi_glink.c
+@@ -186,10 +186,28 @@ static int pmic_glink_ucsi_sync_write(struct ucsi *__ucsi, unsigned int offset,
+       return ret;
+ }
++static void pmic_glink_ucsi_connector_status(struct ucsi_connector *con)
++{
++      struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(con->ucsi);
++      int orientation;
++
++      if (con->num >= PMIC_GLINK_MAX_PORTS ||
++          !ucsi->port_orientation[con->num - 1])
++              return;
++
++      orientation = gpiod_get_value(ucsi->port_orientation[con->num - 1]);
++      if (orientation >= 0) {
++              typec_switch_set(ucsi->port_switch[con->num - 1],
++                               orientation ? TYPEC_ORIENTATION_REVERSE
++                               : TYPEC_ORIENTATION_NORMAL);
++      }
++}
++
+ static const struct ucsi_operations pmic_glink_ucsi_ops = {
+       .read = pmic_glink_ucsi_read,
+       .sync_write = pmic_glink_ucsi_sync_write,
+-      .async_write = pmic_glink_ucsi_async_write
++      .async_write = pmic_glink_ucsi_async_write,
++      .connector_status = pmic_glink_ucsi_connector_status,
+ };
+ static void pmic_glink_ucsi_read_ack(struct pmic_glink_ucsi *ucsi, const void *data, int len)
+@@ -228,20 +246,8 @@ static void pmic_glink_ucsi_notify(struct work_struct *work)
+       }
+       con_num = UCSI_CCI_CONNECTOR(cci);
+-      if (con_num) {
+-              if (con_num <= PMIC_GLINK_MAX_PORTS &&
+-                  ucsi->port_orientation[con_num - 1]) {
+-                      int orientation = gpiod_get_value(ucsi->port_orientation[con_num - 1]);
+-
+-                      if (orientation >= 0) {
+-                              typec_switch_set(ucsi->port_switch[con_num - 1],
+-                                               orientation ? TYPEC_ORIENTATION_REVERSE
+-                                                           : TYPEC_ORIENTATION_NORMAL);
+-                      }
+-              }
+-
++      if (con_num)
+               ucsi_connector_change(ucsi->ucsi, con_num);
+-      }
+       if (ucsi->sync_pending &&
+                  (cci & (UCSI_CCI_ACK_COMPLETE | UCSI_CCI_COMMAND_COMPLETE))) {
+@@ -252,20 +258,6 @@ static void pmic_glink_ucsi_notify(struct work_struct *work)
+ static void pmic_glink_ucsi_register(struct work_struct *work)
+ {
+       struct pmic_glink_ucsi *ucsi = container_of(work, struct pmic_glink_ucsi, register_work);
+-      int orientation;
+-      int i;
+-
+-      for (i = 0; i < PMIC_GLINK_MAX_PORTS; i++) {
+-              if (!ucsi->port_orientation[i])
+-                      continue;
+-              orientation = gpiod_get_value(ucsi->port_orientation[i]);
+-
+-              if (orientation >= 0) {
+-                      typec_switch_set(ucsi->port_switch[i],
+-                                       orientation ? TYPEC_ORIENTATION_REVERSE
+-                                           : TYPEC_ORIENTATION_NORMAL);
+-              }
+-      }
+       ucsi_register(ucsi->ucsi);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.6/usb-typec-ucsi-glink-set-orientation-aware-if-suppor.patch b/queue-6.6/usb-typec-ucsi-glink-set-orientation-aware-if-suppor.patch
new file mode 100644 (file)
index 0000000..95f3231
--- /dev/null
@@ -0,0 +1,56 @@
+From abc9a5d8ff267d55496034a70e7f0becbe2440f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Apr 2024 07:49:57 +0300
+Subject: usb: typec: ucsi: glink: set orientation aware if supported
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 3d1b6c9d47707d6a0f80bb5db6473b1f107b5baf ]
+
+If the PMIC-GLINK device has orientation GPIOs declared, then it will
+report connection orientation. In this case set the flag to mark
+registered ports as orientation-aware.
+
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20240411-ucsi-orient-aware-v2-5-d4b1cb22a33f@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: de9df030ccb5 ("usb: typec: ucsi: glink: be more precise on orientation-aware ports")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/ucsi/ucsi_glink.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c
+index 4c9352cdd641..f6c3af5846e6 100644
+--- a/drivers/usb/typec/ucsi/ucsi_glink.c
++++ b/drivers/usb/typec/ucsi/ucsi_glink.c
+@@ -186,6 +186,17 @@ static int pmic_glink_ucsi_sync_write(struct ucsi *__ucsi, unsigned int offset,
+       return ret;
+ }
++static void pmic_glink_ucsi_update_connector(struct ucsi_connector *con)
++{
++      struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(con->ucsi);
++      int i;
++
++      for (i = 0; i < PMIC_GLINK_MAX_PORTS; i++) {
++              if (ucsi->port_orientation[i])
++                      con->typec_cap.orientation_aware = true;
++      }
++}
++
+ static void pmic_glink_ucsi_connector_status(struct ucsi_connector *con)
+ {
+       struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(con->ucsi);
+@@ -207,6 +218,7 @@ static const struct ucsi_operations pmic_glink_ucsi_ops = {
+       .read = pmic_glink_ucsi_read,
+       .sync_write = pmic_glink_ucsi_sync_write,
+       .async_write = pmic_glink_ucsi_async_write,
++      .update_connector = pmic_glink_ucsi_update_connector,
+       .connector_status = pmic_glink_ucsi_connector_status,
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.6/usb-xhci-avoid-queuing-redundant-stop-endpoint-comma.patch b/queue-6.6/usb-xhci-avoid-queuing-redundant-stop-endpoint-comma.patch
new file mode 100644 (file)
index 0000000..7c025de
--- /dev/null
@@ -0,0 +1,121 @@
+From 5491cfddbc5c9c312ad1b1002c58ca0dc8ea33be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Nov 2024 12:14:59 +0200
+Subject: usb: xhci: Avoid queuing redundant Stop Endpoint commands
+
+From: Michal Pecio <michal.pecio@gmail.com>
+
+[ Upstream commit 474538b8dd1cd9c666e56cfe8ef60fbb0fb513f4 ]
+
+Stop Endpoint command on an already stopped endpoint fails and may be
+misinterpreted as a known hardware bug by the completion handler. This
+results in an unnecessary delay with repeated retries of the command.
+
+Avoid queuing this command when endpoint state flags indicate that it's
+stopped or halted and the command will fail. If commands are pending on
+the endpoint, their completion handlers will process cancelled TDs so
+it's done. In case of waiting for external operations like clearing TT
+buffer, the endpoint is stopped and cancelled TDs can be processed now.
+
+This eliminates practically all unnecessary retries because an endpoint
+with pending URBs is maintained in Running state by the driver, unless
+aforementioned commands or other operations are pending on it. This is
+guaranteed by xhci_ring_ep_doorbell() and by the fact that it is called
+every time any of those operations completes.
+
+The only known exceptions are hardware bugs (the endpoint never starts
+at all) and Stream Protocol errors not associated with any TRB, which
+cause an endpoint reset not followed by restart. Sounds like a bug.
+
+Generally, these retries are only expected to happen when the endpoint
+fails to start for unknown/no reason, which is a worse problem itself,
+and fixing the bug eliminates the retries too.
+
+All cases were tested and found to work as expected. SET_DEQ_PENDING
+was produced by patching uvcvideo to unlink URBs in 100us intervals,
+which then runs into this case very often. EP_HALTED was produced by
+restarting 'cat /dev/ttyUSB0' on a serial dongle with broken cable.
+EP_CLEARING_TT by the same, with the dongle on an external hub.
+
+Fixes: fd9d55d190c0 ("xhci: retry Stop Endpoint on buggy NEC controllers")
+CC: stable@vger.kernel.org
+Signed-off-by: Michal Pecio <michal.pecio@gmail.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20241106101459.775897-34-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-ring.c | 13 +++++++++++++
+ drivers/usb/host/xhci.c      | 19 +++++++++++++++----
+ drivers/usb/host/xhci.h      |  1 +
+ 3 files changed, 29 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index 729319d81753..0d628af5c3ba 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1092,6 +1092,19 @@ static int xhci_invalidate_cancelled_tds(struct xhci_virt_ep *ep)
+       return 0;
+ }
++/*
++ * Erase queued TDs from transfer ring(s) and give back those the xHC didn't
++ * stop on. If necessary, queue commands to move the xHC off cancelled TDs it
++ * stopped on. Those will be given back later when the commands complete.
++ *
++ * Call under xhci->lock on a stopped endpoint.
++ */
++void xhci_process_cancelled_tds(struct xhci_virt_ep *ep)
++{
++      xhci_invalidate_cancelled_tds(ep);
++      xhci_giveback_invalidated_tds(ep);
++}
++
+ /*
+  * Returns the TD the endpoint ring halted on.
+  * Only call for non-running rings without streams.
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
+index 0b3688478ed3..70e6c240a540 100644
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -1738,10 +1738,21 @@ static int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+               }
+       }
+-      /* Queue a stop endpoint command, but only if this is
+-       * the first cancellation to be handled.
+-       */
+-      if (!(ep->ep_state & EP_STOP_CMD_PENDING)) {
++      /* These completion handlers will sort out cancelled TDs for us */
++      if (ep->ep_state & (EP_STOP_CMD_PENDING | EP_HALTED | SET_DEQ_PENDING)) {
++              xhci_dbg(xhci, "Not queuing Stop Endpoint on slot %d ep %d in state 0x%x\n",
++                              urb->dev->slot_id, ep_index, ep->ep_state);
++              goto done;
++      }
++
++      /* In this case no commands are pending but the endpoint is stopped */
++      if (ep->ep_state & EP_CLEARING_TT) {
++              /* and cancelled TDs can be given back right away */
++              xhci_dbg(xhci, "Invalidating TDs instantly on slot %d ep %d in state 0x%x\n",
++                              urb->dev->slot_id, ep_index, ep->ep_state);
++              xhci_process_cancelled_tds(ep);
++      } else {
++              /* Otherwise, queue a new Stop Endpoint command */
+               command = xhci_alloc_command(xhci, false, GFP_ATOMIC);
+               if (!command) {
+                       ret = -ENOMEM;
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index d89010ac5f8a..fddb3a90dae3 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1952,6 +1952,7 @@ void xhci_ring_doorbell_for_active_rings(struct xhci_hcd *xhci,
+ void xhci_cleanup_command_queue(struct xhci_hcd *xhci);
+ void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring);
+ unsigned int count_trbs(u64 addr, u64 len);
++void xhci_process_cancelled_tds(struct xhci_virt_ep *ep);
+ /* xHCI roothub code */
+ void xhci_set_link_state(struct xhci_hcd *xhci, struct xhci_port *port,
+-- 
+2.39.5
+
diff --git a/queue-6.6/usb-xhci-limit-stop-endpoint-retries.patch b/queue-6.6/usb-xhci-limit-stop-endpoint-retries.patch
new file mode 100644 (file)
index 0000000..25d834e
--- /dev/null
@@ -0,0 +1,149 @@
+From 67f640fbd282d84cc56e34072d5e30b93771e62c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Nov 2024 12:14:57 +0200
+Subject: usb: xhci: Limit Stop Endpoint retries
+
+From: Michal Pecio <michal.pecio@gmail.com>
+
+[ Upstream commit 42b7581376015c1bbcbe5831f043cd0ac119d028 ]
+
+Some host controllers fail to atomically transition an endpoint to the
+Running state on a doorbell ring and enter a hidden "Restarting" state,
+which looks very much like Stopped, with the important difference that
+it will spontaneously transition to Running anytime soon.
+
+A Stop Endpoint command queued in the Restarting state typically fails
+with Context State Error and the completion handler sees the Endpoint
+Context State as either still Stopped or already Running. Even a case
+of Halted was observed, when an error occurred right after the restart.
+
+The Halted state is already recovered from by resetting the endpoint.
+The Running state is handled by retrying Stop Endpoint.
+
+The Stopped state was recognized as a problem on NEC controllers and
+worked around also by retrying, because the endpoint soon restarts and
+then stops for good. But there is a risk: the command may fail if the
+endpoint is "stopped for good" already, and retries will fail forever.
+
+The possibility of this was not realized at the time, but a number of
+cases were discovered later and reproduced. Some proved difficult to
+deal with, and it is outright impossible to predict if an endpoint may
+fail to ever start at all due to a hardware bug. One such bug (albeit
+on ASM3142, not on NEC) was found to be reliably triggered simply by
+toggling an AX88179 NIC up/down in a tight loop for a few seconds.
+
+An endless retries storm is quite nasty. Besides putting needless load
+on the xHC and CPU, it causes URBs never to be given back, paralyzing
+the device and connection/disconnection logic for the whole bus if the
+device is unplugged. User processes waiting for URBs become unkillable,
+drivers and kworker threads lock up and xhci_hcd cannot be reloaded.
+
+For peace of mind, impose a timeout on Stop Endpoint retries in this
+case. If they don't succeed in 100ms, consider the endpoint stopped
+permanently for some reason and just give back the unlinked URBs. This
+failure case is rare already and work is under way to make it rarer.
+
+Start this work today by also handling one simple case of race with
+Reset Endpoint, because it costs just two lines to implement.
+
+Fixes: fd9d55d190c0 ("xhci: retry Stop Endpoint on buggy NEC controllers")
+CC: stable@vger.kernel.org
+Signed-off-by: Michal Pecio <michal.pecio@gmail.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20241106101459.775897-32-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: e21ebe51af68 ("xhci: Turn NEC specific quirk for handling Stop Endpoint errors generic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-ring.c | 28 ++++++++++++++++++++++++----
+ drivers/usb/host/xhci.c      |  2 ++
+ drivers/usb/host/xhci.h      |  1 +
+ 3 files changed, 27 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index 7c3e39482834..d318310e3135 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -52,6 +52,7 @@
+  *   endpoint rings; it generates events on the event ring for these.
+  */
++#include <linux/jiffies.h>
+ #include <linux/scatterlist.h>
+ #include <linux/slab.h>
+ #include <linux/dma-mapping.h>
+@@ -1182,16 +1183,35 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
+                       return;
+               case EP_STATE_STOPPED:
+                       /*
+-                       * NEC uPD720200 sometimes sets this state and fails with
+-                       * Context Error while continuing to process TRBs.
+-                       * Be conservative and trust EP_CTX_STATE on other chips.
++                       * Per xHCI 4.6.9, Stop Endpoint command on a Stopped
++                       * EP is a Context State Error, and EP stays Stopped.
++                       *
++                       * But maybe it failed on Halted, and somebody ran Reset
++                       * Endpoint later. EP state is now Stopped and EP_HALTED
++                       * still set because Reset EP handler will run after us.
++                       */
++                      if (ep->ep_state & EP_HALTED)
++                              break;
++                      /*
++                       * On some HCs EP state remains Stopped for some tens of
++                       * us to a few ms or more after a doorbell ring, and any
++                       * new Stop Endpoint fails without aborting the restart.
++                       * This handler may run quickly enough to still see this
++                       * Stopped state, but it will soon change to Running.
++                       *
++                       * Assume this bug on unexpected Stop Endpoint failures.
++                       * Keep retrying until the EP starts and stops again, on
++                       * chips where this is known to help. Wait for 100ms.
+                        */
+                       if (!(xhci->quirks & XHCI_NEC_HOST))
+                               break;
++                      if (time_is_before_jiffies(ep->stop_time + msecs_to_jiffies(100)))
++                              break;
+                       fallthrough;
+               case EP_STATE_RUNNING:
+                       /* Race, HW handled stop ep cmd before ep was running */
+-                      xhci_dbg(xhci, "Stop ep completion ctx error, ep is running\n");
++                      xhci_dbg(xhci, "Stop ep completion ctx error, ctx_state %d\n",
++                                      GET_EP_CTX_STATE(ep_ctx));
+                       command = xhci_alloc_command(xhci, false, GFP_ATOMIC);
+                       if (!command) {
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
+index 3bd70e6ad64b..0b3688478ed3 100644
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -8,6 +8,7 @@
+  * Some code borrowed from the Linux EHCI driver.
+  */
++#include <linux/jiffies.h>
+ #include <linux/pci.h>
+ #include <linux/iommu.h>
+ #include <linux/iopoll.h>
+@@ -1746,6 +1747,7 @@ static int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+                       ret = -ENOMEM;
+                       goto done;
+               }
++              ep->stop_time = jiffies;
+               ep->ep_state |= EP_STOP_CMD_PENDING;
+               xhci_queue_stop_endpoint(xhci, command, urb->dev->slot_id,
+                                        ep_index, 0);
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index 4bbd12db7239..d89010ac5f8a 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -717,6 +717,7 @@ struct xhci_virt_ep {
+       /* Bandwidth checking storage */
+       struct xhci_bw_info     bw_info;
+       struct list_head        bw_endpoint_list;
++      unsigned long           stop_time;
+       /* Isoch Frame ID checking storage */
+       int                     next_frame_id;
+       /* Use new Isoch TRB layout needed for extended TBC support */
+-- 
+2.39.5
+
diff --git a/queue-6.6/watchdog-rzg2l_wdt-power-on-the-watchdog-domain-in-t.patch b/queue-6.6/watchdog-rzg2l_wdt-power-on-the-watchdog-domain-in-t.patch
new file mode 100644 (file)
index 0000000..3d8bc50
--- /dev/null
@@ -0,0 +1,103 @@
+From a9767f47e1c2bfcdfe37d9cfc8888f4f619e2efd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Oct 2024 19:47:32 +0300
+Subject: watchdog: rzg2l_wdt: Power on the watchdog domain in the restart
+ handler
+
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+
+[ Upstream commit bad201b2ac4e238c6d4b6966a220240e3861640c ]
+
+On RZ/G3S the watchdog can be part of a software-controlled PM domain. In
+this case, the watchdog device need to be powered on in
+struct watchdog_ops::restart API. This can be done though
+pm_runtime_resume_and_get() API if the watchdog PM domain and watchdog
+device are marked as IRQ safe. We mark the watchdog PM domain as IRQ safe
+with GENPD_FLAG_IRQ_SAFE when the watchdog PM domain is registered and the
+watchdog device though pm_runtime_irq_safe().
+
+Before commit e4cf89596c1f ("watchdog: rzg2l_wdt: Fix 'BUG: Invalid wait
+context'") pm_runtime_get_sync() was used in watchdog restart handler
+(which is similar to pm_runtime_resume_and_get() except the later one
+handles the runtime resume errors).
+
+Commit e4cf89596c1f ("watchdog: rzg2l_wdt: Fix 'BUG: Invalid wait
+context'") dropped the pm_runtime_get_sync() and replaced it with
+clk_prepare_enable() to avoid invalid wait context due to genpd_lock()
+in genpd_runtime_resume() being called from atomic context. But
+clk_prepare_enable() doesn't fit for this either (as reported by
+Ulf Hansson) as clk_prepare() can also sleep (it just not throw invalid
+wait context warning as it is not written for this).
+
+Because the watchdog device is marked now as IRQ safe (though this patch)
+the irq_safe_dev_in_sleep_domain() call from genpd_runtime_resume() returns
+1 for devices not registering an IRQ safe PM domain for watchdog (as the
+watchdog device is IRQ safe, PM domain is not and watchdog PM domain is
+always-on), this being the case for RZ/G3S with old device trees and
+the rest of the SoCs that use this driver, we can now drop also the
+clk_prepare_enable() calls in restart handler and rely on
+pm_runtime_resume_and_get().
+
+Thus, drop clk_prepare_enable() and use pm_runtime_resume_and_get() in
+watchdog restart handler.
+
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Acked-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20241015164732.4085249-5-claudiu.beznea.uj@bp.renesas.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/rzg2l_wdt.c | 20 ++++++++++++++++++--
+ 1 file changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/watchdog/rzg2l_wdt.c b/drivers/watchdog/rzg2l_wdt.c
+index d09f938415fc..525a72d8d746 100644
+--- a/drivers/watchdog/rzg2l_wdt.c
++++ b/drivers/watchdog/rzg2l_wdt.c
+@@ -12,6 +12,7 @@
+ #include <linux/module.h>
+ #include <linux/of.h>
+ #include <linux/platform_device.h>
++#include <linux/pm_domain.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/reset.h>
+ #include <linux/units.h>
+@@ -166,8 +167,22 @@ static int rzg2l_wdt_restart(struct watchdog_device *wdev,
+       struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
+       int ret;
+-      clk_prepare_enable(priv->pclk);
+-      clk_prepare_enable(priv->osc_clk);
++      /*
++       * In case of RZ/G3S the watchdog device may be part of an IRQ safe power
++       * domain that is currently powered off. In this case we need to power
++       * it on before accessing registers. Along with this the clocks will be
++       * enabled. We don't undo the pm_runtime_resume_and_get() as the device
++       * need to be on for the reboot to happen.
++       *
++       * For the rest of SoCs not registering a watchdog IRQ safe power
++       * domain it is safe to call pm_runtime_resume_and_get() as the
++       * irq_safe_dev_in_sleep_domain() call in genpd_runtime_resume()
++       * returns non zero value and the genpd_lock() is avoided, thus, there
++       * will be no invalid wait context reported by lockdep.
++       */
++      ret = pm_runtime_resume_and_get(wdev->parent);
++      if (ret)
++              return ret;
+       if (priv->devtype == WDT_RZG2L) {
+               ret = reset_control_deassert(priv->rstc);
+@@ -275,6 +290,7 @@ static int rzg2l_wdt_probe(struct platform_device *pdev)
+       priv->devtype = (uintptr_t)of_device_get_match_data(dev);
++      pm_runtime_irq_safe(&pdev->dev);
+       pm_runtime_enable(&pdev->dev);
+       priv->wdev.info = &rzg2l_wdt_ident;
+-- 
+2.39.5
+
diff --git a/queue-6.6/watchdog-rzg2l_wdt-rely-on-the-reset-driver-for-doin.patch b/queue-6.6/watchdog-rzg2l_wdt-rely-on-the-reset-driver-for-doin.patch
new file mode 100644 (file)
index 0000000..a73a50e
--- /dev/null
@@ -0,0 +1,118 @@
+From 38d9e40d3b0bd69c9e889090edd9960e5930ca34 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 May 2024 09:57:21 +0300
+Subject: watchdog: rzg2l_wdt: Rely on the reset driver for doing proper reset
+
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+
+[ Upstream commit d8997ed79ed7c7c32b2ae571e0d99a58bbfd01fe ]
+
+The reset driver has been adapted in commit da235d2fac21
+("clk: renesas: rzg2l: Check reset monitor registers") to check the reset
+monitor bits before declaring reset asserts/de-asserts as
+successful/failure operations. With that, there is no need to keep the
+reset workaround for RZ/V2M in place in the watchdog driver.
+
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20240531065723.1085423-8-claudiu.beznea.uj@bp.renesas.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Stable-dep-of: bad201b2ac4e ("watchdog: rzg2l_wdt: Power on the watchdog domain in the restart handler")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/rzg2l_wdt.c | 39 ++++--------------------------------
+ 1 file changed, 4 insertions(+), 35 deletions(-)
+
+diff --git a/drivers/watchdog/rzg2l_wdt.c b/drivers/watchdog/rzg2l_wdt.c
+index 7aad66da138a..d09f938415fc 100644
+--- a/drivers/watchdog/rzg2l_wdt.c
++++ b/drivers/watchdog/rzg2l_wdt.c
+@@ -8,7 +8,6 @@
+ #include <linux/clk.h>
+ #include <linux/delay.h>
+ #include <linux/io.h>
+-#include <linux/iopoll.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
+@@ -54,35 +53,11 @@ struct rzg2l_wdt_priv {
+       struct reset_control *rstc;
+       unsigned long osc_clk_rate;
+       unsigned long delay;
+-      unsigned long minimum_assertion_period;
+       struct clk *pclk;
+       struct clk *osc_clk;
+       enum rz_wdt_type devtype;
+ };
+-static int rzg2l_wdt_reset(struct rzg2l_wdt_priv *priv)
+-{
+-      int err, status;
+-
+-      if (priv->devtype == WDT_RZV2M) {
+-              /* WDT needs TYPE-B reset control */
+-              err = reset_control_assert(priv->rstc);
+-              if (err)
+-                      return err;
+-              ndelay(priv->minimum_assertion_period);
+-              err = reset_control_deassert(priv->rstc);
+-              if (err)
+-                      return err;
+-              err = read_poll_timeout(reset_control_status, status,
+-                                      status != 1, 0, 1000, false,
+-                                      priv->rstc);
+-      } else {
+-              err = reset_control_reset(priv->rstc);
+-      }
+-
+-      return err;
+-}
+-
+ static void rzg2l_wdt_wait_delay(struct rzg2l_wdt_priv *priv)
+ {
+       /* delay timer when change the setting register */
+@@ -189,13 +164,12 @@ static int rzg2l_wdt_restart(struct watchdog_device *wdev,
+                            unsigned long action, void *data)
+ {
+       struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
++      int ret;
+       clk_prepare_enable(priv->pclk);
+       clk_prepare_enable(priv->osc_clk);
+       if (priv->devtype == WDT_RZG2L) {
+-              int ret;
+-
+               ret = reset_control_deassert(priv->rstc);
+               if (ret)
+                       return ret;
+@@ -207,7 +181,9 @@ static int rzg2l_wdt_restart(struct watchdog_device *wdev,
+               rzg2l_wdt_write(priv, PEEN_FORCE, PEEN);
+       } else {
+               /* RZ/V2M doesn't have parity error registers */
+-              rzg2l_wdt_reset(priv);
++              ret = reset_control_reset(priv->rstc);
++              if (ret)
++                      return ret;
+               wdev->timeout = 0;
+@@ -299,13 +275,6 @@ static int rzg2l_wdt_probe(struct platform_device *pdev)
+       priv->devtype = (uintptr_t)of_device_get_match_data(dev);
+-      if (priv->devtype == WDT_RZV2M) {
+-              priv->minimum_assertion_period = RZV2M_A_NSEC +
+-                      3 * F2CYCLE_NSEC(pclk_rate) + 5 *
+-                      max(F2CYCLE_NSEC(priv->osc_clk_rate),
+-                          F2CYCLE_NSEC(pclk_rate));
+-      }
+-
+       pm_runtime_enable(&pdev->dev);
+       priv->wdev.info = &rzg2l_wdt_ident;
+-- 
+2.39.5
+
diff --git a/queue-6.6/watchdog-rzg2l_wdt-remove-reset-de-assert-from-probe.patch b/queue-6.6/watchdog-rzg2l_wdt-remove-reset-de-assert-from-probe.patch
new file mode 100644 (file)
index 0000000..4ae6909
--- /dev/null
@@ -0,0 +1,110 @@
+From 0f600398be367bf7b70f62c7c7792b35fa4762c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 May 2024 09:57:19 +0300
+Subject: watchdog: rzg2l_wdt: Remove reset de-assert from probe
+
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+
+[ Upstream commit 064319c3fac88e04f53f3460cd24ae90de2d9fb6 ]
+
+There is no need to de-assert the reset signal on probe as the watchdog
+is not used prior executing start. Also, the clocks are not enabled in
+probe (pm_runtime_enable() doesn't do that), thus this is another indicator
+that the watchdog wasn't used previously like this. Instead, keep the
+watchdog hardware in its previous state at probe (by default it is in
+reset state), enable it when it is started and move it to reset state
+when it is stopped. This saves some extra power when the watchdog is
+unused.
+
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20240531065723.1085423-6-claudiu.beznea.uj@bp.renesas.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Stable-dep-of: bad201b2ac4e ("watchdog: rzg2l_wdt: Power on the watchdog domain in the restart handler")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/rzg2l_wdt.c | 28 +++++++++++++++++-----------
+ 1 file changed, 17 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/watchdog/rzg2l_wdt.c b/drivers/watchdog/rzg2l_wdt.c
+index 7bce093316c4..7aad66da138a 100644
+--- a/drivers/watchdog/rzg2l_wdt.c
++++ b/drivers/watchdog/rzg2l_wdt.c
+@@ -129,6 +129,12 @@ static int rzg2l_wdt_start(struct watchdog_device *wdev)
+       if (ret)
+               return ret;
++      ret = reset_control_deassert(priv->rstc);
++      if (ret) {
++              pm_runtime_put(wdev->parent);
++              return ret;
++      }
++
+       /* Initialize time out */
+       rzg2l_wdt_init_timeout(wdev);
+@@ -146,7 +152,9 @@ static int rzg2l_wdt_stop(struct watchdog_device *wdev)
+       struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
+       int ret;
+-      rzg2l_wdt_reset(priv);
++      ret = reset_control_assert(priv->rstc);
++      if (ret)
++              return ret;
+       ret = pm_runtime_put(wdev->parent);
+       if (ret < 0)
+@@ -186,6 +194,12 @@ static int rzg2l_wdt_restart(struct watchdog_device *wdev,
+       clk_prepare_enable(priv->osc_clk);
+       if (priv->devtype == WDT_RZG2L) {
++              int ret;
++
++              ret = reset_control_deassert(priv->rstc);
++              if (ret)
++                      return ret;
++
+               /* Generate Reset (WDTRSTB) Signal on parity error */
+               rzg2l_wdt_write(priv, 0, PECR);
+@@ -236,13 +250,11 @@ static const struct watchdog_ops rzg2l_wdt_ops = {
+       .restart = rzg2l_wdt_restart,
+ };
+-static void rzg2l_wdt_reset_assert_pm_disable(void *data)
++static void rzg2l_wdt_pm_disable(void *data)
+ {
+       struct watchdog_device *wdev = data;
+-      struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
+       pm_runtime_disable(wdev->parent);
+-      reset_control_assert(priv->rstc);
+ }
+ static int rzg2l_wdt_probe(struct platform_device *pdev)
+@@ -285,10 +297,6 @@ static int rzg2l_wdt_probe(struct platform_device *pdev)
+               return dev_err_probe(&pdev->dev, PTR_ERR(priv->rstc),
+                                    "failed to get cpg reset");
+-      ret = reset_control_deassert(priv->rstc);
+-      if (ret)
+-              return dev_err_probe(dev, ret, "failed to deassert");
+-
+       priv->devtype = (uintptr_t)of_device_get_match_data(dev);
+       if (priv->devtype == WDT_RZV2M) {
+@@ -309,9 +317,7 @@ static int rzg2l_wdt_probe(struct platform_device *pdev)
+       priv->wdev.timeout = WDT_DEFAULT_TIMEOUT;
+       watchdog_set_drvdata(&priv->wdev, priv);
+-      ret = devm_add_action_or_reset(&pdev->dev,
+-                                     rzg2l_wdt_reset_assert_pm_disable,
+-                                     &priv->wdev);
++      ret = devm_add_action_or_reset(&pdev->dev, rzg2l_wdt_pm_disable, &priv->wdev);
+       if (ret < 0)
+               return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.6/watchdog-s3c2410_wdt-use-exynos_get_pmu_regmap_by_ph.patch b/queue-6.6/watchdog-s3c2410_wdt-use-exynos_get_pmu_regmap_by_ph.patch
new file mode 100644 (file)
index 0000000..50f31e5
--- /dev/null
@@ -0,0 +1,73 @@
+From d9b6d9fd215637faecdb7f5ef92865a6a76ca509 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Feb 2024 22:06:13 +0000
+Subject: watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle() for PMU
+ regs
+
+From: Peter Griffin <peter.griffin@linaro.org>
+
+[ Upstream commit 746f0770f916e6c48e422d6a34e67eae16707f0e ]
+
+Obtain the PMU regmap using the new API added to exynos-pmu driver rather
+than syscon_regmap_lookup_by_phandle(). As this driver no longer depends
+on mfd syscon remove that header and Kconfig dependency.
+
+Tested-by: Alexey Klimov <alexey.klimov@linaro.org>
+Tested-by: Sam Protsenko <semen.protsenko@linaro.org>
+Acked-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org>
+Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
+Link: https://lore.kernel.org/r/20240220220613.797068-3-peter.griffin@linaro.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Stable-dep-of: ccfb765944bb ("Revert "watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle() for PMU regs"")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/Kconfig       | 1 -
+ drivers/watchdog/s3c2410_wdt.c | 8 ++++----
+ 2 files changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
+index 751458959411..4ecf701abe5f 100644
+--- a/drivers/watchdog/Kconfig
++++ b/drivers/watchdog/Kconfig
+@@ -512,7 +512,6 @@ config S3C2410_WATCHDOG
+       tristate "S3C6410/S5Pv210/Exynos Watchdog"
+       depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
+       select WATCHDOG_CORE
+-      select MFD_SYSCON if ARCH_EXYNOS
+       help
+         Watchdog timer block in the Samsung S3C64xx, S5Pv210 and Exynos
+         SoCs. This will reboot the system when the timer expires with
+diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
+index 0b4bd883ff28..0c9c649583d4 100644
+--- a/drivers/watchdog/s3c2410_wdt.c
++++ b/drivers/watchdog/s3c2410_wdt.c
+@@ -23,9 +23,9 @@
+ #include <linux/slab.h>
+ #include <linux/err.h>
+ #include <linux/of.h>
+-#include <linux/mfd/syscon.h>
+ #include <linux/regmap.h>
+ #include <linux/delay.h>
++#include <linux/soc/samsung/exynos-pmu.h>
+ #define S3C2410_WTCON         0x00
+ #define S3C2410_WTDAT         0x04
+@@ -640,11 +640,11 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
+               return ret;
+       if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) {
+-              wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
+-                                              "samsung,syscon-phandle");
++              wdt->pmureg = exynos_get_pmu_regmap_by_phandle(dev->of_node,
++                                               "samsung,syscon-phandle");
+               if (IS_ERR(wdt->pmureg))
+                       return dev_err_probe(dev, PTR_ERR(wdt->pmureg),
+-                                           "syscon regmap lookup failed.\n");
++                                           "PMU regmap lookup failed.\n");
+       }
+       wdt_irq = platform_get_irq(pdev, 0);
+-- 
+2.39.5
+
diff --git a/queue-6.6/wifi-ath10k-avoid-null-pointer-error-during-sdio-rem.patch b/queue-6.6/wifi-ath10k-avoid-null-pointer-error-during-sdio-rem.patch
new file mode 100644 (file)
index 0000000..deb58be
--- /dev/null
@@ -0,0 +1,105 @@
+From 8b0ef76c817997bbc0ba67255cb520002b8f3490 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Oct 2024 10:22:46 +0800
+Subject: wifi: ath10k: avoid NULL pointer error during sdio remove
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Kang Yang <quic_kangyang@quicinc.com>
+
+[ Upstream commit 95c38953cb1ecf40399a676a1f85dfe2b5780a9a ]
+
+When running 'rmmod ath10k', ath10k_sdio_remove() will free sdio
+workqueue by destroy_workqueue(). But if CONFIG_INIT_ON_FREE_DEFAULT_ON
+is set to yes, kernel panic will happen:
+Call trace:
+ destroy_workqueue+0x1c/0x258
+ ath10k_sdio_remove+0x84/0x94
+ sdio_bus_remove+0x50/0x16c
+ device_release_driver_internal+0x188/0x25c
+ device_driver_detach+0x20/0x2c
+
+This is because during 'rmmod ath10k', ath10k_sdio_remove() will call
+ath10k_core_destroy() before destroy_workqueue(). wiphy_dev_release()
+will finally be called in ath10k_core_destroy(). This function will free
+struct cfg80211_registered_device *rdev and all its members, including
+wiphy, dev and the pointer of sdio workqueue. Then the pointer of sdio
+workqueue will be set to NULL due to CONFIG_INIT_ON_FREE_DEFAULT_ON.
+
+After device release, destroy_workqueue() will use NULL pointer then the
+kernel panic happen.
+
+Call trace:
+ath10k_sdio_remove
+  ->ath10k_core_unregister
+    â€¦â€¦
+    ->ath10k_core_stop
+      ->ath10k_hif_stop
+        ->ath10k_sdio_irq_disable
+    ->ath10k_hif_power_down
+      ->del_timer_sync(&ar_sdio->sleep_timer)
+  ->ath10k_core_destroy
+    ->ath10k_mac_destroy
+      ->ieee80211_free_hw
+        ->wiphy_free
+    â€¦â€¦
+          ->wiphy_dev_release
+  ->destroy_workqueue
+
+Need to call destroy_workqueue() before ath10k_core_destroy(), free
+the work queue buffer first and then free pointer of work queue by
+ath10k_core_destroy(). This order matches the error path order in
+ath10k_sdio_probe().
+
+No work will be queued on sdio workqueue between it is destroyed and
+ath10k_core_destroy() is called. Based on the call_stack above, the
+reason is:
+Only ath10k_sdio_sleep_timer_handler(), ath10k_sdio_hif_tx_sg() and
+ath10k_sdio_irq_disable() will queue work on sdio workqueue.
+Sleep timer will be deleted before ath10k_core_destroy() in
+ath10k_hif_power_down().
+ath10k_sdio_irq_disable() only be called in ath10k_hif_stop().
+ath10k_core_unregister() will call ath10k_hif_power_down() to stop hif
+bus, so ath10k_sdio_hif_tx_sg() won't be called anymore.
+
+Tested-on: QCA6174 hw3.2 SDIO WLAN.RMH.4.4.1-00189
+
+Signed-off-by: Kang Yang <quic_kangyang@quicinc.com>
+Tested-by: David Ruth <druth@chromium.org>
+Reviewed-by: David Ruth <druth@chromium.org>
+Link: https://patch.msgid.link/20241008022246.1010-1-quic_kangyang@quicinc.com
+Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath10k/sdio.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c
+index 0ab5433f6cf6..850d999615a2 100644
+--- a/drivers/net/wireless/ath/ath10k/sdio.c
++++ b/drivers/net/wireless/ath/ath10k/sdio.c
+@@ -3,7 +3,7 @@
+  * Copyright (c) 2004-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2012,2017 Qualcomm Atheros, Inc.
+  * Copyright (c) 2016-2017 Erik Stromdahl <erik.stromdahl@gmail.com>
+- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
++ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include <linux/module.h>
+@@ -2648,9 +2648,9 @@ static void ath10k_sdio_remove(struct sdio_func *func)
+       netif_napi_del(&ar->napi);
+-      ath10k_core_destroy(ar);
+-
+       destroy_workqueue(ar_sdio->workqueue);
++
++      ath10k_core_destroy(ar);
+ }
+ static const struct sdio_device_id ath10k_sdio_devices[] = {
+-- 
+2.39.5
+
diff --git a/queue-6.6/wifi-ath10k-update-qualcomm-innovation-center-inc.-c.patch b/queue-6.6/wifi-ath10k-update-qualcomm-innovation-center-inc.-c.patch
new file mode 100644 (file)
index 0000000..b383d8d
--- /dev/null
@@ -0,0 +1,387 @@
+From 40147aa9c89b1046acb61a78cf1c07a022669b75 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Nov 2023 13:39:28 +0200
+Subject: wifi: ath10k: Update Qualcomm Innovation Center, Inc. copyrights
+
+From: Jeff Johnson <quic_jjohnson@quicinc.com>
+
+[ Upstream commit b1dc0ba41431147e55407140962c76f3e7a06753 ]
+
+Update the copyright for all ath10k files modified on behalf of
+Qualcomm Innovation Center, Inc. in 2021 through 2023.
+
+Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20231128-ath12kcopyrights-v1-3-be0b7408cbac@quicinc.com
+Stable-dep-of: 95c38953cb1e ("wifi: ath10k: avoid NULL pointer error during sdio remove")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath10k/bmi.c          | 1 +
+ drivers/net/wireless/ath/ath10k/ce.c           | 1 +
+ drivers/net/wireless/ath/ath10k/core.c         | 1 +
+ drivers/net/wireless/ath/ath10k/core.h         | 1 +
+ drivers/net/wireless/ath/ath10k/coredump.c     | 1 +
+ drivers/net/wireless/ath/ath10k/coredump.h     | 1 +
+ drivers/net/wireless/ath/ath10k/debug.c        | 1 +
+ drivers/net/wireless/ath/ath10k/debugfs_sta.c  | 1 +
+ drivers/net/wireless/ath/ath10k/htc.c          | 1 +
+ drivers/net/wireless/ath/ath10k/htt.h          | 1 +
+ drivers/net/wireless/ath/ath10k/htt_rx.c       | 1 +
+ drivers/net/wireless/ath/ath10k/htt_tx.c       | 1 +
+ drivers/net/wireless/ath/ath10k/hw.c           | 1 +
+ drivers/net/wireless/ath/ath10k/hw.h           | 1 +
+ drivers/net/wireless/ath/ath10k/mac.c          | 1 +
+ drivers/net/wireless/ath/ath10k/pci.c          | 1 +
+ drivers/net/wireless/ath/ath10k/pci.h          | 1 +
+ drivers/net/wireless/ath/ath10k/qmi.c          | 1 +
+ drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c | 1 +
+ drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h | 1 +
+ drivers/net/wireless/ath/ath10k/rx_desc.h      | 1 +
+ drivers/net/wireless/ath/ath10k/sdio.c         | 1 +
+ drivers/net/wireless/ath/ath10k/thermal.c      | 1 +
+ drivers/net/wireless/ath/ath10k/usb.h          | 1 +
+ drivers/net/wireless/ath/ath10k/wmi-tlv.h      | 1 +
+ drivers/net/wireless/ath/ath10k/wmi.c          | 1 +
+ drivers/net/wireless/ath/ath10k/wmi.h          | 1 +
+ drivers/net/wireless/ath/ath10k/wow.c          | 1 +
+ 28 files changed, 28 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath10k/bmi.c b/drivers/net/wireless/ath/ath10k/bmi.c
+index af6546572df2..9a4f8e815412 100644
+--- a/drivers/net/wireless/ath/ath10k/bmi.c
++++ b/drivers/net/wireless/ath/ath10k/bmi.c
+@@ -2,6 +2,7 @@
+ /*
+  * Copyright (c) 2005-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2014,2016-2017 Qualcomm Atheros, Inc.
++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include "bmi.h"
+diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
+index c27b8204718a..afae4a8027f8 100644
+--- a/drivers/net/wireless/ath/ath10k/ce.c
++++ b/drivers/net/wireless/ath/ath10k/ce.c
+@@ -3,6 +3,7 @@
+  * Copyright (c) 2005-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+  * Copyright (c) 2018 The Linux Foundation. All rights reserved.
++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include "hif.h"
+diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
+index 81058be3598f..c3a8b3496be2 100644
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -3,6 +3,7 @@
+  * Copyright (c) 2005-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+  * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include <linux/module.h>
+diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
+index 4b5239de4018..cb2359d2ee0b 100644
+--- a/drivers/net/wireless/ath/ath10k/core.h
++++ b/drivers/net/wireless/ath/ath10k/core.h
+@@ -3,6 +3,7 @@
+  * Copyright (c) 2005-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+  * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #ifndef _CORE_H_
+diff --git a/drivers/net/wireless/ath/ath10k/coredump.c b/drivers/net/wireless/ath/ath10k/coredump.c
+index 2d1634a890dd..bb3a276b7ed5 100644
+--- a/drivers/net/wireless/ath/ath10k/coredump.c
++++ b/drivers/net/wireless/ath/ath10k/coredump.c
+@@ -2,6 +2,7 @@
+ /*
+  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include "coredump.h"
+diff --git a/drivers/net/wireless/ath/ath10k/coredump.h b/drivers/net/wireless/ath/ath10k/coredump.h
+index 437b9759f05d..e5ef0352e319 100644
+--- a/drivers/net/wireless/ath/ath10k/coredump.h
++++ b/drivers/net/wireless/ath/ath10k/coredump.h
+@@ -1,6 +1,7 @@
+ /* SPDX-License-Identifier: ISC */
+ /*
+  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #ifndef _COREDUMP_H_
+diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
+index fe89bc61e531..92ad0a04bcc7 100644
+--- a/drivers/net/wireless/ath/ath10k/debug.c
++++ b/drivers/net/wireless/ath/ath10k/debug.c
+@@ -3,6 +3,7 @@
+  * Copyright (c) 2005-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include <linux/module.h>
+diff --git a/drivers/net/wireless/ath/ath10k/debugfs_sta.c b/drivers/net/wireless/ath/ath10k/debugfs_sta.c
+index 5598cf706daa..0f6de862c3a9 100644
+--- a/drivers/net/wireless/ath/ath10k/debugfs_sta.c
++++ b/drivers/net/wireless/ath/ath10k/debugfs_sta.c
+@@ -2,6 +2,7 @@
+ /*
+  * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
+  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include "core.h"
+diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c
+index 5bfeecb95fca..a6e21ce90bad 100644
+--- a/drivers/net/wireless/ath/ath10k/htc.c
++++ b/drivers/net/wireless/ath/ath10k/htc.c
+@@ -2,6 +2,7 @@
+ /*
+  * Copyright (c) 2005-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include "core.h"
+diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
+index 7b24297146e7..52f6dc6b81c5 100644
+--- a/drivers/net/wireless/ath/ath10k/htt.h
++++ b/drivers/net/wireless/ath/ath10k/htt.h
+@@ -3,6 +3,7 @@
+  * Copyright (c) 2005-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
++ * Copyright (c) 2021, 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #ifndef _HTT_H_
+diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
+index 438b0caaceb7..51855f23ea26 100644
+--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
+@@ -3,6 +3,7 @@
+  * Copyright (c) 2005-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include "core.h"
+diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
+index bd603feb7953..60425d22d707 100644
+--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
++++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
+@@ -2,6 +2,7 @@
+ /*
+  * Copyright (c) 2005-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include <linux/etherdevice.h>
+diff --git a/drivers/net/wireless/ath/ath10k/hw.c b/drivers/net/wireless/ath/ath10k/hw.c
+index 6d32b43a4da6..8fafe096adff 100644
+--- a/drivers/net/wireless/ath/ath10k/hw.c
++++ b/drivers/net/wireless/ath/ath10k/hw.c
+@@ -1,6 +1,7 @@
+ // SPDX-License-Identifier: ISC
+ /*
+  * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include <linux/types.h>
+diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
+index 7ecdd0011cfa..afd336282615 100644
+--- a/drivers/net/wireless/ath/ath10k/hw.h
++++ b/drivers/net/wireless/ath/ath10k/hw.h
+@@ -3,6 +3,7 @@
+  * Copyright (c) 2005-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+  * Copyright (c) 2018 The Linux Foundation. All rights reserved.
++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #ifndef _HW_H_
+diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
+index d5e6e11f630b..655fb5cdf01f 100644
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -3,6 +3,7 @@
+  * Copyright (c) 2005-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+  * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include "mac.h"
+diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
+index 23f366221939..aaa240f3c08a 100644
+--- a/drivers/net/wireless/ath/ath10k/pci.c
++++ b/drivers/net/wireless/ath/ath10k/pci.c
+@@ -2,6 +2,7 @@
+ /*
+  * Copyright (c) 2005-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include <linux/pci.h>
+diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h
+index 480cd97ab739..27bb4cf2dfea 100644
+--- a/drivers/net/wireless/ath/ath10k/pci.h
++++ b/drivers/net/wireless/ath/ath10k/pci.h
+@@ -2,6 +2,7 @@
+ /*
+  * Copyright (c) 2005-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #ifndef _PCI_H_
+diff --git a/drivers/net/wireless/ath/ath10k/qmi.c b/drivers/net/wireless/ath/ath10k/qmi.c
+index 52c1a3de8da6..38e939f572a9 100644
+--- a/drivers/net/wireless/ath/ath10k/qmi.c
++++ b/drivers/net/wireless/ath/ath10k/qmi.c
+@@ -1,6 +1,7 @@
+ // SPDX-License-Identifier: ISC
+ /*
+  * Copyright (c) 2018 The Linux Foundation. All rights reserved.
++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include <linux/completion.h>
+diff --git a/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c
+index 1c81e454f943..0e85c75d2278 100644
+--- a/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c
++++ b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c
+@@ -1,6 +1,7 @@
+ // SPDX-License-Identifier: ISC
+ /*
+  * Copyright (c) 2018 The Linux Foundation. All rights reserved.
++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include <linux/soc/qcom/qmi.h>
+diff --git a/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h
+index f0db991408dc..9f311f3bc9e7 100644
+--- a/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h
++++ b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h
+@@ -1,6 +1,7 @@
+ /* SPDX-License-Identifier: ISC */
+ /*
+  * Copyright (c) 2018 The Linux Foundation. All rights reserved.
++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #ifndef WCN3990_QMI_SVC_V01_H
+diff --git a/drivers/net/wireless/ath/ath10k/rx_desc.h b/drivers/net/wireless/ath/ath10k/rx_desc.h
+index 777e53aa69dc..564293df1e9a 100644
+--- a/drivers/net/wireless/ath/ath10k/rx_desc.h
++++ b/drivers/net/wireless/ath/ath10k/rx_desc.h
+@@ -2,6 +2,7 @@
+ /*
+  * Copyright (c) 2005-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #ifndef _RX_DESC_H_
+diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c
+index 56fbcfb80bf8..0ab5433f6cf6 100644
+--- a/drivers/net/wireless/ath/ath10k/sdio.c
++++ b/drivers/net/wireless/ath/ath10k/sdio.c
+@@ -3,6 +3,7 @@
+  * Copyright (c) 2004-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2012,2017 Qualcomm Atheros, Inc.
+  * Copyright (c) 2016-2017 Erik Stromdahl <erik.stromdahl@gmail.com>
++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include <linux/module.h>
+diff --git a/drivers/net/wireless/ath/ath10k/thermal.c b/drivers/net/wireless/ath/ath10k/thermal.c
+index cefd97323dfe..31c8d7fbb095 100644
+--- a/drivers/net/wireless/ath/ath10k/thermal.c
++++ b/drivers/net/wireless/ath/ath10k/thermal.c
+@@ -1,6 +1,7 @@
+ // SPDX-License-Identifier: ISC
+ /*
+  * Copyright (c) 2014-2015 Qualcomm Atheros, Inc.
++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include <linux/device.h>
+diff --git a/drivers/net/wireless/ath/ath10k/usb.h b/drivers/net/wireless/ath/ath10k/usb.h
+index 48e066ba8162..7e4cfbb673c9 100644
+--- a/drivers/net/wireless/ath/ath10k/usb.h
++++ b/drivers/net/wireless/ath/ath10k/usb.h
+@@ -3,6 +3,7 @@
+  * Copyright (c) 2004-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
+  * Copyright (c) 2016-2017 Erik Stromdahl <erik.stromdahl@gmail.com>
++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #ifndef _USB_H_
+diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
+index dbb48d70f2e9..83a8f07a687f 100644
+--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h
++++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
+@@ -3,6 +3,7 @@
+  * Copyright (c) 2005-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+  * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #ifndef _WMI_TLV_H
+ #define _WMI_TLV_H
+diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
+index 1c21dbde77b8..818aea99f85e 100644
+--- a/drivers/net/wireless/ath/ath10k/wmi.c
++++ b/drivers/net/wireless/ath/ath10k/wmi.c
+@@ -3,6 +3,7 @@
+  * Copyright (c) 2005-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+  * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
++ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include <linux/skbuff.h>
+diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
+index b112e8826093..9146df98fcee 100644
+--- a/drivers/net/wireless/ath/ath10k/wmi.h
++++ b/drivers/net/wireless/ath/ath10k/wmi.h
+@@ -3,6 +3,7 @@
+  * Copyright (c) 2005-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+  * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #ifndef _WMI_H_
+diff --git a/drivers/net/wireless/ath/ath10k/wow.c b/drivers/net/wireless/ath/ath10k/wow.c
+index 20b9aa8ddf7d..aa7b2e703f3d 100644
+--- a/drivers/net/wireless/ath/ath10k/wow.c
++++ b/drivers/net/wireless/ath/ath10k/wow.c
+@@ -2,6 +2,7 @@
+ /*
+  * Copyright (c) 2015-2017 Qualcomm Atheros, Inc.
+  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include "mac.h"
+-- 
+2.39.5
+
diff --git a/queue-6.6/wifi-ath12k-fix-atomic-calls-in-ath12k_mac_op_set_bi.patch b/queue-6.6/wifi-ath12k-fix-atomic-calls-in-ath12k_mac_op_set_bi.patch
new file mode 100644 (file)
index 0000000..791fb09
--- /dev/null
@@ -0,0 +1,171 @@
+From fe1b88e14cac1f0244b4f33cbd20708a157bab7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Oct 2024 19:59:27 +0300
+Subject: wifi: ath12k: fix atomic calls in ath12k_mac_op_set_bitrate_mask()
+
+From: Kalle Valo <quic_kvalo@quicinc.com>
+
+[ Upstream commit 8fac3266c68a8e647240b8ac8d0b82f1821edf85 ]
+
+When I try to manually set bitrates:
+
+iw wlan0 set bitrates legacy-2.4 1
+
+I get sleeping from invalid context error, see below. Fix that by switching to
+use recently introduced ieee80211_iterate_stations_mtx().
+
+Do note that WCN6855 firmware is still crashing, I'm not sure if that firmware
+even supports bitrate WMI commands and should we consider disabling
+ath12k_mac_op_set_bitrate_mask() for WCN6855? But that's for another patch.
+
+BUG: sleeping function called from invalid context at drivers/net/wireless/ath/ath12k/wmi.c:420
+in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 2236, name: iw
+preempt_count: 0, expected: 0
+RCU nest depth: 1, expected: 0
+3 locks held by iw/2236:
+ #0: ffffffffabc6f1d8 (cb_lock){++++}-{3:3}, at: genl_rcv+0x14/0x40
+ #1: ffff888138410810 (&rdev->wiphy.mtx){+.+.}-{3:3}, at: nl80211_pre_doit+0x54d/0x800 [cfg80211]
+ #2: ffffffffab2cfaa0 (rcu_read_lock){....}-{1:2}, at: ieee80211_iterate_stations_atomic+0x2f/0x200 [mac80211]
+CPU: 3 UID: 0 PID: 2236 Comm: iw Not tainted 6.11.0-rc7-wt-ath+ #1772
+Hardware name: Intel(R) Client Systems NUC8i7HVK/NUC8i7HVB, BIOS HNKBLi70.86A.0067.2021.0528.1339 05/28/2021
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xa4/0xe0
+ dump_stack+0x10/0x20
+ __might_resched+0x363/0x5a0
+ ? __alloc_skb+0x165/0x340
+ __might_sleep+0xad/0x160
+ ath12k_wmi_cmd_send+0xb1/0x3d0 [ath12k]
+ ? ath12k_wmi_init_wcn7850+0xa40/0xa40 [ath12k]
+ ? __netdev_alloc_skb+0x45/0x7b0
+ ? __asan_memset+0x39/0x40
+ ? ath12k_wmi_alloc_skb+0xf0/0x150 [ath12k]
+ ? reacquire_held_locks+0x4d0/0x4d0
+ ath12k_wmi_set_peer_param+0x340/0x5b0 [ath12k]
+ ath12k_mac_disable_peer_fixed_rate+0xa3/0x110 [ath12k]
+ ? ath12k_mac_vdev_stop+0x4f0/0x4f0 [ath12k]
+ ieee80211_iterate_stations_atomic+0xd4/0x200 [mac80211]
+ ath12k_mac_op_set_bitrate_mask+0x5d2/0x1080 [ath12k]
+ ? ath12k_mac_vif_chan+0x320/0x320 [ath12k]
+ drv_set_bitrate_mask+0x267/0x470 [mac80211]
+ ieee80211_set_bitrate_mask+0x4cc/0x8a0 [mac80211]
+ ? __this_cpu_preempt_check+0x13/0x20
+ nl80211_set_tx_bitrate_mask+0x2bc/0x530 [cfg80211]
+ ? nl80211_parse_tx_bitrate_mask+0x2320/0x2320 [cfg80211]
+ ? trace_contention_end+0xef/0x140
+ ? rtnl_unlock+0x9/0x10
+ ? nl80211_pre_doit+0x557/0x800 [cfg80211]
+ genl_family_rcv_msg_doit+0x1f0/0x2e0
+ ? genl_family_rcv_msg_attrs_parse.isra.0+0x250/0x250
+ ? ns_capable+0x57/0xd0
+ genl_family_rcv_msg+0x34c/0x600
+ ? genl_family_rcv_msg_dumpit+0x310/0x310
+ ? __lock_acquire+0xc62/0x1de0
+ ? he_set_mcs_mask.isra.0+0x8d0/0x8d0 [cfg80211]
+ ? nl80211_parse_tx_bitrate_mask+0x2320/0x2320 [cfg80211]
+ ? cfg80211_external_auth_request+0x690/0x690 [cfg80211]
+ genl_rcv_msg+0xa0/0x130
+ netlink_rcv_skb+0x14c/0x400
+ ? genl_family_rcv_msg+0x600/0x600
+ ? netlink_ack+0xd70/0xd70
+ ? rwsem_optimistic_spin+0x4f0/0x4f0
+ ? genl_rcv+0x14/0x40
+ ? down_read_killable+0x580/0x580
+ ? netlink_deliver_tap+0x13e/0x350
+ ? __this_cpu_preempt_check+0x13/0x20
+ genl_rcv+0x23/0x40
+ netlink_unicast+0x45e/0x790
+ ? netlink_attachskb+0x7f0/0x7f0
+ netlink_sendmsg+0x7eb/0xdb0
+ ? netlink_unicast+0x790/0x790
+ ? __this_cpu_preempt_check+0x13/0x20
+ ? selinux_socket_sendmsg+0x31/0x40
+ ? netlink_unicast+0x790/0x790
+ __sock_sendmsg+0xc9/0x160
+ ____sys_sendmsg+0x620/0x990
+ ? kernel_sendmsg+0x30/0x30
+ ? __copy_msghdr+0x410/0x410
+ ? __kasan_check_read+0x11/0x20
+ ? mark_lock+0xe6/0x1470
+ ___sys_sendmsg+0xe9/0x170
+ ? copy_msghdr_from_user+0x120/0x120
+ ? __lock_acquire+0xc62/0x1de0
+ ? do_fault_around+0x2c6/0x4e0
+ ? do_user_addr_fault+0x8c1/0xde0
+ ? reacquire_held_locks+0x220/0x4d0
+ ? do_user_addr_fault+0x8c1/0xde0
+ ? __kasan_check_read+0x11/0x20
+ ? __fdget+0x4e/0x1d0
+ ? sockfd_lookup_light+0x1a/0x170
+ __sys_sendmsg+0xd2/0x180
+ ? __sys_sendmsg_sock+0x20/0x20
+ ? reacquire_held_locks+0x4d0/0x4d0
+ ? debug_smp_processor_id+0x17/0x20
+ __x64_sys_sendmsg+0x72/0xb0
+ ? lockdep_hardirqs_on+0x7d/0x100
+ x64_sys_call+0x894/0x9f0
+ do_syscall_64+0x64/0x130
+ entry_SYSCALL_64_after_hwframe+0x4b/0x53
+RIP: 0033:0x7f230fe04807
+Code: 64 89 02 48 c7 c0 ff ff ff ff eb bb 0f 1f 80 00 00 00 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 89 54 24 1c 48 89 74 24 10
+RSP: 002b:00007ffe996a7ea8 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 0000556f9f9c3390 RCX: 00007f230fe04807
+RDX: 0000000000000000 RSI: 00007ffe996a7ee0 RDI: 0000000000000003
+RBP: 0000556f9f9c88c0 R08: 0000000000000002 R09: 0000000000000000
+R10: 0000556f965ca190 R11: 0000000000000246 R12: 0000556f9f9c8780
+R13: 00007ffe996a7ee0 R14: 0000556f9f9c87d0 R15: 0000556f9f9c88c0
+ </TASK>
+
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://patch.msgid.link/20241007165932.78081-2-kvalo@kernel.org
+Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/mac.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
+index e4b8c45898d2..713899735ccc 100644
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -6676,9 +6676,9 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
+                                   arvif->vdev_id, ret);
+                       return ret;
+               }
+-              ieee80211_iterate_stations_atomic(hw,
+-                                                ath12k_mac_disable_peer_fixed_rate,
+-                                                arvif);
++              ieee80211_iterate_stations_mtx(hw,
++                                             ath12k_mac_disable_peer_fixed_rate,
++                                             arvif);
+       } else if (ath12k_mac_bitrate_mask_get_single_nss(ar, band, mask,
+                                                         &single_nss)) {
+               rate = WMI_FIXED_RATE_NONE;
+@@ -6722,16 +6722,16 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
+                       return -EINVAL;
+               }
+-              ieee80211_iterate_stations_atomic(hw,
+-                                                ath12k_mac_disable_peer_fixed_rate,
+-                                                arvif);
++              ieee80211_iterate_stations_mtx(hw,
++                                             ath12k_mac_disable_peer_fixed_rate,
++                                             arvif);
+               mutex_lock(&ar->conf_mutex);
+               arvif->bitrate_mask = *mask;
+-              ieee80211_iterate_stations_atomic(hw,
+-                                                ath12k_mac_set_bitrate_mask_iter,
+-                                                arvif);
++              ieee80211_iterate_stations_mtx(hw,
++                                             ath12k_mac_set_bitrate_mask_iter,
++                                             arvif);
+               mutex_unlock(&ar->conf_mutex);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.6/wifi-ath12k-optimize-the-mac80211-hw-data-access.patch b/queue-6.6/wifi-ath12k-optimize-the-mac80211-hw-data-access.patch
new file mode 100644 (file)
index 0000000..164c667
--- /dev/null
@@ -0,0 +1,123 @@
+From a28acaad2f30e25e035925efd0472f3cb62d7c9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Nov 2023 05:28:11 +0530
+Subject: wifi: ath12k: Optimize the mac80211 hw data access
+
+From: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
+
+[ Upstream commit 842addae02089fce4731be1c8d7d539449d4d009 ]
+
+Currently mac80211 hw data is accessed by convert the hw to radio (ar)
+structure and then radio to hw structure which is not necessary in some
+places where mac80211 hw data is already present. So in that kind of
+places avoid the conversion and directly access the mac80211 hw data.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
+
+Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20231120235812.2602198-2-quic_periyasa@quicinc.com
+Stable-dep-of: 8fac3266c68a ("wifi: ath12k: fix atomic calls in ath12k_mac_op_set_bitrate_mask()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/mac.c | 14 +++++++-------
+ drivers/net/wireless/ath/ath12k/reg.c |  6 +++---
+ 2 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
+index f90191a290c2..e4b8c45898d2 100644
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -4945,7 +4945,7 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw,
+               if (ret) {
+                       ath12k_warn(ar->ab, "failed to queue management frame %d\n",
+                                   ret);
+-                      ieee80211_free_txskb(ar->hw, skb);
++                      ieee80211_free_txskb(hw, skb);
+               }
+               return;
+       }
+@@ -4953,7 +4953,7 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw,
+       ret = ath12k_dp_tx(ar, arvif, skb);
+       if (ret) {
+               ath12k_warn(ar->ab, "failed to transmit frame %d\n", ret);
+-              ieee80211_free_txskb(ar->hw, skb);
++              ieee80211_free_txskb(hw, skb);
+       }
+ }
+@@ -5496,7 +5496,7 @@ static int ath12k_mac_op_add_interface(struct ieee80211_hw *hw,
+               goto err_peer_del;
+       param_id = WMI_VDEV_PARAM_RTS_THRESHOLD;
+-      param_value = ar->hw->wiphy->rts_threshold;
++      param_value = hw->wiphy->rts_threshold;
+       ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
+                                           param_id, param_value);
+       if (ret) {
+@@ -6676,7 +6676,7 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
+                                   arvif->vdev_id, ret);
+                       return ret;
+               }
+-              ieee80211_iterate_stations_atomic(ar->hw,
++              ieee80211_iterate_stations_atomic(hw,
+                                                 ath12k_mac_disable_peer_fixed_rate,
+                                                 arvif);
+       } else if (ath12k_mac_bitrate_mask_get_single_nss(ar, band, mask,
+@@ -6722,14 +6722,14 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
+                       return -EINVAL;
+               }
+-              ieee80211_iterate_stations_atomic(ar->hw,
++              ieee80211_iterate_stations_atomic(hw,
+                                                 ath12k_mac_disable_peer_fixed_rate,
+                                                 arvif);
+               mutex_lock(&ar->conf_mutex);
+               arvif->bitrate_mask = *mask;
+-              ieee80211_iterate_stations_atomic(ar->hw,
++              ieee80211_iterate_stations_atomic(hw,
+                                                 ath12k_mac_set_bitrate_mask_iter,
+                                                 arvif);
+@@ -6767,7 +6767,7 @@ ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw,
+               ath12k_warn(ar->ab, "pdev %d successfully recovered\n",
+                           ar->pdev->pdev_id);
+               ar->state = ATH12K_STATE_ON;
+-              ieee80211_wake_queues(ar->hw);
++              ieee80211_wake_queues(hw);
+               if (ab->is_reset) {
+                       recovery_count = atomic_inc_return(&ab->recovery_count);
+diff --git a/drivers/net/wireless/ath/ath12k/reg.c b/drivers/net/wireless/ath/ath12k/reg.c
+index 32bdefeccc24..837a3e1ec3a4 100644
+--- a/drivers/net/wireless/ath/ath12k/reg.c
++++ b/drivers/net/wireless/ath/ath12k/reg.c
+@@ -28,11 +28,11 @@ static const struct ieee80211_regdomain ath12k_world_regd = {
+       }
+ };
+-static bool ath12k_regdom_changes(struct ath12k *ar, char *alpha2)
++static bool ath12k_regdom_changes(struct ieee80211_hw *hw, char *alpha2)
+ {
+       const struct ieee80211_regdomain *regd;
+-      regd = rcu_dereference_rtnl(ar->hw->wiphy->regd);
++      regd = rcu_dereference_rtnl(hw->wiphy->regd);
+       /* This can happen during wiphy registration where the previous
+        * user request is received before we update the regd received
+        * from firmware.
+@@ -71,7 +71,7 @@ ath12k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
+               return;
+       }
+-      if (!ath12k_regdom_changes(ar, request->alpha2)) {
++      if (!ath12k_regdom_changes(hw, request->alpha2)) {
+               ath12k_dbg(ar->ab, ATH12K_DBG_REG, "Country is already set\n");
+               return;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.6/wifi-mac80211-add-non-atomic-station-iterator.patch b/queue-6.6/wifi-mac80211-add-non-atomic-station-iterator.patch
new file mode 100644 (file)
index 0000000..6883f1e
--- /dev/null
@@ -0,0 +1,93 @@
+From 62c4d12f503c092263b527512217b4d11cdf357f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Aug 2024 17:40:23 -0700
+Subject: wifi: mac80211: Add non-atomic station iterator
+
+From: Rory Little <rory@candelatech.com>
+
+[ Upstream commit 7c3b69eadea9e57c28bf914b0fd70f268f3682e1 ]
+
+Drivers may at times want to iterate their stations with a function
+which requires some non-atomic operations.
+
+ieee80211_iterate_stations_mtx() introduces an API to iterate stations
+while holding that wiphy's mutex. This allows the iterating function to
+do non-atomic operations safely.
+
+Signed-off-by: Rory Little <rory@candelatech.com>
+Link: https://patch.msgid.link/20240806004024.2014080-2-rory@candelatech.com
+[unify internal list iteration functions]
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Stable-dep-of: 8fac3266c68a ("wifi: ath12k: fix atomic calls in ath12k_mac_op_set_bitrate_mask()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/mac80211.h | 18 ++++++++++++++++++
+ net/mac80211/util.c    | 16 +++++++++++++++-
+ 2 files changed, 33 insertions(+), 1 deletion(-)
+
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index 901fe3ac139e..835a58ce9ca5 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -6080,6 +6080,24 @@ void ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw,
+                                      void (*iterator)(void *data,
+                                               struct ieee80211_sta *sta),
+                                      void *data);
++
++/**
++ * ieee80211_iterate_stations_mtx - iterate stations
++ *
++ * This function iterates over all stations associated with a given
++ * hardware that are currently uploaded to the driver and calls the callback
++ * function for them. This version can only be used while holding the wiphy
++ * mutex.
++ *
++ * @hw: the hardware struct of which the interfaces should be iterated over
++ * @iterator: the iterator function to call
++ * @data: first argument of the iterator function
++ */
++void ieee80211_iterate_stations_mtx(struct ieee80211_hw *hw,
++                                  void (*iterator)(void *data,
++                                                   struct ieee80211_sta *sta),
++                                  void *data);
++
+ /**
+  * ieee80211_queue_work - add work onto the mac80211 workqueue
+  *
+diff --git a/net/mac80211/util.c b/net/mac80211/util.c
+index d682c32821a1..cc3c46a82077 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -827,7 +827,8 @@ static void __iterate_stations(struct ieee80211_local *local,
+ {
+       struct sta_info *sta;
+-      list_for_each_entry_rcu(sta, &local->sta_list, list) {
++      list_for_each_entry_rcu(sta, &local->sta_list, list,
++                              lockdep_is_held(&local->hw.wiphy->mtx)) {
+               if (!sta->uploaded)
+                       continue;
+@@ -848,6 +849,19 @@ void ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw,
+ }
+ EXPORT_SYMBOL_GPL(ieee80211_iterate_stations_atomic);
++void ieee80211_iterate_stations_mtx(struct ieee80211_hw *hw,
++                                  void (*iterator)(void *data,
++                                                   struct ieee80211_sta *sta),
++                                  void *data)
++{
++      struct ieee80211_local *local = hw_to_local(hw);
++
++      lockdep_assert_wiphy(local->hw.wiphy);
++
++      __iterate_stations(local, iterator, data);
++}
++EXPORT_SYMBOL_GPL(ieee80211_iterate_stations_mtx);
++
+ struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev)
+ {
+       struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
+-- 
+2.39.5
+
diff --git a/queue-6.6/wifi-mac80211-export-ieee80211_purge_tx_queue-for-dr.patch b/queue-6.6/wifi-mac80211-export-ieee80211_purge_tx_queue-for-dr.patch
new file mode 100644 (file)
index 0000000..fec8044
--- /dev/null
@@ -0,0 +1,74 @@
+From c54d8898c482819efdeb76d19dd4b804a41a01e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Aug 2024 09:42:54 +0800
+Subject: wifi: mac80211: export ieee80211_purge_tx_queue() for drivers
+
+From: Ping-Ke Shih <pkshih@realtek.com>
+
+[ Upstream commit 53bc1b73b67836ac9867f93dee7a443986b4a94f ]
+
+Drivers need to purge TX SKB when stopping. Using skb_queue_purge() can't
+report TX status to mac80211, causing ieee80211_free_ack_frame() warns
+"Have pending ack frames!". Export ieee80211_purge_tx_queue() for drivers
+to not have to reimplement it.
+
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://patch.msgid.link/20240822014255.10211-1-pkshih@realtek.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Stable-dep-of: 3e5e4a801aaf ("wifi: rtw88: use ieee80211_purge_tx_queue() to purge TX skb")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/mac80211.h     | 13 +++++++++++++
+ net/mac80211/ieee80211_i.h |  2 --
+ net/mac80211/status.c      |  1 +
+ 3 files changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index 47ade676565d..901fe3ac139e 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -3039,6 +3039,19 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
+  */
+ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
++/**
++ * ieee80211_purge_tx_queue - purge TX skb queue
++ * @hw: the hardware
++ * @skbs: the skbs
++ *
++ * Free a set of transmit skbs. Use this function when device is going to stop
++ * but some transmit skbs without TX status are still queued.
++ * This function does not take the list lock and the caller must hold the
++ * relevant locks to use it.
++ */
++void ieee80211_purge_tx_queue(struct ieee80211_hw *hw,
++                            struct sk_buff_head *skbs);
++
+ /**
+  * DOC: Hardware crypto acceleration
+  *
+diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
+index daea061d0fc1..04c876d78d3b 100644
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -2057,8 +2057,6 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
+                                 u32 info_flags,
+                                 u32 ctrl_flags,
+                                 u64 *cookie);
+-void ieee80211_purge_tx_queue(struct ieee80211_hw *hw,
+-                            struct sk_buff_head *skbs);
+ struct sk_buff *
+ ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata,
+                             struct sk_buff *skb, u32 info_flags);
+diff --git a/net/mac80211/status.c b/net/mac80211/status.c
+index 44d83da60aee..9676ed15efec 100644
+--- a/net/mac80211/status.c
++++ b/net/mac80211/status.c
+@@ -1270,3 +1270,4 @@ void ieee80211_purge_tx_queue(struct ieee80211_hw *hw,
+       while ((skb = __skb_dequeue(skbs)))
+               ieee80211_free_txskb(hw, skb);
+ }
++EXPORT_SYMBOL(ieee80211_purge_tx_queue);
+-- 
+2.39.5
+
diff --git a/queue-6.6/wifi-rtw88-use-ieee80211_purge_tx_queue-to-purge-tx-.patch b/queue-6.6/wifi-rtw88-use-ieee80211_purge_tx_queue-to-purge-tx-.patch
new file mode 100644 (file)
index 0000000..4941f77
--- /dev/null
@@ -0,0 +1,128 @@
+From ccccfeb30c5f9c20a97d082b03113c367f4ca07d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Aug 2024 09:42:55 +0800
+Subject: wifi: rtw88: use ieee80211_purge_tx_queue() to purge TX skb
+
+From: Ping-Ke Shih <pkshih@realtek.com>
+
+[ Upstream commit 3e5e4a801aaf4283390cc34959c6c48f910ca5ea ]
+
+When removing kernel modules by:
+   rmmod rtw88_8723cs rtw88_8703b rtw88_8723x rtw88_sdio rtw88_core
+
+Driver uses skb_queue_purge() to purge TX skb, but not report tx status
+causing "Have pending ack frames!" warning. Use ieee80211_purge_tx_queue()
+to correct this.
+
+Since ieee80211_purge_tx_queue() doesn't take locks, to prevent racing
+between TX work and purge TX queue, flush and destroy TX work in advance.
+
+   wlan0: deauthenticating from aa:f5:fd:60:4c:a8 by local
+     choice (Reason: 3=DEAUTH_LEAVING)
+   ------------[ cut here ]------------
+   Have pending ack frames!
+   WARNING: CPU: 3 PID: 9232 at net/mac80211/main.c:1691
+       ieee80211_free_ack_frame+0x5c/0x90 [mac80211]
+   CPU: 3 PID: 9232 Comm: rmmod Tainted: G         C
+       6.10.1-200.fc40.aarch64 #1
+   Hardware name: pine64 Pine64 PinePhone Braveheart
+      (1.1)/Pine64 PinePhone Braveheart (1.1), BIOS 2024.01 01/01/2024
+   pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+   pc : ieee80211_free_ack_frame+0x5c/0x90 [mac80211]
+   lr : ieee80211_free_ack_frame+0x5c/0x90 [mac80211]
+   sp : ffff80008c1b37b0
+   x29: ffff80008c1b37b0 x28: ffff000003be8000 x27: 0000000000000000
+   x26: 0000000000000000 x25: ffff000003dc14b8 x24: ffff80008c1b37d0
+   x23: ffff000000ff9f80 x22: 0000000000000000 x21: 000000007fffffff
+   x20: ffff80007c7e93d8 x19: ffff00006e66f400 x18: 0000000000000000
+   x17: ffff7ffffd2b3000 x16: ffff800083fc0000 x15: 0000000000000000
+   x14: 0000000000000000 x13: 2173656d61726620 x12: 6b636120676e6964
+   x11: 0000000000000000 x10: 000000000000005d x9 : ffff8000802af2b0
+   x8 : ffff80008c1b3430 x7 : 0000000000000001 x6 : 0000000000000001
+   x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000
+   x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff000003be8000
+   Call trace:
+    ieee80211_free_ack_frame+0x5c/0x90 [mac80211]
+    idr_for_each+0x74/0x110
+    ieee80211_free_hw+0x44/0xe8 [mac80211]
+    rtw_sdio_remove+0x9c/0xc0 [rtw88_sdio]
+    sdio_bus_remove+0x44/0x180
+    device_remove+0x54/0x90
+    device_release_driver_internal+0x1d4/0x238
+    driver_detach+0x54/0xc0
+    bus_remove_driver+0x78/0x108
+    driver_unregister+0x38/0x78
+    sdio_unregister_driver+0x2c/0x40
+    rtw_8723cs_driver_exit+0x18/0x1000 [rtw88_8723cs]
+    __do_sys_delete_module.isra.0+0x190/0x338
+    __arm64_sys_delete_module+0x1c/0x30
+    invoke_syscall+0x74/0x100
+    el0_svc_common.constprop.0+0x48/0xf0
+    do_el0_svc+0x24/0x38
+    el0_svc+0x3c/0x158
+    el0t_64_sync_handler+0x120/0x138
+    el0t_64_sync+0x194/0x198
+   ---[ end trace 0000000000000000 ]---
+
+Reported-by: Peter Robinson <pbrobinson@gmail.com>
+Closes: https://lore.kernel.org/linux-wireless/CALeDE9OAa56KMzgknaCD3quOgYuEHFx9_hcT=OFgmMAb+8MPyA@mail.gmail.com/
+Tested-by: Ping-Ke Shih <pkshih@realtek.com> # 8723DU
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://patch.msgid.link/20240822014255.10211-2-pkshih@realtek.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw88/sdio.c | 6 +++---
+ drivers/net/wireless/realtek/rtw88/usb.c  | 5 +++--
+ 2 files changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c
+index 0cae5746f540..5bd1ee81210d 100644
+--- a/drivers/net/wireless/realtek/rtw88/sdio.c
++++ b/drivers/net/wireless/realtek/rtw88/sdio.c
+@@ -1295,12 +1295,12 @@ static void rtw_sdio_deinit_tx(struct rtw_dev *rtwdev)
+       struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
+       int i;
+-      for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++)
+-              skb_queue_purge(&rtwsdio->tx_queue[i]);
+-
+       flush_workqueue(rtwsdio->txwq);
+       destroy_workqueue(rtwsdio->txwq);
+       kfree(rtwsdio->tx_handler_data);
++
++      for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++)
++              ieee80211_purge_tx_queue(rtwdev->hw, &rtwsdio->tx_queue[i]);
+ }
+ int rtw_sdio_probe(struct sdio_func *sdio_func,
+diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c
+index 04a64afcbf8a..8f1d653282b7 100644
+--- a/drivers/net/wireless/realtek/rtw88/usb.c
++++ b/drivers/net/wireless/realtek/rtw88/usb.c
+@@ -416,10 +416,11 @@ static void rtw_usb_tx_handler(struct work_struct *work)
+ static void rtw_usb_tx_queue_purge(struct rtw_usb *rtwusb)
+ {
++      struct rtw_dev *rtwdev = rtwusb->rtwdev;
+       int i;
+       for (i = 0; i < ARRAY_SIZE(rtwusb->tx_queue); i++)
+-              skb_queue_purge(&rtwusb->tx_queue[i]);
++              ieee80211_purge_tx_queue(rtwdev->hw, &rtwusb->tx_queue[i]);
+ }
+ static void rtw_usb_write_port_complete(struct urb *urb)
+@@ -801,9 +802,9 @@ static void rtw_usb_deinit_tx(struct rtw_dev *rtwdev)
+ {
+       struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
+-      rtw_usb_tx_queue_purge(rtwusb);
+       flush_workqueue(rtwusb->txwq);
+       destroy_workqueue(rtwusb->txwq);
++      rtw_usb_tx_queue_purge(rtwusb);
+ }
+ static int rtw_usb_intf_init(struct rtw_dev *rtwdev,
+-- 
+2.39.5
+
diff --git a/queue-6.6/x86-crash-wrap-crash-dumping-code-into-crash-related.patch b/queue-6.6/x86-crash-wrap-crash-dumping-code-into-crash-related.patch
new file mode 100644 (file)
index 0000000..501e941
--- /dev/null
@@ -0,0 +1,264 @@
+From f42388f495a402ab0b4d8c4f8f5a3e49fcbe373b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jan 2024 13:12:46 +0800
+Subject: x86, crash: wrap crash dumping code into crash related ifdefs
+
+From: Baoquan He <bhe@redhat.com>
+
+[ Upstream commit a4eeb2176d89fdf2785851521577b94b31690a60 ]
+
+Now crash codes under kernel/ folder has been split out from kexec
+code, crash dumping can be separated from kexec reboot in config
+items on x86 with some adjustments.
+
+Here, also change some ifdefs or IS_ENABLED() check to more appropriate
+ones, e,g
+ - #ifdef CONFIG_KEXEC_CORE -> #ifdef CONFIG_CRASH_DUMP
+ - (!IS_ENABLED(CONFIG_KEXEC_CORE)) - > (!IS_ENABLED(CONFIG_CRASH_RESERVE))
+
+[bhe@redhat.com: don't nest CONFIG_CRASH_DUMP ifdef inside CONFIG_KEXEC_CODE ifdef scope]
+  Link: https://lore.kernel.org/all/SN6PR02MB4157931105FA68D72E3D3DB8D47B2@SN6PR02MB4157.namprd02.prod.outlook.com/T/#u
+Link: https://lkml.kernel.org/r/20240124051254.67105-7-bhe@redhat.com
+Signed-off-by: Baoquan He <bhe@redhat.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Eric W. Biederman <ebiederm@xmission.com>
+Cc: Hari Bathini <hbathini@linux.ibm.com>
+Cc: Pingfan Liu <piliu@redhat.com>
+Cc: Klara Modin <klarasmodin@gmail.com>
+Cc: Michael Kelley <mhklinux@outlook.com>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Stephen Rothwell <sfr@canb.auug.org.au>
+Cc: Yang Li <yang.lee@linux.alibaba.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: bcc80dec91ee ("x86/hyperv: Fix hv tsc page based sched_clock for hibernation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/Makefile           |  4 ++--
+ arch/x86/kernel/cpu/mshyperv.c     | 10 ++++++++--
+ arch/x86/kernel/kexec-bzimage64.c  |  4 ++++
+ arch/x86/kernel/kvm.c              |  4 ++--
+ arch/x86/kernel/machine_kexec_64.c |  3 +++
+ arch/x86/kernel/reboot.c           |  4 ++--
+ arch/x86/kernel/setup.c            |  2 +-
+ arch/x86/kernel/smp.c              |  2 +-
+ arch/x86/xen/enlighten_hvm.c       |  4 ++++
+ arch/x86/xen/mmu_pv.c              |  2 +-
+ 10 files changed, 28 insertions(+), 11 deletions(-)
+
+diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
+index 3269a0e23d3a..15fc9fc3dcf0 100644
+--- a/arch/x86/kernel/Makefile
++++ b/arch/x86/kernel/Makefile
+@@ -99,9 +99,9 @@ obj-$(CONFIG_TRACING)                += trace.o
+ obj-$(CONFIG_RETHOOK)         += rethook.o
+ obj-$(CONFIG_CRASH_CORE)      += crash_core_$(BITS).o
+ obj-$(CONFIG_KEXEC_CORE)      += machine_kexec_$(BITS).o
+-obj-$(CONFIG_KEXEC_CORE)      += relocate_kernel_$(BITS).o crash.o
++obj-$(CONFIG_KEXEC_CORE)      += relocate_kernel_$(BITS).o
+ obj-$(CONFIG_KEXEC_FILE)      += kexec-bzimage64.o
+-obj-$(CONFIG_CRASH_DUMP)      += crash_dump_$(BITS).o
++obj-$(CONFIG_CRASH_DUMP)      += crash_dump_$(BITS).o crash.o
+ obj-y                         += kprobes/
+ obj-$(CONFIG_MODULES)         += module.o
+ obj-$(CONFIG_X86_32)          += doublefault_32.o
+diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
+index bcb2d640a0cd..93e1cb4f7ff1 100644
+--- a/arch/x86/kernel/cpu/mshyperv.c
++++ b/arch/x86/kernel/cpu/mshyperv.c
+@@ -209,7 +209,9 @@ static void hv_machine_shutdown(void)
+       if (kexec_in_progress)
+               hyperv_cleanup();
+ }
++#endif /* CONFIG_KEXEC_CORE */
++#ifdef CONFIG_CRASH_DUMP
+ static void hv_machine_crash_shutdown(struct pt_regs *regs)
+ {
+       if (hv_crash_handler)
+@@ -221,7 +223,7 @@ static void hv_machine_crash_shutdown(struct pt_regs *regs)
+       /* Disable the hypercall page when there is only 1 active CPU. */
+       hyperv_cleanup();
+ }
+-#endif /* CONFIG_KEXEC_CORE */
++#endif /* CONFIG_CRASH_DUMP */
+ #endif /* CONFIG_HYPERV */
+ static uint32_t  __init ms_hyperv_platform(void)
+@@ -493,9 +495,13 @@ static void __init ms_hyperv_init_platform(void)
+       no_timer_check = 1;
+ #endif
+-#if IS_ENABLED(CONFIG_HYPERV) && defined(CONFIG_KEXEC_CORE)
++#if IS_ENABLED(CONFIG_HYPERV)
++#if defined(CONFIG_KEXEC_CORE)
+       machine_ops.shutdown = hv_machine_shutdown;
++#endif
++#if defined(CONFIG_CRASH_DUMP)
+       machine_ops.crash_shutdown = hv_machine_crash_shutdown;
++#endif
+ #endif
+       if (ms_hyperv.features & HV_ACCESS_TSC_INVARIANT) {
+               /*
+diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
+index a61c12c01270..0de509c02d18 100644
+--- a/arch/x86/kernel/kexec-bzimage64.c
++++ b/arch/x86/kernel/kexec-bzimage64.c
+@@ -263,11 +263,13 @@ setup_boot_parameters(struct kimage *image, struct boot_params *params,
+       memset(&params->hd0_info, 0, sizeof(params->hd0_info));
+       memset(&params->hd1_info, 0, sizeof(params->hd1_info));
++#ifdef CONFIG_CRASH_DUMP
+       if (image->type == KEXEC_TYPE_CRASH) {
+               ret = crash_setup_memmap_entries(image, params);
+               if (ret)
+                       return ret;
+       } else
++#endif
+               setup_e820_entries(params);
+       nr_e820_entries = params->e820_entries;
+@@ -428,12 +430,14 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
+               return ERR_PTR(-EINVAL);
+       }
++#ifdef CONFIG_CRASH_DUMP
+       /* Allocate and load backup region */
+       if (image->type == KEXEC_TYPE_CRASH) {
+               ret = crash_load_segments(image);
+               if (ret)
+                       return ERR_PTR(ret);
+       }
++#endif
+       /*
+        * Load purgatory. For 64bit entry point, purgatory  code can be
+diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
+index b8ab9ee5896c..38d88c8b56ec 100644
+--- a/arch/x86/kernel/kvm.c
++++ b/arch/x86/kernel/kvm.c
+@@ -769,7 +769,7 @@ static struct notifier_block kvm_pv_reboot_nb = {
+  * won't be valid. In cases like kexec, in which you install a new kernel, this
+  * means a random memory location will be kept being written.
+  */
+-#ifdef CONFIG_KEXEC_CORE
++#ifdef CONFIG_CRASH_DUMP
+ static void kvm_crash_shutdown(struct pt_regs *regs)
+ {
+       kvm_guest_cpu_offline(true);
+@@ -852,7 +852,7 @@ static void __init kvm_guest_init(void)
+       kvm_guest_cpu_init();
+ #endif
+-#ifdef CONFIG_KEXEC_CORE
++#ifdef CONFIG_CRASH_DUMP
+       machine_ops.crash_shutdown = kvm_crash_shutdown;
+ #endif
+diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
+index 2fa12d1dc676..aaeac2deb85d 100644
+--- a/arch/x86/kernel/machine_kexec_64.c
++++ b/arch/x86/kernel/machine_kexec_64.c
+@@ -545,6 +545,8 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
+ }
+ #endif /* CONFIG_KEXEC_FILE */
++#ifdef CONFIG_CRASH_DUMP
++
+ static int
+ kexec_mark_range(unsigned long start, unsigned long end, bool protect)
+ {
+@@ -589,6 +591,7 @@ void arch_kexec_unprotect_crashkres(void)
+ {
+       kexec_mark_crashkres(false);
+ }
++#endif
+ /*
+  * During a traditional boot under SME, SME will encrypt the kernel,
+diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
+index 830425e6d38e..f3130f762784 100644
+--- a/arch/x86/kernel/reboot.c
++++ b/arch/x86/kernel/reboot.c
+@@ -796,7 +796,7 @@ struct machine_ops machine_ops __ro_after_init = {
+       .emergency_restart = native_machine_emergency_restart,
+       .restart = native_machine_restart,
+       .halt = native_machine_halt,
+-#ifdef CONFIG_KEXEC_CORE
++#ifdef CONFIG_CRASH_DUMP
+       .crash_shutdown = native_machine_crash_shutdown,
+ #endif
+ };
+@@ -826,7 +826,7 @@ void machine_halt(void)
+       machine_ops.halt();
+ }
+-#ifdef CONFIG_KEXEC_CORE
++#ifdef CONFIG_CRASH_DUMP
+ void machine_crash_shutdown(struct pt_regs *regs)
+ {
+       machine_ops.crash_shutdown(regs);
+diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
+index eb129277dcdd..8bcecabd475b 100644
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -547,7 +547,7 @@ static void __init reserve_crashkernel(void)
+       bool high = false;
+       int ret;
+-      if (!IS_ENABLED(CONFIG_KEXEC_CORE))
++      if (!IS_ENABLED(CONFIG_CRASH_RESERVE))
+               return;
+       total_mem = memblock_phys_mem_size();
+diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
+index 96a771f9f930..52c3823b7211 100644
+--- a/arch/x86/kernel/smp.c
++++ b/arch/x86/kernel/smp.c
+@@ -282,7 +282,7 @@ struct smp_ops smp_ops = {
+       .smp_cpus_done          = native_smp_cpus_done,
+       .stop_other_cpus        = native_stop_other_cpus,
+-#if defined(CONFIG_KEXEC_CORE)
++#if defined(CONFIG_CRASH_DUMP)
+       .crash_stop_other_cpus  = kdump_nmi_shootdown_cpus,
+ #endif
+       .smp_send_reschedule    = native_smp_send_reschedule,
+diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c
+index 70be57e8f51c..ade22feee7ae 100644
+--- a/arch/x86/xen/enlighten_hvm.c
++++ b/arch/x86/xen/enlighten_hvm.c
+@@ -141,7 +141,9 @@ static void xen_hvm_shutdown(void)
+       if (kexec_in_progress)
+               xen_reboot(SHUTDOWN_soft_reset);
+ }
++#endif
++#ifdef CONFIG_CRASH_DUMP
+ static void xen_hvm_crash_shutdown(struct pt_regs *regs)
+ {
+       native_machine_crash_shutdown(regs);
+@@ -229,6 +231,8 @@ static void __init xen_hvm_guest_init(void)
+ #ifdef CONFIG_KEXEC_CORE
+       machine_ops.shutdown = xen_hvm_shutdown;
++#endif
++#ifdef CONFIG_CRASH_DUMP
+       machine_ops.crash_shutdown = xen_hvm_crash_shutdown;
+ #endif
+ }
+diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c
+index 6b201e64d8ab..bfd57d07f4b5 100644
+--- a/arch/x86/xen/mmu_pv.c
++++ b/arch/x86/xen/mmu_pv.c
+@@ -2517,7 +2517,7 @@ int xen_remap_pfn(struct vm_area_struct *vma, unsigned long addr,
+ }
+ EXPORT_SYMBOL_GPL(xen_remap_pfn);
+-#ifdef CONFIG_KEXEC_CORE
++#ifdef CONFIG_VMCORE_INFO
+ phys_addr_t paddr_vmcoreinfo_note(void)
+ {
+       if (xen_pv_domain())
+-- 
+2.39.5
+
diff --git a/queue-6.6/x86-fred-clear-wfe-in-missing-endbranch-cps.patch b/queue-6.6/x86-fred-clear-wfe-in-missing-endbranch-cps.patch
new file mode 100644 (file)
index 0000000..5fc6416
--- /dev/null
@@ -0,0 +1,103 @@
+From b1d1dadd691a4a9a0fb66ca9b12b28ba376b54c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Nov 2024 09:59:34 -0800
+Subject: x86/fred: Clear WFE in missing-ENDBRANCH #CPs
+
+From: Xin Li (Intel) <xin@zytor.com>
+
+[ Upstream commit dc81e556f2a017d681251ace21bf06c126d5a192 ]
+
+An indirect branch instruction sets the CPU indirect branch tracker
+(IBT) into WAIT_FOR_ENDBRANCH (WFE) state and WFE stays asserted
+across the instruction boundary.  When the decoder finds an
+inappropriate instruction while WFE is set ENDBR, the CPU raises a #CP
+fault.
+
+For the "kernel IBT no ENDBR" selftest where #CPs are deliberately
+triggered, the WFE state of the interrupted context needs to be
+cleared to let execution continue.  Otherwise when the CPU resumes
+from the instruction that just caused the previous #CP, another
+missing-ENDBRANCH #CP is raised and the CPU enters a dead loop.
+
+This is not a problem with IDT because it doesn't preserve WFE and
+IRET doesn't set WFE.  But FRED provides space on the entry stack
+(in an expanded CS area) to save and restore the WFE state, thus the
+WFE state is no longer clobbered, so software must clear it.
+
+Clear WFE to avoid dead looping in ibt_clear_fred_wfe() and the
+!ibt_fatal code path when execution is allowed to continue.
+
+Clobbering WFE in any other circumstance is a security-relevant bug.
+
+[ dhansen: changelog rewording ]
+
+Fixes: a5f6c2ace997 ("x86/shstk: Add user control-protection fault handler")
+Signed-off-by: Xin Li (Intel) <xin@zytor.com>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/all/20241113175934.3897541-1-xin%40zytor.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cet.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/arch/x86/kernel/cet.c b/arch/x86/kernel/cet.c
+index d2c732a34e5d..303bf74d175b 100644
+--- a/arch/x86/kernel/cet.c
++++ b/arch/x86/kernel/cet.c
+@@ -81,6 +81,34 @@ static void do_user_cp_fault(struct pt_regs *regs, unsigned long error_code)
+ static __ro_after_init bool ibt_fatal = true;
++/*
++ * By definition, all missing-ENDBRANCH #CPs are a result of WFE && !ENDBR.
++ *
++ * For the kernel IBT no ENDBR selftest where #CPs are deliberately triggered,
++ * the WFE state of the interrupted context needs to be cleared to let execution
++ * continue.  Otherwise when the CPU resumes from the instruction that just
++ * caused the previous #CP, another missing-ENDBRANCH #CP is raised and the CPU
++ * enters a dead loop.
++ *
++ * This is not a problem with IDT because it doesn't preserve WFE and IRET doesn't
++ * set WFE.  But FRED provides space on the entry stack (in an expanded CS area)
++ * to save and restore the WFE state, thus the WFE state is no longer clobbered,
++ * so software must clear it.
++ */
++static void ibt_clear_fred_wfe(struct pt_regs *regs)
++{
++      /*
++       * No need to do any FRED checks.
++       *
++       * For IDT event delivery, the high-order 48 bits of CS are pushed
++       * as 0s into the stack, and later IRET ignores these bits.
++       *
++       * For FRED, a test to check if fred_cs.wfe is set would be dropped
++       * by compilers.
++       */
++      regs->fred_cs.wfe = 0;
++}
++
+ static void do_kernel_cp_fault(struct pt_regs *regs, unsigned long error_code)
+ {
+       if ((error_code & CP_EC) != CP_ENDBR) {
+@@ -90,6 +118,7 @@ static void do_kernel_cp_fault(struct pt_regs *regs, unsigned long error_code)
+       if (unlikely(regs->ip == (unsigned long)&ibt_selftest_noendbr)) {
+               regs->ax = 0;
++              ibt_clear_fred_wfe(regs);
+               return;
+       }
+@@ -97,6 +126,7 @@ static void do_kernel_cp_fault(struct pt_regs *regs, unsigned long error_code)
+       if (!ibt_fatal) {
+               printk(KERN_DEFAULT CUT_HERE);
+               __warn(__FILE__, __LINE__, (void *)regs->ip, TAINT_WARN, regs, NULL);
++              ibt_clear_fred_wfe(regs);
+               return;
+       }
+       BUG();
+-- 
+2.39.5
+
diff --git a/queue-6.6/x86-hyperv-fix-hv-tsc-page-based-sched_clock-for-hib.patch b/queue-6.6/x86-hyperv-fix-hv-tsc-page-based-sched_clock-for-hib.patch
new file mode 100644 (file)
index 0000000..086294d
--- /dev/null
@@ -0,0 +1,177 @@
+From 4c8d45af23c2af5ce425e6ded5fed31e0ffcff2a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Sep 2024 11:09:17 +0530
+Subject: x86/hyperv: Fix hv tsc page based sched_clock for hibernation
+
+From: Naman Jain <namjain@linux.microsoft.com>
+
+[ Upstream commit bcc80dec91ee745b3d66f3e48f0ec2efdea97149 ]
+
+read_hv_sched_clock_tsc() assumes that the Hyper-V clock counter is
+bigger than the variable hv_sched_clock_offset, which is cached during
+early boot, but depending on the timing this assumption may be false
+when a hibernated VM starts again (the clock counter starts from 0
+again) and is resuming back (Note: hv_init_tsc_clocksource() is not
+called during hibernation/resume); consequently,
+read_hv_sched_clock_tsc() may return a negative integer (which is
+interpreted as a huge positive integer since the return type is u64)
+and new kernel messages are prefixed with huge timestamps before
+read_hv_sched_clock_tsc() grows big enough (which typically takes
+several seconds).
+
+Fix the issue by saving the Hyper-V clock counter just before the
+suspend, and using it to correct the hv_sched_clock_offset in
+resume. This makes hv tsc page based sched_clock continuous and ensures
+that post resume, it starts from where it left off during suspend.
+Override x86_platform.save_sched_clock_state and
+x86_platform.restore_sched_clock_state routines to correct this as soon
+as possible.
+
+Note: if Invariant TSC is available, the issue doesn't happen because
+1) we don't register read_hv_sched_clock_tsc() for sched clock:
+See commit e5313f1c5404 ("clocksource/drivers/hyper-v: Rework
+clocksource and sched clock setup");
+2) the common x86 code adjusts TSC similarly: see
+__restore_processor_state() ->  tsc_verify_tsc_adjust(true) and
+x86_platform.restore_sched_clock_state().
+
+Cc: stable@vger.kernel.org
+Fixes: 1349401ff1aa ("clocksource/drivers/hyper-v: Suspend/resume Hyper-V clocksource for hibernation")
+Co-developed-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
+Reviewed-by: Michael Kelley <mhklinux@outlook.com>
+Link: https://lore.kernel.org/r/20240917053917.76787-1-namjain@linux.microsoft.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Message-ID: <20240917053917.76787-1-namjain@linux.microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/mshyperv.c     | 58 ++++++++++++++++++++++++++++++
+ drivers/clocksource/hyperv_timer.c | 14 +++++++-
+ include/clocksource/hyperv_timer.h |  2 ++
+ 3 files changed, 73 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
+index 93e1cb4f7ff1..6328cf56e59b 100644
+--- a/arch/x86/kernel/cpu/mshyperv.c
++++ b/arch/x86/kernel/cpu/mshyperv.c
+@@ -224,6 +224,63 @@ static void hv_machine_crash_shutdown(struct pt_regs *regs)
+       hyperv_cleanup();
+ }
+ #endif /* CONFIG_CRASH_DUMP */
++
++static u64 hv_ref_counter_at_suspend;
++static void (*old_save_sched_clock_state)(void);
++static void (*old_restore_sched_clock_state)(void);
++
++/*
++ * Hyper-V clock counter resets during hibernation. Save and restore clock
++ * offset during suspend/resume, while also considering the time passed
++ * before suspend. This is to make sure that sched_clock using hv tsc page
++ * based clocksource, proceeds from where it left off during suspend and
++ * it shows correct time for the timestamps of kernel messages after resume.
++ */
++static void save_hv_clock_tsc_state(void)
++{
++      hv_ref_counter_at_suspend = hv_read_reference_counter();
++}
++
++static void restore_hv_clock_tsc_state(void)
++{
++      /*
++       * Adjust the offsets used by hv tsc clocksource to
++       * account for the time spent before hibernation.
++       * adjusted value = reference counter (time) at suspend
++       *                - reference counter (time) now.
++       */
++      hv_adj_sched_clock_offset(hv_ref_counter_at_suspend - hv_read_reference_counter());
++}
++
++/*
++ * Functions to override save_sched_clock_state and restore_sched_clock_state
++ * functions of x86_platform. The Hyper-V clock counter is reset during
++ * suspend-resume and the offset used to measure time needs to be
++ * corrected, post resume.
++ */
++static void hv_save_sched_clock_state(void)
++{
++      old_save_sched_clock_state();
++      save_hv_clock_tsc_state();
++}
++
++static void hv_restore_sched_clock_state(void)
++{
++      restore_hv_clock_tsc_state();
++      old_restore_sched_clock_state();
++}
++
++static void __init x86_setup_ops_for_tsc_pg_clock(void)
++{
++      if (!(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE))
++              return;
++
++      old_save_sched_clock_state = x86_platform.save_sched_clock_state;
++      x86_platform.save_sched_clock_state = hv_save_sched_clock_state;
++
++      old_restore_sched_clock_state = x86_platform.restore_sched_clock_state;
++      x86_platform.restore_sched_clock_state = hv_restore_sched_clock_state;
++}
+ #endif /* CONFIG_HYPERV */
+ static uint32_t  __init ms_hyperv_platform(void)
+@@ -578,6 +635,7 @@ static void __init ms_hyperv_init_platform(void)
+       /* Register Hyper-V specific clocksource */
+       hv_init_clocksource();
++      x86_setup_ops_for_tsc_pg_clock();
+       hv_vtl_init_platform();
+ #endif
+       /*
+diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c
+index 8ff7cd4e20bb..5eec1457e139 100644
+--- a/drivers/clocksource/hyperv_timer.c
++++ b/drivers/clocksource/hyperv_timer.c
+@@ -27,7 +27,8 @@
+ #include <asm/mshyperv.h>
+ static struct clock_event_device __percpu *hv_clock_event;
+-static u64 hv_sched_clock_offset __ro_after_init;
++/* Note: offset can hold negative values after hibernation. */
++static u64 hv_sched_clock_offset __read_mostly;
+ /*
+  * If false, we're using the old mechanism for stimer0 interrupts
+@@ -456,6 +457,17 @@ static void resume_hv_clock_tsc(struct clocksource *arg)
+       hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64);
+ }
++/*
++ * Called during resume from hibernation, from overridden
++ * x86_platform.restore_sched_clock_state routine. This is to adjust offsets
++ * used to calculate time for hv tsc page based sched_clock, to account for
++ * time spent before hibernation.
++ */
++void hv_adj_sched_clock_offset(u64 offset)
++{
++      hv_sched_clock_offset -= offset;
++}
++
+ #ifdef HAVE_VDSO_CLOCKMODE_HVCLOCK
+ static int hv_cs_enable(struct clocksource *cs)
+ {
+diff --git a/include/clocksource/hyperv_timer.h b/include/clocksource/hyperv_timer.h
+index 6cdc873ac907..aa5233b1eba9 100644
+--- a/include/clocksource/hyperv_timer.h
++++ b/include/clocksource/hyperv_timer.h
+@@ -38,6 +38,8 @@ extern void hv_remap_tsc_clocksource(void);
+ extern unsigned long hv_get_tsc_pfn(void);
+ extern struct ms_hyperv_tsc_page *hv_get_tsc_page(void);
++extern void hv_adj_sched_clock_offset(u64 offset);
++
+ static __always_inline bool
+ hv_read_tsc_page_tsc(const struct ms_hyperv_tsc_page *tsc_pg,
+                    u64 *cur_tsc, u64 *time)
+-- 
+2.39.5
+
diff --git a/queue-6.6/x86-mm-carve-out-invlpg-inline-asm-for-use-by-others.patch b/queue-6.6/x86-mm-carve-out-invlpg-inline-asm-for-use-by-others.patch
new file mode 100644 (file)
index 0000000..2939bee
--- /dev/null
@@ -0,0 +1,56 @@
+From e4f1455e41ec556226af9bad8598d04b714dab6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Nov 2024 12:21:32 +0100
+Subject: x86/mm: Carve out INVLPG inline asm for use by others
+
+From: Borislav Petkov (AMD) <bp@alien8.de>
+
+[ Upstream commit f1d84b59cbb9547c243d93991acf187fdbe9fbe9 ]
+
+No functional changes.
+
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Link: https://lore.kernel.org/r/ZyulbYuvrkshfsd2@antipodes
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/tlb.h | 4 ++++
+ arch/x86/mm/tlb.c          | 3 ++-
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/include/asm/tlb.h b/arch/x86/include/asm/tlb.h
+index 580636cdc257..4d3c9d00d6b6 100644
+--- a/arch/x86/include/asm/tlb.h
++++ b/arch/x86/include/asm/tlb.h
+@@ -34,4 +34,8 @@ static inline void __tlb_remove_table(void *table)
+       free_page_and_swap_cache(table);
+ }
++static inline void invlpg(unsigned long addr)
++{
++      asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
++}
+ #endif /* _ASM_X86_TLB_H */
+diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
+index 2fbae48f0b47..64f594826a28 100644
+--- a/arch/x86/mm/tlb.c
++++ b/arch/x86/mm/tlb.c
+@@ -19,6 +19,7 @@
+ #include <asm/cacheflush.h>
+ #include <asm/apic.h>
+ #include <asm/perf_event.h>
++#include <asm/tlb.h>
+ #include "mm_internal.h"
+@@ -1145,7 +1146,7 @@ STATIC_NOPV void native_flush_tlb_one_user(unsigned long addr)
+       bool cpu_pcide;
+       /* Flush 'addr' from the kernel PCID: */
+-      asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
++      invlpg(addr);
+       /* If PTI is off there is no user PCID and nothing to flush. */
+       if (!static_cpu_has(X86_FEATURE_PTI))
+-- 
+2.39.5
+
diff --git a/queue-6.6/x86-ptrace-add-fred-additional-information-to-the-pt.patch b/queue-6.6/x86-ptrace-add-fred-additional-information-to-the-pt.patch
new file mode 100644 (file)
index 0000000..a37f28a
--- /dev/null
@@ -0,0 +1,137 @@
+From f91e62282bab1b2f055166147b0b2323c710f23b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Dec 2023 02:50:03 -0800
+Subject: x86/ptrace: Add FRED additional information to the pt_regs structure
+
+From: Xin Li <xin3.li@intel.com>
+
+[ Upstream commit 3c77bf02d0c03beb3efdf7a5b427fb2e1a76c265 ]
+
+FRED defines additional information in the upper 48 bits of cs/ss
+fields. Therefore add the information definitions into the pt_regs
+structure.
+
+Specifically introduce a new structure fred_ss to denote the FRED flags
+above SS selector, which avoids FRED_SSX_ macros and makes the code
+simpler and easier to read.
+
+Suggested-by: Thomas Gleixner <tglx@linutronix.de>
+Originally-by: H. Peter Anvin (Intel) <hpa@zytor.com>
+Signed-off-by: Xin Li <xin3.li@intel.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Tested-by: Shan Kang <shan.kang@intel.com>
+Link: https://lore.kernel.org/r/20231205105030.8698-15-xin3.li@intel.com
+Stable-dep-of: dc81e556f2a0 ("x86/fred: Clear WFE in missing-ENDBRANCH #CPs")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/ptrace.h | 66 ++++++++++++++++++++++++++++++++---
+ 1 file changed, 61 insertions(+), 5 deletions(-)
+
+diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h
+index b268cd2a2d01..5a83fbd9bc0b 100644
+--- a/arch/x86/include/asm/ptrace.h
++++ b/arch/x86/include/asm/ptrace.h
+@@ -56,6 +56,50 @@ struct pt_regs {
+ #else /* __i386__ */
++struct fred_cs {
++              /* CS selector */
++      u64     cs      : 16,
++              /* Stack level at event time */
++              sl      :  2,
++              /* IBT in WAIT_FOR_ENDBRANCH state */
++              wfe     :  1,
++                      : 45;
++};
++
++struct fred_ss {
++              /* SS selector */
++      u64     ss      : 16,
++              /* STI state */
++              sti     :  1,
++              /* Set if syscall, sysenter or INT n */
++              swevent :  1,
++              /* Event is NMI type */
++              nmi     :  1,
++                      : 13,
++              /* Event vector */
++              vector  :  8,
++                      :  8,
++              /* Event type */
++              type    :  4,
++                      :  4,
++              /* Event was incident to enclave execution */
++              enclave :  1,
++              /* CPU was in long mode */
++              lm      :  1,
++              /*
++               * Nested exception during FRED delivery, not set
++               * for #DF.
++               */
++              nested  :  1,
++                      :  1,
++              /*
++               * The length of the instruction causing the event.
++               * Only set for INTO, INT1, INT3, INT n, SYSCALL
++               * and SYSENTER.  0 otherwise.
++               */
++              insnlen :  4;
++};
++
+ struct pt_regs {
+       /*
+        * C ABI says these regs are callee-preserved. They aren't saved on
+@@ -85,6 +129,12 @@ struct pt_regs {
+        * - the syscall number (syscall, sysenter, int80)
+        * - error_code stored by the CPU on traps and exceptions
+        * - the interrupt number for device interrupts
++       *
++       * A FRED stack frame starts here:
++       *   1) It _always_ includes an error code;
++       *
++       *   2) The return frame for ERET[US] starts here, but
++       *      the content of orig_ax is ignored.
+        */
+       unsigned long orig_ax;
+@@ -92,24 +142,30 @@ struct pt_regs {
+       unsigned long ip;
+       union {
+-              /* The full 64-bit data slot containing CS */
+-              u64             csx;
+               /* CS selector */
+               u16             cs;
++              /* The extended 64-bit data slot containing CS */
++              u64             csx;
++              /* The FRED CS extension */
++              struct fred_cs  fred_cs;
+       };
+       unsigned long flags;
+       unsigned long sp;
+       union {
+-              /* The full 64-bit data slot containing SS */
+-              u64             ssx;
+               /* SS selector */
+               u16             ss;
++              /* The extended 64-bit data slot containing SS */
++              u64             ssx;
++              /* The FRED SS extension */
++              struct fred_ss  fred_ss;
+       };
+       /*
+-       * Top of stack on IDT systems.
++       * Top of stack on IDT systems, while FRED systems have extra fields
++       * defined above for storing exception related information, e.g. CR2 or
++       * DR6.
+        */
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.6/x86-ptrace-cleanup-the-definition-of-the-pt_regs-str.patch b/queue-6.6/x86-ptrace-cleanup-the-definition-of-the-pt_regs-str.patch
new file mode 100644 (file)
index 0000000..157eed0
--- /dev/null
@@ -0,0 +1,144 @@
+From 07f03d87296dadf00cd3d6479a64060f042a13e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Dec 2023 02:50:02 -0800
+Subject: x86/ptrace: Cleanup the definition of the pt_regs structure
+
+From: Xin Li <xin3.li@intel.com>
+
+[ Upstream commit ee63291aa8287cb7ded767d340155fe8681fc075 ]
+
+struct pt_regs is hard to read because the member or section related
+comments are not aligned with the members.
+
+The 'cs' and 'ss' members of pt_regs are type of 'unsigned long' while
+in reality they are only 16-bit wide. This works so far as the
+remaining space is unused, but FRED will use the remaining bits for
+other purposes.
+
+To prepare for FRED:
+
+  - Cleanup the formatting
+  - Convert 'cs' and 'ss' to u16 and embed them into an union
+    with a u64
+  - Fixup the related printk() format strings
+
+Suggested-by: Thomas Gleixner <tglx@linutronix.de>
+Originally-by: H. Peter Anvin (Intel) <hpa@zytor.com>
+Signed-off-by: Xin Li <xin3.li@intel.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Tested-by: Shan Kang <shan.kang@intel.com>
+Link: https://lore.kernel.org/r/20231205105030.8698-14-xin3.li@intel.com
+Stable-dep-of: dc81e556f2a0 ("x86/fred: Clear WFE in missing-ENDBRANCH #CPs")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/entry/vsyscall/vsyscall_64.c |  2 +-
+ arch/x86/include/asm/ptrace.h         | 48 +++++++++++++++++++--------
+ arch/x86/kernel/process_64.c          |  2 +-
+ 3 files changed, 37 insertions(+), 15 deletions(-)
+
+diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c
+index 1245000a8792..2fb7d53cf333 100644
+--- a/arch/x86/entry/vsyscall/vsyscall_64.c
++++ b/arch/x86/entry/vsyscall/vsyscall_64.c
+@@ -76,7 +76,7 @@ static void warn_bad_vsyscall(const char *level, struct pt_regs *regs,
+       if (!show_unhandled_signals)
+               return;
+-      printk_ratelimited("%s%s[%d] %s ip:%lx cs:%lx sp:%lx ax:%lx si:%lx di:%lx\n",
++      printk_ratelimited("%s%s[%d] %s ip:%lx cs:%x sp:%lx ax:%lx si:%lx di:%lx\n",
+                          level, current->comm, task_pid_nr(current),
+                          message, regs->ip, regs->cs,
+                          regs->sp, regs->ax, regs->si, regs->di);
+diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h
+index f4db78b09c8f..b268cd2a2d01 100644
+--- a/arch/x86/include/asm/ptrace.h
++++ b/arch/x86/include/asm/ptrace.h
+@@ -57,17 +57,19 @@ struct pt_regs {
+ #else /* __i386__ */
+ struct pt_regs {
+-/*
+- * C ABI says these regs are callee-preserved. They aren't saved on kernel entry
+- * unless syscall needs a complete, fully filled "struct pt_regs".
+- */
++      /*
++       * C ABI says these regs are callee-preserved. They aren't saved on
++       * kernel entry unless syscall needs a complete, fully filled
++       * "struct pt_regs".
++       */
+       unsigned long r15;
+       unsigned long r14;
+       unsigned long r13;
+       unsigned long r12;
+       unsigned long bp;
+       unsigned long bx;
+-/* These regs are callee-clobbered. Always saved on kernel entry. */
++
++      /* These regs are callee-clobbered. Always saved on kernel entry. */
+       unsigned long r11;
+       unsigned long r10;
+       unsigned long r9;
+@@ -77,18 +79,38 @@ struct pt_regs {
+       unsigned long dx;
+       unsigned long si;
+       unsigned long di;
+-/*
+- * On syscall entry, this is syscall#. On CPU exception, this is error code.
+- * On hw interrupt, it's IRQ number:
+- */
++
++      /*
++       * orig_ax is used on entry for:
++       * - the syscall number (syscall, sysenter, int80)
++       * - error_code stored by the CPU on traps and exceptions
++       * - the interrupt number for device interrupts
++       */
+       unsigned long orig_ax;
+-/* Return frame for iretq */
++
++      /* The IRETQ return frame starts here */
+       unsigned long ip;
+-      unsigned long cs;
++
++      union {
++              /* The full 64-bit data slot containing CS */
++              u64             csx;
++              /* CS selector */
++              u16             cs;
++      };
++
+       unsigned long flags;
+       unsigned long sp;
+-      unsigned long ss;
+-/* top of stack page */
++
++      union {
++              /* The full 64-bit data slot containing SS */
++              u64             ssx;
++              /* SS selector */
++              u16             ss;
++      };
++
++      /*
++       * Top of stack on IDT systems.
++       */
+ };
+ #endif /* !__i386__ */
+diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
+index d595ef7c1de0..dd19a4db741a 100644
+--- a/arch/x86/kernel/process_64.c
++++ b/arch/x86/kernel/process_64.c
+@@ -117,7 +117,7 @@ void __show_regs(struct pt_regs *regs, enum show_regs_mode mode,
+       printk("%sFS:  %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n",
+              log_lvl, fs, fsindex, gs, gsindex, shadowgs);
+-      printk("%sCS:  %04lx DS: %04x ES: %04x CR0: %016lx\n",
++      printk("%sCS:  %04x DS: %04x ES: %04x CR0: %016lx\n",
+               log_lvl, regs->cs, ds, es, cr0);
+       printk("%sCR2: %016lx CR3: %016lx CR4: %016lx\n",
+               log_lvl, cr2, cr3, cr4);
+-- 
+2.39.5
+
diff --git a/queue-6.6/xhci-retry-stop-endpoint-on-buggy-nec-controllers.patch b/queue-6.6/xhci-retry-stop-endpoint-on-buggy-nec-controllers.patch
new file mode 100644 (file)
index 0000000..5453729
--- /dev/null
@@ -0,0 +1,57 @@
+From e508d0ec7a43a542274c68c15a620ce08cfdbc18 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 16:14:36 +0200
+Subject: xhci: retry Stop Endpoint on buggy NEC controllers
+
+From: Michal Pecio <michal.pecio@gmail.com>
+
+[ Upstream commit fd9d55d190c0e5fefd3a9165ea361809427885a1 ]
+
+Two NEC uPD720200 adapters have been observed to randomly misbehave:
+a Stop Endpoint command fails with Context Error, the Output Context
+indicates Stopped state, and the endpoint keeps running. Very often,
+Set TR Dequeue Pointer is seen to fail next with Context Error too,
+in addition to problems from unexpectedly completed cancelled work.
+
+The pathology is common on fast running isoc endpoints like uvcvideo,
+but has also been reproduced on a full-speed bulk endpoint of pl2303.
+It seems all EPs are affected, with risk proportional to their load.
+
+Reproduction involves receiving any kind of stream and closing it to
+make the device driver cancel URBs already queued in advance.
+
+Deal with it by retrying the command like in the Running state.
+
+Signed-off-by: Michal Pecio <michal.pecio@gmail.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20240229141438.619372-8-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: e21ebe51af68 ("xhci: Turn NEC specific quirk for handling Stop Endpoint errors generic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-ring.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index 50f588011400..7c3e39482834 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1180,6 +1180,15 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
+                               break;
+                       ep->ep_state &= ~EP_STOP_CMD_PENDING;
+                       return;
++              case EP_STATE_STOPPED:
++                      /*
++                       * NEC uPD720200 sometimes sets this state and fails with
++                       * Context Error while continuing to process TRBs.
++                       * Be conservative and trust EP_CTX_STATE on other chips.
++                       */
++                      if (!(xhci->quirks & XHCI_NEC_HOST))
++                              break;
++                      fallthrough;
+               case EP_STATE_RUNNING:
+                       /* Race, HW handled stop ep cmd before ep was running */
+                       xhci_dbg(xhci, "Stop ep completion ctx error, ep is running\n");
+-- 
+2.39.5
+
diff --git a/queue-6.6/xhci-turn-nec-specific-quirk-for-handling-stop-endpo.patch b/queue-6.6/xhci-turn-nec-specific-quirk-for-handling-stop-endpo.patch
new file mode 100644 (file)
index 0000000..2ced24b
--- /dev/null
@@ -0,0 +1,45 @@
+From f33d1477db7f55664b457f32fb7c0f4e6dc8209c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Dec 2024 12:21:21 +0200
+Subject: xhci: Turn NEC specific quirk for handling Stop Endpoint errors
+ generic
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+[ Upstream commit e21ebe51af688eb98fd6269240212a3c7300deea ]
+
+xHC hosts from several vendors have the same issue where endpoints start
+so slowly that a later queued 'Stop Endpoint' command may complete before
+endpoint is up and running.
+
+The 'Stop Endpoint' command fails with context state error as the endpoint
+still appears as  stopped.
+
+See commit 42b758137601 ("usb: xhci: Limit Stop Endpoint retries") for
+details
+
+CC: stable@vger.kernel.org
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20241217102122.2316814-2-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-ring.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index d318310e3135..729319d81753 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1203,8 +1203,6 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
+                        * Keep retrying until the EP starts and stops again, on
+                        * chips where this is known to help. Wait for 100ms.
+                        */
+-                      if (!(xhci->quirks & XHCI_NEC_HOST))
+-                              break;
+                       if (time_is_before_jiffies(ep->stop_time + msecs_to_jiffies(100)))
+                               break;
+                       fallthrough;
+-- 
+2.39.5
+