]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 21 Jul 2026 13:56:59 +0000 (15:56 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 21 Jul 2026 13:56:59 +0000 (15:56 +0200)
added patches:
acpi-nfit-core-fix-acpi_nfit_init-error-cleanup.patch
alsa-aoa-check-snd_ctl_new1-return-value.patch
audit-add-audit_log_nf_skb-helper-function.patch
audit-fix-potential-integer-overflow-in-audit_log_n_hex.patch
binder-fix-uaf-in-binder_free_transaction.patch
bitops-make-bytes_to_bits-treewide-available.patch
bluetooth-btintel-check-firmware-version-before-download.patch
bluetooth-btintel-fix-offset-calculation-boot-address-parameter.patch
bluetooth-btusb-fix-use-after-free-on-marvell-probe-failure.patch
bluetooth-btusb-fix-wakeup-source-leak-on-probe-failure.patch
bluetooth-l2cap-cancel-pending_rx_work-before-taking-conn-lock.patch
bluetooth-l2cap-fix-deadlock-in-l2cap_conn_del.patch
bluetooth-l2cap-fix-not-tracking-outstanding-tx-ident.patch
btrfs-do-not-trim-a-device-which-is-not-writeable.patch
cifs-create-a-new-shared-file-holding-smb2-pdu-definitions.patch
cifs-remove-check-of-list-iterator-against-head-past-the-loop-body.patch
cifs-remove-unused-server-parameter-from-calc_smb_size.patch
coresight-etb10-restore-atomic_t-for-shared-reading-state.patch
cpufreq-intel_pstate-sync-policy-cur-during-cpu-offline.patch
crypto-atmel-drop-explicit-initialization-of-struct-i2c_device_id-driver_data-to-0.patch
crypto-atmel-sha204a-drop-hwrng-quality-reduction-for-atsha204a.patch
crypto-atmel-sha204a-mark-of-related-data-as-maybe-unused.patch
crypto-qat-fix-restarting-state-leak-on-allocation-failure.patch
crypto-qat-fix-vf2pf-work-teardown-race-in-adf_disable_sriov.patch
crypto-qat-validate-rsa-crt-component-lengths.patch
drm-i2c-sil164-drop-no-op-remove-function.patch
gpio-pca953x-make-platform-teardown-callback-return-void.patch
hfs-hfsplus-fix-u32-overflow-in-check_and_correct_requested_length.patch
hfs-hfsplus-prevent-getting-negative-values-of-offset-length.patch
hid-add-haptics-page-defines.patch
hid-appleir-fix-uaf-on-pending-key_up_timer-in-remove.patch
hid-multitouch-fix-out-of-bounds-bit-access-on-mt_io_flags.patch
iio-common-st_sensors-honour-channel-endianness-in-read_axis_data.patch
iio-hid-sensor-rotation-fix-stale-or-zero-output-when-reading-raw-values.patch
iio-imu-adis-add-irqf_no_thread-to-non-fifo-trigger-irq.patch
iio-imu-inv_icm42600-fix-timestamping-by-limiting-fifo-reading.patch
iio-imu-inv_icm42600-make-timestamp-module-chip-independent.patch
iio-imu-inv_icm42600-stabilized-timestamp-in-interrupt.patch
iio-imu-inv_mpu6050-use-the-common-inv_sensors-timestamp-module.patch
iio-invensense-fix-timestamp-glitches-when-switching-frequency.patch
iio-invensense-remove-redundant-initialization-of-variable-period.patch
iio-make-invensense-timestamp-module-generic.patch
iio-move-inv_icm42600-timestamp-module-in-common.patch
leds-lm3601x-improve-error-reporting-for-problems-during-.remove.patch
leds-lm3697-remove-duplicated-error-reporting-in-.remove.patch
media-atomisp-replace-boolean-comparison-of-values-with-bool-variables.patch
media-staging-media-atomisp-fix-alignment-and-line-length-issues.patch
media-staging-media-atomisp-fix-sh_css.c-brace-coding-style-issues.patch
media-staging-media-atomisp-fix-the-rest-of-sh_css.c-brace-issues.patch
media-staging-media-atomisp-replace-if-else-clause-with-a-ternary.patch
netfilter-ebtables-use-vmalloc_array-to-improve-code.patch
netfilter-ebtables-zero-chainstack-array.patch
pci-add-kerneldoc-for-pci_resize_resource.patch
pci-altera-fix-resource-leaks-on-probe-failure.patch
pci-controller-use-dev_fwnode-instead-of-of_fwnode_handle.patch
pci-fix-restoring-bars-on-bar-resize-rollback-path.patch
pci-free-saved-list-without-holding-pci_bus_sem.patch
pci-imx6-fix-imx6sx_gpr12_pcie_test_powerdown-handling.patch
pci-mediatek-convert-bool-to-single-quirks-entry-and-bitmap.patch
pci-mediatek-fix-irq-domain-leak-when-port-fails-to-enable.patch
pci-move-resizable-bar-code-to-rebar.c.patch
pci-prevent-resource-tree-corruption-when-bar-resize-fails.patch
pci-skip-resizable-bar-restore-on-read-error.patch
proc-protect-ptrace_may_access-with-exec_update_lock-fd-links.patch
proc-protect-ptrace_may_access-with-exec_update_lock-part-1.patch
proc-rename-proc_setattr-to-proc_nochmod_setattr.patch
proc-use-generic-setattr-for-proc-pid-net.patch
serial-8250_mid-disable-dma-for-selected-platforms.patch
serial-8250_mid-remove-8250_pci-usage.patch
smb-client-fix-next-buffer-leak-in-receive_encrypted_standard.patch
smb-client-harden-posix-sid-length-parsing.patch
smb-client-mask-server-provided-mode-to-07777-in-modefromsid.patch
smb-client-restrict-implied-bcc-exemption-to-responses-without-data-area.patch
smb-client-use-unaligned-reads-in-parse_posix_ctxt.patch
smb2-small-refactor-in-smb2_check_message.patch
staging-media-atomisp-reduce-load_primary_binaries-stack-usage.patch
staging-rtl8723bs-clean-up-comparsions-to-null.patch
staging-rtl8723bs-fix-heap-buffer-overflow-in-rtw_cfg80211_set_wpa_ie.patch
staging-rtl8723bs-fix-oob-reads-in-ie-loops-in-issue_assocreq-and-join_cmd_hdl.patch
staging-rtl8723bs-fix-space-issues.patch
staging-rtl8723bs-fix-wep-length-underflow-and-oob-read-in-onauth.patch
staging-rtl8723bs-remove-5ghz-code-blocks.patch
staging-rtl8723bs-remove-5ghz-code-related-to-channel-plan-definition.patch
staging-rtl8723bs-remove-all-5ghz-network-types.patch
staging-rtl8723bs-remove-commented-out-condition.patch
staging-rtl8723bs-remove-commented-out-rt_assert-occurrences.patch
staging-rtl8723bs-remove-dbg_871x-log-argument.patch
staging-rtl8723bs-split-too-long-line.patch
usb-atm-ueagle-atm-wait-for-pre-firmware-load-in-.disconnect.patch
usb-free-iso-schedules-on-failed-submit.patch
usb-gadget-f_fs-initialize-reset_work-at-allocation-time.patch
usb-gadget-f_fs-tie-read_buffer-lifetime-to-ffs_epfile.patch
usb-gadget-f_printer-take-kref-only-for-successful-open.patch
usb-gadget-function-simplify-diagnostic-messaging-in-printer.patch
usb-iowarrior-remove-inherent-race-with-minor-number.patch
usb-serial-digi_acceleport-fix-write-buffer-corruption.patch
usb-typec-tcpm-fix-vdm-type-for-enter-mode-commands.patch
usb-typec-ucsi-ccg-fix-use-after-free-of-ucsi-on-remove.patch
vfio-pci-release-the-vga-arbiter-client-on-register_device-failure.patch
writeback-fix-race-between-cgroup_writeback_umount-and-inode_switch_wbs.patch
x.509-fix-validation-of-asn.1-certificate-header.patch
xfs-fix-unreachable-bigtime-check-in-dquot-flush-validation.patch
xfs-reflect-sb-features-in-xfs_mount.patch
xfs-use-null-daddr-for-unset-first-bad-log-block.patch

105 files changed:
queue-5.10/acpi-nfit-core-fix-acpi_nfit_init-error-cleanup.patch [new file with mode: 0644]
queue-5.10/alsa-aoa-check-snd_ctl_new1-return-value.patch [new file with mode: 0644]
queue-5.10/audit-add-audit_log_nf_skb-helper-function.patch [new file with mode: 0644]
queue-5.10/audit-fix-potential-integer-overflow-in-audit_log_n_hex.patch [new file with mode: 0644]
queue-5.10/binder-fix-uaf-in-binder_free_transaction.patch [new file with mode: 0644]
queue-5.10/bitops-make-bytes_to_bits-treewide-available.patch [new file with mode: 0644]
queue-5.10/bluetooth-btintel-check-firmware-version-before-download.patch [new file with mode: 0644]
queue-5.10/bluetooth-btintel-fix-offset-calculation-boot-address-parameter.patch [new file with mode: 0644]
queue-5.10/bluetooth-btusb-fix-use-after-free-on-marvell-probe-failure.patch [new file with mode: 0644]
queue-5.10/bluetooth-btusb-fix-wakeup-source-leak-on-probe-failure.patch [new file with mode: 0644]
queue-5.10/bluetooth-l2cap-cancel-pending_rx_work-before-taking-conn-lock.patch [new file with mode: 0644]
queue-5.10/bluetooth-l2cap-fix-deadlock-in-l2cap_conn_del.patch [new file with mode: 0644]
queue-5.10/bluetooth-l2cap-fix-not-tracking-outstanding-tx-ident.patch [new file with mode: 0644]
queue-5.10/btrfs-do-not-trim-a-device-which-is-not-writeable.patch [new file with mode: 0644]
queue-5.10/cifs-create-a-new-shared-file-holding-smb2-pdu-definitions.patch [new file with mode: 0644]
queue-5.10/cifs-remove-check-of-list-iterator-against-head-past-the-loop-body.patch [new file with mode: 0644]
queue-5.10/cifs-remove-unused-server-parameter-from-calc_smb_size.patch [new file with mode: 0644]
queue-5.10/coresight-etb10-restore-atomic_t-for-shared-reading-state.patch [new file with mode: 0644]
queue-5.10/cpufreq-intel_pstate-sync-policy-cur-during-cpu-offline.patch [new file with mode: 0644]
queue-5.10/crypto-atmel-drop-explicit-initialization-of-struct-i2c_device_id-driver_data-to-0.patch [new file with mode: 0644]
queue-5.10/crypto-atmel-sha204a-drop-hwrng-quality-reduction-for-atsha204a.patch [new file with mode: 0644]
queue-5.10/crypto-atmel-sha204a-mark-of-related-data-as-maybe-unused.patch [new file with mode: 0644]
queue-5.10/crypto-qat-fix-restarting-state-leak-on-allocation-failure.patch [new file with mode: 0644]
queue-5.10/crypto-qat-fix-vf2pf-work-teardown-race-in-adf_disable_sriov.patch [new file with mode: 0644]
queue-5.10/crypto-qat-validate-rsa-crt-component-lengths.patch [new file with mode: 0644]
queue-5.10/drm-i2c-sil164-drop-no-op-remove-function.patch [new file with mode: 0644]
queue-5.10/gpio-pca953x-make-platform-teardown-callback-return-void.patch [new file with mode: 0644]
queue-5.10/hfs-hfsplus-fix-u32-overflow-in-check_and_correct_requested_length.patch [new file with mode: 0644]
queue-5.10/hfs-hfsplus-prevent-getting-negative-values-of-offset-length.patch [new file with mode: 0644]
queue-5.10/hid-add-haptics-page-defines.patch [new file with mode: 0644]
queue-5.10/hid-appleir-fix-uaf-on-pending-key_up_timer-in-remove.patch [new file with mode: 0644]
queue-5.10/hid-multitouch-fix-out-of-bounds-bit-access-on-mt_io_flags.patch [new file with mode: 0644]
queue-5.10/iio-common-st_sensors-honour-channel-endianness-in-read_axis_data.patch [new file with mode: 0644]
queue-5.10/iio-hid-sensor-rotation-fix-stale-or-zero-output-when-reading-raw-values.patch [new file with mode: 0644]
queue-5.10/iio-imu-adis-add-irqf_no_thread-to-non-fifo-trigger-irq.patch [new file with mode: 0644]
queue-5.10/iio-imu-inv_icm42600-fix-timestamping-by-limiting-fifo-reading.patch [new file with mode: 0644]
queue-5.10/iio-imu-inv_icm42600-make-timestamp-module-chip-independent.patch [new file with mode: 0644]
queue-5.10/iio-imu-inv_icm42600-stabilized-timestamp-in-interrupt.patch [new file with mode: 0644]
queue-5.10/iio-imu-inv_mpu6050-use-the-common-inv_sensors-timestamp-module.patch [new file with mode: 0644]
queue-5.10/iio-invensense-fix-timestamp-glitches-when-switching-frequency.patch [new file with mode: 0644]
queue-5.10/iio-invensense-remove-redundant-initialization-of-variable-period.patch [new file with mode: 0644]
queue-5.10/iio-make-invensense-timestamp-module-generic.patch [new file with mode: 0644]
queue-5.10/iio-move-inv_icm42600-timestamp-module-in-common.patch [new file with mode: 0644]
queue-5.10/leds-lm3601x-improve-error-reporting-for-problems-during-.remove.patch [new file with mode: 0644]
queue-5.10/leds-lm3697-remove-duplicated-error-reporting-in-.remove.patch [new file with mode: 0644]
queue-5.10/media-atomisp-replace-boolean-comparison-of-values-with-bool-variables.patch [new file with mode: 0644]
queue-5.10/media-staging-media-atomisp-fix-alignment-and-line-length-issues.patch [new file with mode: 0644]
queue-5.10/media-staging-media-atomisp-fix-sh_css.c-brace-coding-style-issues.patch [new file with mode: 0644]
queue-5.10/media-staging-media-atomisp-fix-the-rest-of-sh_css.c-brace-issues.patch [new file with mode: 0644]
queue-5.10/media-staging-media-atomisp-replace-if-else-clause-with-a-ternary.patch [new file with mode: 0644]
queue-5.10/netfilter-ebtables-use-vmalloc_array-to-improve-code.patch [new file with mode: 0644]
queue-5.10/netfilter-ebtables-zero-chainstack-array.patch [new file with mode: 0644]
queue-5.10/pci-add-kerneldoc-for-pci_resize_resource.patch [new file with mode: 0644]
queue-5.10/pci-altera-fix-resource-leaks-on-probe-failure.patch [new file with mode: 0644]
queue-5.10/pci-controller-use-dev_fwnode-instead-of-of_fwnode_handle.patch [new file with mode: 0644]
queue-5.10/pci-fix-restoring-bars-on-bar-resize-rollback-path.patch [new file with mode: 0644]
queue-5.10/pci-free-saved-list-without-holding-pci_bus_sem.patch [new file with mode: 0644]
queue-5.10/pci-imx6-fix-imx6sx_gpr12_pcie_test_powerdown-handling.patch [new file with mode: 0644]
queue-5.10/pci-mediatek-convert-bool-to-single-quirks-entry-and-bitmap.patch [new file with mode: 0644]
queue-5.10/pci-mediatek-fix-irq-domain-leak-when-port-fails-to-enable.patch [new file with mode: 0644]
queue-5.10/pci-move-resizable-bar-code-to-rebar.c.patch [new file with mode: 0644]
queue-5.10/pci-prevent-resource-tree-corruption-when-bar-resize-fails.patch [new file with mode: 0644]
queue-5.10/pci-skip-resizable-bar-restore-on-read-error.patch [new file with mode: 0644]
queue-5.10/proc-protect-ptrace_may_access-with-exec_update_lock-fd-links.patch [new file with mode: 0644]
queue-5.10/proc-protect-ptrace_may_access-with-exec_update_lock-part-1.patch [new file with mode: 0644]
queue-5.10/proc-rename-proc_setattr-to-proc_nochmod_setattr.patch [new file with mode: 0644]
queue-5.10/proc-use-generic-setattr-for-proc-pid-net.patch [new file with mode: 0644]
queue-5.10/serial-8250_mid-disable-dma-for-selected-platforms.patch [new file with mode: 0644]
queue-5.10/serial-8250_mid-remove-8250_pci-usage.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/smb-client-fix-next-buffer-leak-in-receive_encrypted_standard.patch [new file with mode: 0644]
queue-5.10/smb-client-harden-posix-sid-length-parsing.patch [new file with mode: 0644]
queue-5.10/smb-client-mask-server-provided-mode-to-07777-in-modefromsid.patch [new file with mode: 0644]
queue-5.10/smb-client-restrict-implied-bcc-exemption-to-responses-without-data-area.patch [new file with mode: 0644]
queue-5.10/smb-client-use-unaligned-reads-in-parse_posix_ctxt.patch [new file with mode: 0644]
queue-5.10/smb2-small-refactor-in-smb2_check_message.patch [new file with mode: 0644]
queue-5.10/staging-media-atomisp-reduce-load_primary_binaries-stack-usage.patch [new file with mode: 0644]
queue-5.10/staging-rtl8723bs-clean-up-comparsions-to-null.patch [new file with mode: 0644]
queue-5.10/staging-rtl8723bs-fix-heap-buffer-overflow-in-rtw_cfg80211_set_wpa_ie.patch [new file with mode: 0644]
queue-5.10/staging-rtl8723bs-fix-oob-reads-in-ie-loops-in-issue_assocreq-and-join_cmd_hdl.patch [new file with mode: 0644]
queue-5.10/staging-rtl8723bs-fix-space-issues.patch [new file with mode: 0644]
queue-5.10/staging-rtl8723bs-fix-wep-length-underflow-and-oob-read-in-onauth.patch [new file with mode: 0644]
queue-5.10/staging-rtl8723bs-remove-5ghz-code-blocks.patch [new file with mode: 0644]
queue-5.10/staging-rtl8723bs-remove-5ghz-code-related-to-channel-plan-definition.patch [new file with mode: 0644]
queue-5.10/staging-rtl8723bs-remove-all-5ghz-network-types.patch [new file with mode: 0644]
queue-5.10/staging-rtl8723bs-remove-commented-out-condition.patch [new file with mode: 0644]
queue-5.10/staging-rtl8723bs-remove-commented-out-rt_assert-occurrences.patch [new file with mode: 0644]
queue-5.10/staging-rtl8723bs-remove-dbg_871x-log-argument.patch [new file with mode: 0644]
queue-5.10/staging-rtl8723bs-split-too-long-line.patch [new file with mode: 0644]
queue-5.10/usb-atm-ueagle-atm-wait-for-pre-firmware-load-in-.disconnect.patch [new file with mode: 0644]
queue-5.10/usb-free-iso-schedules-on-failed-submit.patch [new file with mode: 0644]
queue-5.10/usb-gadget-f_fs-initialize-reset_work-at-allocation-time.patch [new file with mode: 0644]
queue-5.10/usb-gadget-f_fs-tie-read_buffer-lifetime-to-ffs_epfile.patch [new file with mode: 0644]
queue-5.10/usb-gadget-f_printer-take-kref-only-for-successful-open.patch [new file with mode: 0644]
queue-5.10/usb-gadget-function-simplify-diagnostic-messaging-in-printer.patch [new file with mode: 0644]
queue-5.10/usb-iowarrior-remove-inherent-race-with-minor-number.patch [new file with mode: 0644]
queue-5.10/usb-serial-digi_acceleport-fix-write-buffer-corruption.patch [new file with mode: 0644]
queue-5.10/usb-typec-tcpm-fix-vdm-type-for-enter-mode-commands.patch [new file with mode: 0644]
queue-5.10/usb-typec-ucsi-ccg-fix-use-after-free-of-ucsi-on-remove.patch [new file with mode: 0644]
queue-5.10/vfio-pci-release-the-vga-arbiter-client-on-register_device-failure.patch [new file with mode: 0644]
queue-5.10/writeback-fix-race-between-cgroup_writeback_umount-and-inode_switch_wbs.patch [new file with mode: 0644]
queue-5.10/x.509-fix-validation-of-asn.1-certificate-header.patch [new file with mode: 0644]
queue-5.10/xfs-fix-unreachable-bigtime-check-in-dquot-flush-validation.patch [new file with mode: 0644]
queue-5.10/xfs-reflect-sb-features-in-xfs_mount.patch [new file with mode: 0644]
queue-5.10/xfs-use-null-daddr-for-unset-first-bad-log-block.patch [new file with mode: 0644]

diff --git a/queue-5.10/acpi-nfit-core-fix-acpi_nfit_init-error-cleanup.patch b/queue-5.10/acpi-nfit-core-fix-acpi_nfit_init-error-cleanup.patch
new file mode 100644 (file)
index 0000000..8c11482
--- /dev/null
@@ -0,0 +1,103 @@
+From stable+bounces-273267-greg=kroah.com@vger.kernel.org Fri Jul 10 17:49:15 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 11:42:05 -0400
+Subject: ACPI: NFIT: core: Fix acpi_nfit_init() error cleanup
+To: stable@vger.kernel.org
+Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>, Dave Jiang <dave.jiang@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260710154205.284338-1-sashal@kernel.org>
+
+From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 38bf27511ef41bffebd157ec3eba41fc89ba59cd ]
+
+If acpi_nfit_init() fails after adding the acpi_desc object to the
+acpi_descs list, that object is never removed from that list because
+the acpi_nfit_shutdown() devm action is not added for the NFIT device
+in that case.  Next, the acpi_nfit_init() failure causes
+acpi_nfit_probe() to fail, the acpi_desc object is freed, and a
+dangling pointer is left behind in the acpi_descs.  Any subsequent
+ACPI Machine Check Exception will trigger nfit_handle_mce() which
+iterates over acpi_descs and so a use-after-free will occur.
+
+Moreover, if acpi_nfit_probe() returns 0 after installing a notify
+handler for the NFIT device and without allocating the acpi_desc
+object and setting the NFIT device's driver data pointer, the
+acpi_desc object will be allocated by acpi_nfit_update_notify()
+and acpi_nfit_init() will be called to initialize it.  Regardless
+of whether or not acpi_nfit_init() fails in that case, the
+acpi_nfit_shutdown() devm action is not added for the NFIT device
+and acpi_desc is never removed from the acpi_descs list.  If the
+acpi_desc object is freed subsequently on driver removal, any
+subsequent ACPI MCE will lead to a use-after-free like in the
+previous case.
+
+To address the first issue mentioned above, make acpi_nfit_probe()
+call acpi_nfit_shutdown() directly on acpi_nfit_init() failures and
+to address the other one, add a remove callback to the driver and
+make it call acpi_nfit_shutdown().  Also, since it is now possible to
+pass NULL to acpi_nfit_shutdown() or the acpi_desc object passed to it
+may not have been initialized, add checks against NULL for acpi_desc and
+its nvdimm_bus field to that function and make acpi_nfit_unregister()
+clear the latter after unregistering the NVDIMM bus.
+
+Fixes: a61fe6f7902e ("nfit, tools/testing/nvdimm: unify common init for acpi_nfit_desc")
+Fixes: fbabd829fe76 ("acpi, nfit: fix module unload vs workqueue shutdown race")
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Cc: All applicable <stable@vger.kernel.org>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://patch.msgid.link/1963615.tdWV9SEqCh@rafael.j.wysocki
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/acpi/nfit/core.c |   15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+--- a/drivers/acpi/nfit/core.c
++++ b/drivers/acpi/nfit/core.c
+@@ -3456,6 +3456,8 @@ static void acpi_nfit_unregister(void *d
+       struct acpi_nfit_desc *acpi_desc = data;
+       nvdimm_bus_unregister(acpi_desc->nvdimm_bus);
++      /* The nvdimm_bus object may have been freed, so clear the pointer. */
++      acpi_desc->nvdimm_bus = NULL;
+ }
+ int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, void *data, acpi_size sz)
+@@ -3680,7 +3682,10 @@ static void acpi_nfit_put_table(void *ta
+ void acpi_nfit_shutdown(void *data)
+ {
+       struct acpi_nfit_desc *acpi_desc = data;
+-      struct device *bus_dev = to_nvdimm_bus_dev(acpi_desc->nvdimm_bus);
++      struct device *bus_dev;
++
++      if (!acpi_desc || !acpi_desc->nvdimm_bus)
++              return;
+       /*
+        * Destruct under acpi_desc_lock so that nfit_handle_mce does not
+@@ -3695,6 +3700,7 @@ void acpi_nfit_shutdown(void *data)
+       mutex_unlock(&acpi_desc->init_mutex);
+       cancel_delayed_work_sync(&acpi_desc->dwork);
++      bus_dev = to_nvdimm_bus_dev(acpi_desc->nvdimm_bus);
+       /*
+        * Bounce the nvdimm bus lock to make sure any in-flight
+        * acpi_nfit_ars_rescan() submissions have had a chance to
+@@ -3762,13 +3768,14 @@ static int acpi_nfit_add(struct acpi_dev
+                               sz - sizeof(struct acpi_table_nfit));
+       if (rc)
+-              return rc;
+-      return devm_add_action_or_reset(dev, acpi_nfit_shutdown, acpi_desc);
++              acpi_nfit_shutdown(acpi_desc);
++
++      return rc;
+ }
+ static int acpi_nfit_remove(struct acpi_device *adev)
+ {
+-      /* see acpi_nfit_unregister */
++      acpi_nfit_shutdown(dev_get_drvdata(&adev->dev));
+       return 0;
+ }
diff --git a/queue-5.10/alsa-aoa-check-snd_ctl_new1-return-value.patch b/queue-5.10/alsa-aoa-check-snd_ctl_new1-return-value.patch
new file mode 100644 (file)
index 0000000..6e4d13a
--- /dev/null
@@ -0,0 +1,61 @@
+From stable+bounces-274100-greg=kroah.com@vger.kernel.org Tue Jul 14 05:06:56 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:53 -0400
+Subject: ALSA: aoa: check snd_ctl_new1() return value
+To: stable@vger.kernel.org
+Cc: Zhao Dongdong <zhaodongdong@kylinos.cn>, Takashi Iwai <tiwai@suse.de>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030453.2382650-1-sashal@kernel.org>
+
+From: Zhao Dongdong <zhaodongdong@kylinos.cn>
+
+[ Upstream commit 8df560fefe6fed6a20b7e06720eeaeccec349ac0 ]
+
+snd_ctl_new1() can return NULL when memory allocation fails. In
+layout.c, the function does not check the return value before
+dereferencing ctl->id.name or passing to aoa_snd_ctl_add(), which can
+lead to a NULL pointer dereference.
+
+Add NULL checks after snd_ctl_new1() calls and return early if any
+fails.
+
+Assisted-by: Opencode:DeepSeek-V4-Flash
+Cc: stable@vger.kernel.org
+Fixes: f3d9478b2ce4 ("[ALSA] snd-aoa: add snd-aoa")
+Signed-off-by: Zhao Dongdong <zhaodongdong@kylinos.cn>
+Link: https://patch.msgid.link/tencent_35F3A25FEEBF190A2E15ED787754C57E3708@qq.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/aoa/fabrics/layout.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/sound/aoa/fabrics/layout.c
++++ b/sound/aoa/fabrics/layout.c
+@@ -947,6 +947,8 @@ static void layout_attached_codec(struct
+                       if (lineout == 1)
+                               ldev->gpio.methods->set_lineout(codec->gpio, 1);
+                       ctl = snd_ctl_new1(&lineout_ctl, codec->gpio);
++                      if (!ctl)
++                              return;
+                       if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
+                               strlcpy(ctl->id.name,
+                                       "Headphone Switch", sizeof(ctl->id.name));
+@@ -961,6 +963,8 @@ static void layout_attached_codec(struct
+                       if (ldev->have_lineout_detect) {
+                               ctl = snd_ctl_new1(&lineout_detect_choice,
+                                                  ldev);
++                              if (!ctl)
++                                      return;
+                               if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
+                                       strlcpy(ctl->id.name,
+                                               "Headphone Detect Autoswitch",
+@@ -968,6 +972,8 @@ static void layout_attached_codec(struct
+                               aoa_snd_ctl_add(ctl);
+                               ctl = snd_ctl_new1(&lineout_detected,
+                                                  ldev);
++                              if (!ctl)
++                                      return;
+                               if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
+                                       strlcpy(ctl->id.name,
+                                               "Headphone Detected",
diff --git a/queue-5.10/audit-add-audit_log_nf_skb-helper-function.patch b/queue-5.10/audit-add-audit_log_nf_skb-helper-function.patch
new file mode 100644 (file)
index 0000000..b5e9dc1
--- /dev/null
@@ -0,0 +1,296 @@
+From stable+bounces-278575-greg=kroah.com@vger.kernel.org Tue Jul 21 14:02:36 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jul 2026 07:56:41 -0400
+Subject: audit: add audit_log_nf_skb helper function
+To: stable@vger.kernel.org
+Cc: Ricardo Robaina <rrobaina@redhat.com>, Florian Westphal <fw@strlen.de>, Paul Moore <paul@paul-moore.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260721115642.3699441-1-sashal@kernel.org>
+
+From: Ricardo Robaina <rrobaina@redhat.com>
+
+[ Upstream commit f19590b07cb620be1fcd5474c49515e21a05d406 ]
+
+Netfilter code (net/netfilter/nft_log.c and net/netfilter/xt_AUDIT.c)
+have to be kept in sync. Both source files had duplicated versions of
+audit_ip4() and audit_ip6() functions, which can result in lack of
+consistency and/or duplicated work.
+
+This patch adds a helper function in audit.c that can be called by
+netfilter code commonly, aiming to improve maintainability and
+consistency.
+
+Suggested-by: Florian Westphal <fw@strlen.de>
+Suggested-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: Ricardo Robaina <rrobaina@redhat.com>
+Acked-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Stable-dep-of: 65dfde57d1e2 ("audit: fix potential integer overflow in audit_log_n_hex()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/audit.h    |    8 +++++
+ kernel/audit.c           |   64 +++++++++++++++++++++++++++++++++++++++++++++++
+ net/netfilter/nft_log.c  |   58 ------------------------------------------
+ net/netfilter/xt_AUDIT.c |   58 ------------------------------------------
+ 4 files changed, 74 insertions(+), 114 deletions(-)
+
+--- a/include/linux/audit.h
++++ b/include/linux/audit.h
+@@ -186,6 +186,8 @@ extern void                    audit_log_lost(const ch
+ extern int audit_log_task_context(struct audit_buffer *ab);
+ extern void audit_log_task_info(struct audit_buffer *ab);
++extern int audit_log_nf_skb(struct audit_buffer *ab,
++                          const struct sk_buff *skb, u8 nfproto);
+ extern int                audit_update_lsm_rules(void);
+@@ -251,6 +253,12 @@ static inline int audit_log_task_context
+ static inline void audit_log_task_info(struct audit_buffer *ab)
+ { }
++static inline int audit_log_nf_skb(struct audit_buffer *ab,
++                                 const struct sk_buff *skb, u8 nfproto)
++{
++      return 0;
++}
++
+ static inline kuid_t audit_get_loginuid(struct task_struct *tsk)
+ {
+       return INVALID_UID;
+--- a/kernel/audit.c
++++ b/kernel/audit.c
+@@ -59,6 +59,8 @@
+ #include <linux/freezer.h>
+ #include <linux/pid_namespace.h>
+ #include <net/netns/generic.h>
++#include <net/ip.h>
++#include <net/ipv6.h>
+ #include "audit.h"
+@@ -2304,6 +2306,68 @@ void audit_log_path_denied(int type, con
+       audit_log_end(ab);
+ }
++int audit_log_nf_skb(struct audit_buffer *ab,
++                   const struct sk_buff *skb, u8 nfproto)
++{
++      /* find the IP protocol in the case of NFPROTO_BRIDGE */
++      if (nfproto == NFPROTO_BRIDGE) {
++              switch (eth_hdr(skb)->h_proto) {
++              case htons(ETH_P_IP):
++                      nfproto = NFPROTO_IPV4;
++                      break;
++              case htons(ETH_P_IPV6):
++                      nfproto = NFPROTO_IPV6;
++                      break;
++              default:
++                      goto unknown_proto;
++              }
++      }
++
++      switch (nfproto) {
++      case NFPROTO_IPV4: {
++              struct iphdr iph;
++              const struct iphdr *ih;
++
++              ih = skb_header_pointer(skb, skb_network_offset(skb),
++                                      sizeof(iph), &iph);
++              if (!ih)
++                      return -ENOMEM;
++
++              audit_log_format(ab, " saddr=%pI4 daddr=%pI4 proto=%hhu",
++                               &ih->saddr, &ih->daddr, ih->protocol);
++              break;
++      }
++      case NFPROTO_IPV6: {
++              struct ipv6hdr iph;
++              const struct ipv6hdr *ih;
++              u8 nexthdr;
++              __be16 frag_off;
++
++              ih = skb_header_pointer(skb, skb_network_offset(skb),
++                                      sizeof(iph), &iph);
++              if (!ih)
++                      return -ENOMEM;
++
++              nexthdr = ih->nexthdr;
++              ipv6_skip_exthdr(skb, skb_network_offset(skb) + sizeof(iph),
++                               &nexthdr, &frag_off);
++
++              audit_log_format(ab, " saddr=%pI6c daddr=%pI6c proto=%hhu",
++                               &ih->saddr, &ih->daddr, nexthdr);
++              break;
++      }
++      default:
++              goto unknown_proto;
++      }
++
++      return 0;
++
++unknown_proto:
++      audit_log_format(ab, " saddr=? daddr=? proto=?");
++      return -EPFNOSUPPORT;
++}
++EXPORT_SYMBOL(audit_log_nf_skb);
++
+ /* global counter which is incremented every time something logs in */
+ static atomic_t session_id = ATOMIC_INIT(0);
+--- a/net/netfilter/nft_log.c
++++ b/net/netfilter/nft_log.c
+@@ -26,46 +26,10 @@ struct nft_log {
+       char                    *prefix;
+ };
+-static bool audit_ip4(struct audit_buffer *ab, struct sk_buff *skb)
+-{
+-      struct iphdr _iph;
+-      const struct iphdr *ih;
+-
+-      ih = skb_header_pointer(skb, skb_network_offset(skb), sizeof(_iph), &_iph);
+-      if (!ih)
+-              return false;
+-
+-      audit_log_format(ab, " saddr=%pI4 daddr=%pI4 proto=%hhu",
+-                       &ih->saddr, &ih->daddr, ih->protocol);
+-
+-      return true;
+-}
+-
+-static bool audit_ip6(struct audit_buffer *ab, struct sk_buff *skb)
+-{
+-      struct ipv6hdr _ip6h;
+-      const struct ipv6hdr *ih;
+-      u8 nexthdr;
+-      __be16 frag_off;
+-
+-      ih = skb_header_pointer(skb, skb_network_offset(skb), sizeof(_ip6h), &_ip6h);
+-      if (!ih)
+-              return false;
+-
+-      nexthdr = ih->nexthdr;
+-      ipv6_skip_exthdr(skb, skb_network_offset(skb) + sizeof(_ip6h), &nexthdr, &frag_off);
+-
+-      audit_log_format(ab, " saddr=%pI6c daddr=%pI6c proto=%hhu",
+-                       &ih->saddr, &ih->daddr, nexthdr);
+-
+-      return true;
+-}
+-
+ static void nft_log_eval_audit(const struct nft_pktinfo *pkt)
+ {
+       struct sk_buff *skb = pkt->skb;
+       struct audit_buffer *ab;
+-      int fam = -1;
+       if (!audit_enabled)
+               return;
+@@ -76,27 +40,7 @@ static void nft_log_eval_audit(const str
+       audit_log_format(ab, "mark=%#x", skb->mark);
+-      switch (nft_pf(pkt)) {
+-      case NFPROTO_BRIDGE:
+-              switch (eth_hdr(skb)->h_proto) {
+-              case htons(ETH_P_IP):
+-                      fam = audit_ip4(ab, skb) ? NFPROTO_IPV4 : -1;
+-                      break;
+-              case htons(ETH_P_IPV6):
+-                      fam = audit_ip6(ab, skb) ? NFPROTO_IPV6 : -1;
+-                      break;
+-              }
+-              break;
+-      case NFPROTO_IPV4:
+-              fam = audit_ip4(ab, skb) ? NFPROTO_IPV4 : -1;
+-              break;
+-      case NFPROTO_IPV6:
+-              fam = audit_ip6(ab, skb) ? NFPROTO_IPV6 : -1;
+-              break;
+-      }
+-
+-      if (fam == -1)
+-              audit_log_format(ab, " saddr=? daddr=? proto=-1");
++      audit_log_nf_skb(ab, skb, nft_pf(pkt));
+       audit_log_end(ab);
+ }
+--- a/net/netfilter/xt_AUDIT.c
++++ b/net/netfilter/xt_AUDIT.c
+@@ -28,46 +28,10 @@ MODULE_ALIAS("ip6t_AUDIT");
+ MODULE_ALIAS("ebt_AUDIT");
+ MODULE_ALIAS("arpt_AUDIT");
+-static bool audit_ip4(struct audit_buffer *ab, struct sk_buff *skb)
+-{
+-      struct iphdr _iph;
+-      const struct iphdr *ih;
+-
+-      ih = skb_header_pointer(skb, skb_network_offset(skb), sizeof(_iph), &_iph);
+-      if (!ih)
+-              return false;
+-
+-      audit_log_format(ab, " saddr=%pI4 daddr=%pI4 proto=%hhu",
+-                       &ih->saddr, &ih->daddr, ih->protocol);
+-
+-      return true;
+-}
+-
+-static bool audit_ip6(struct audit_buffer *ab, struct sk_buff *skb)
+-{
+-      struct ipv6hdr _ip6h;
+-      const struct ipv6hdr *ih;
+-      u8 nexthdr;
+-      __be16 frag_off;
+-
+-      ih = skb_header_pointer(skb, skb_network_offset(skb), sizeof(_ip6h), &_ip6h);
+-      if (!ih)
+-              return false;
+-
+-      nexthdr = ih->nexthdr;
+-      ipv6_skip_exthdr(skb, skb_network_offset(skb) + sizeof(_ip6h), &nexthdr, &frag_off);
+-
+-      audit_log_format(ab, " saddr=%pI6c daddr=%pI6c proto=%hhu",
+-                       &ih->saddr, &ih->daddr, nexthdr);
+-
+-      return true;
+-}
+-
+ static unsigned int
+ audit_tg(struct sk_buff *skb, const struct xt_action_param *par)
+ {
+       struct audit_buffer *ab;
+-      int fam = -1;
+       if (audit_enabled == AUDIT_OFF)
+               goto errout;
+@@ -77,27 +41,7 @@ audit_tg(struct sk_buff *skb, const stru
+       audit_log_format(ab, "mark=%#x", skb->mark);
+-      switch (xt_family(par)) {
+-      case NFPROTO_BRIDGE:
+-              switch (eth_hdr(skb)->h_proto) {
+-              case htons(ETH_P_IP):
+-                      fam = audit_ip4(ab, skb) ? NFPROTO_IPV4 : -1;
+-                      break;
+-              case htons(ETH_P_IPV6):
+-                      fam = audit_ip6(ab, skb) ? NFPROTO_IPV6 : -1;
+-                      break;
+-              }
+-              break;
+-      case NFPROTO_IPV4:
+-              fam = audit_ip4(ab, skb) ? NFPROTO_IPV4 : -1;
+-              break;
+-      case NFPROTO_IPV6:
+-              fam = audit_ip6(ab, skb) ? NFPROTO_IPV6 : -1;
+-              break;
+-      }
+-
+-      if (fam == -1)
+-              audit_log_format(ab, " saddr=? daddr=? proto=-1");
++      audit_log_nf_skb(ab, skb, xt_family(par));
+       audit_log_end(ab);
diff --git a/queue-5.10/audit-fix-potential-integer-overflow-in-audit_log_n_hex.patch b/queue-5.10/audit-fix-potential-integer-overflow-in-audit_log_n_hex.patch
new file mode 100644 (file)
index 0000000..6dfa054
--- /dev/null
@@ -0,0 +1,66 @@
+From stable+bounces-278576-greg=kroah.com@vger.kernel.org Tue Jul 21 13:56:50 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jul 2026 07:56:42 -0400
+Subject: audit: fix potential integer overflow in audit_log_n_hex()
+To: stable@vger.kernel.org
+Cc: Ricardo Robaina <rrobaina@redhat.com>, Richard Guy Briggs <rgb@redhat.com>, Paul Moore <paul@paul-moore.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260721115642.3699441-2-sashal@kernel.org>
+
+From: Ricardo Robaina <rrobaina@redhat.com>
+
+[ Upstream commit 65dfde57d1e29ce2b76fc23dd565eccd5c0bc0f0 ]
+
+The function calculates new_len as len << 1 for hex encoding. This
+has two overflow risks: the shift itself can overflow when len is
+large, and the result can be truncated when assigned to new_len
+(declared as int) from the size_t calculation.
+
+Fix by using check_shl_overflow() to catch shift overflow and
+changing new_len and loop counter i to size_t to prevent truncation.
+
+Cc: stable@vger.kernel.org
+Fixes: 168b7173959f ("AUDIT: Clean up logging of untrusted strings")
+Reviewed-by: Richard Guy Briggs <rgb@redhat.com>
+Signed-off-by: Ricardo Robaina <rrobaina@redhat.com>
+[PM: remove vertical whitspace noise]
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/audit.c |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/kernel/audit.c
++++ b/kernel/audit.c
+@@ -61,6 +61,7 @@
+ #include <net/netns/generic.h>
+ #include <net/ip.h>
+ #include <net/ipv6.h>
++#include <linux/overflow.h>
+ #include "audit.h"
+@@ -2034,7 +2035,8 @@ void audit_log_format(struct audit_buffe
+ void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf,
+               size_t len)
+ {
+-      int i, avail, new_len;
++      int avail;
++      size_t i, new_len;
+       unsigned char *ptr;
+       struct sk_buff *skb;
+@@ -2044,7 +2046,12 @@ void audit_log_n_hex(struct audit_buffer
+       BUG_ON(!ab->skb);
+       skb = ab->skb;
+       avail = skb_tailroom(skb);
+-      new_len = len<<1;
++
++      if (check_shl_overflow(len, 1, &new_len)) {
++              audit_log_format(ab, "?");
++              return;
++      }
++
+       if (new_len >= avail) {
+               /* Round the buffer request up to the next multiple */
+               new_len = AUDIT_BUFSIZ*(((new_len-avail)/AUDIT_BUFSIZ) + 1);
diff --git a/queue-5.10/binder-fix-uaf-in-binder_free_transaction.patch b/queue-5.10/binder-fix-uaf-in-binder_free_transaction.patch
new file mode 100644 (file)
index 0000000..6f121c9
--- /dev/null
@@ -0,0 +1,99 @@
+From sashal@kernel.org Tue Jul 14 16:06:19 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 10:06:12 -0400
+Subject: binder: fix UAF in binder_free_transaction()
+To: stable@vger.kernel.org
+Cc: Carlos Llamas <cmllamas@google.com>, stable <stable@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714140612.2729754-2-sashal@kernel.org>
+
+From: Carlos Llamas <cmllamas@google.com>
+
+[ Upstream commit f223d27a546c1e1f48d38fd67760e78f068fe8c4 ]
+
+In binder_free_transaction(), the t->to_proc is read under the t->lock.
+However, once the t->lock is dropped, the to_proc can die in parallel.
+This leads to a use-after-free error when we attempt to acquire its
+inner lock right afterwards:
+
+  ==================================================================
+  BUG: KASAN: slab-use-after-free in _raw_spin_lock+0xe4/0x1a0
+  Write of size 4 at addr ffff00001125da70 by task B/672
+
+  CPU: 20 UID: 0 PID: 672 Comm: B Not tainted 7.1.0-rc6-00284-g8e65320d91cd #4 PREEMPT
+  Hardware name: linux,dummy-virt (DT)
+  Call trace:
+   _raw_spin_lock+0xe4/0x1a0
+   binder_free_transaction+0x8c/0x320
+   binder_send_failed_reply+0x21c/0x2f8
+   binder_thread_release+0x488/0x7e0
+   binder_ioctl+0x12c0/0x29a0
+  [...]
+
+  Allocated by task 675:
+   __kmalloc_cache_noprof+0x174/0x444
+   binder_open+0x118/0xb70
+   do_dentry_open+0x374/0x1040
+   vfs_open+0x58/0x3bc
+  [...]
+
+  Freed by task 212:
+   __kasan_slab_free+0x58/0x80
+   kfree+0x1a0/0x4a4
+   binder_proc_dec_tmpref+0x32c/0x5e0
+   binder_deferred_func+0xc48/0x104c
+   process_one_work+0x53c/0xbc0
+  [...]
+  ==================================================================
+
+To prevent this, pin the target thread (t->to_thread) to guarantee the
+target process remains alive. Undelivered transactions without a target
+thread are already safe, as the target process can only be the current
+context in those paths.
+
+Cc: stable <stable@kernel.org>
+Reported-by: Alice Ryhl <aliceryhl@google.com>
+Closes: https://lore.kernel.org/all/aikJKVuny_eOivwN@google.com/
+Fixes: a370003cc301 ("binder: fix possible UAF when freeing buffer")
+Signed-off-by: Carlos Llamas <cmllamas@google.com>
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Link: https://patch.msgid.link/20260619185233.2194678-2-cmllamas@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/android/binder.c |   13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/drivers/android/binder.c
++++ b/drivers/android/binder.c
+@@ -1909,10 +1909,19 @@ static void binder_free_txn_fixups(struc
+ static void binder_free_transaction(struct binder_transaction *t)
+ {
++      struct binder_thread *target_thread;
+       struct binder_proc *target_proc;
+       spin_lock(&t->lock);
+       target_proc = t->to_proc;
++      target_thread = t->to_thread;
++      /*
++       * Pin target_thread to keep target_proc alive. Undelivered
++       * transactions with !target_thread are safe, as target_proc
++       * can only be the current context there.
++       */
++      if (target_thread)
++              atomic_inc(&target_thread->tmp_ref);
+       spin_unlock(&t->lock);
+       if (target_proc) {
+@@ -1921,6 +1930,10 @@ static void binder_free_transaction(stru
+                       t->buffer->transaction = NULL;
+               binder_inner_proc_unlock(target_proc);
+       }
++
++      if (target_thread)
++              binder_thread_dec_tmpref(target_thread);
++
+       /*
+        * If the transaction has no target_proc, then
+        * t->buffer->transaction has already been cleared.
diff --git a/queue-5.10/bitops-make-bytes_to_bits-treewide-available.patch b/queue-5.10/bitops-make-bytes_to_bits-treewide-available.patch
new file mode 100644 (file)
index 0000000..a2cd575
--- /dev/null
@@ -0,0 +1,90 @@
+From stable+bounces-274097-greg=kroah.com@vger.kernel.org Tue Jul 14 05:06:45 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:47 -0400
+Subject: bitops: make BYTES_TO_BITS() treewide-available
+To: stable@vger.kernel.org
+Cc: Alexander Lobakin <aleksander.lobakin@intel.com>, Andy Shevchenko <andriy.shevchenko@linux.intel.com>, Przemek Kitszel <przemyslaw.kitszel@intel.com>, Yury Norov <yury.norov@gmail.com>, "David S. Miller" <davem@davemloft.net>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030448.2382602-1-sashal@kernel.org>
+
+From: Alexander Lobakin <aleksander.lobakin@intel.com>
+
+[ Upstream commit 7d8296b250f2eed73f1758607926d4d258dea5d4 ]
+
+Avoid open-coding that simple expression each time by moving
+BYTES_TO_BITS() from the probes code to <linux/bitops.h> to export
+it to the rest of the kernel.
+Simplify the macro while at it. `BITS_PER_LONG / sizeof(long)` always
+equals to %BITS_PER_BYTE, regardless of the target architecture.
+Do the same for the tools ecosystem as well (incl. its version of
+bitops.h). The previous implementation had its implicit type of long,
+while the new one is int, so adjust the format literal accordingly in
+the perf code.
+
+Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Acked-by: Yury Norov <yury.norov@gmail.com>
+Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 55052184ac90 ("iio: common: st_sensors: honour channel endianness in read_axis_data")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/bitops.h         |    2 ++
+ kernel/trace/trace_probe.c     |    2 --
+ tools/include/linux/bitops.h   |    2 ++
+ tools/perf/util/probe-finder.c |    4 +---
+ 4 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/include/linux/bitops.h
++++ b/include/linux/bitops.h
+@@ -17,6 +17,8 @@
+ #define BITS_TO_U32(nr)               DIV_ROUND_UP(nr, BITS_PER_TYPE(u32))
+ #define BITS_TO_BYTES(nr)     DIV_ROUND_UP(nr, BITS_PER_TYPE(char))
++#define BYTES_TO_BITS(nb)     ((nb) * BITS_PER_BYTE)
++
+ extern unsigned int __sw_hweight8(unsigned int w);
+ extern unsigned int __sw_hweight16(unsigned int w);
+ extern unsigned int __sw_hweight32(unsigned int w);
+--- a/kernel/trace/trace_probe.c
++++ b/kernel/trace/trace_probe.c
+@@ -503,8 +503,6 @@ parse_probe_arg(char *arg, const struct
+       return ret;
+ }
+-#define BYTES_TO_BITS(nb)     ((BITS_PER_LONG * (nb)) / sizeof(long))
+-
+ /* Bitfield type needs to be parsed into a fetch function */
+ static int __parse_bitfield_probe_arg(const char *bf,
+                                     const struct fetch_type *t,
+--- a/tools/include/linux/bitops.h
++++ b/tools/include/linux/bitops.h
+@@ -20,6 +20,8 @@
+ #define BITS_TO_U32(nr)               DIV_ROUND_UP(nr, BITS_PER_TYPE(u32))
+ #define BITS_TO_BYTES(nr)     DIV_ROUND_UP(nr, BITS_PER_TYPE(char))
++#define BYTES_TO_BITS(nb)     ((nb) * BITS_PER_BYTE)
++
+ extern unsigned int __sw_hweight8(unsigned int w);
+ extern unsigned int __sw_hweight16(unsigned int w);
+ extern unsigned int __sw_hweight32(unsigned int w);
+--- a/tools/perf/util/probe-finder.c
++++ b/tools/perf/util/probe-finder.c
+@@ -299,8 +299,6 @@ static_var:
+       return ret2;
+ }
+-#define BYTES_TO_BITS(nb)     ((nb) * BITS_PER_LONG / sizeof(long))
+-
+ static int convert_variable_type(Dwarf_Die *vr_die,
+                                struct probe_trace_arg *tvar,
+                                const char *cast, bool user_access)
+@@ -330,7 +328,7 @@ static int convert_variable_type(Dwarf_D
+               total = dwarf_bytesize(vr_die);
+               if (boffs < 0 || total < 0)
+                       return -ENOENT;
+-              ret = snprintf(buf, 16, "b%d@%d/%zd", bsize, boffs,
++              ret = snprintf(buf, 16, "b%d@%d/%d", bsize, boffs,
+                               BYTES_TO_BITS(total));
+               goto formatted;
+       }
diff --git a/queue-5.10/bluetooth-btintel-check-firmware-version-before-download.patch b/queue-5.10/bluetooth-btintel-check-firmware-version-before-download.patch
new file mode 100644 (file)
index 0000000..d611683
--- /dev/null
@@ -0,0 +1,263 @@
+From stable+bounces-274238-greg=kroah.com@vger.kernel.org Tue Jul 14 15:31:51 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 09:26:48 -0400
+Subject: Bluetooth: btintel: Check firmware version before download
+To: stable@vger.kernel.org
+Cc: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Tedd Ho-Jeong An <tedd.an@intel.com>, Marcel Holtmann <marcel@holtmann.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714132650.2663656-2-sashal@kernel.org>
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit ac0565462e330a2b762ca5849a4140b29d725786 ]
+
+This checks the firmware build number, week and year against the
+repective loaded version. If details are a match, skip the download
+process.
+
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Tested-by: Tedd Ho-Jeong An <tedd.an@intel.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Stable-dep-of: c5b600a3c05b ("Bluetooth: btusb: fix use-after-free on marvell probe failure")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bluetooth/btintel.c   |  106 +++++++++++++++++++++++++++++++++---------
+ drivers/bluetooth/btintel.h   |    5 +
+ drivers/bluetooth/btusb.c     |    9 +++
+ drivers/bluetooth/hci_intel.c |    7 +-
+ 4 files changed, 101 insertions(+), 26 deletions(-)
+
+--- a/drivers/bluetooth/btintel.c
++++ b/drivers/bluetooth/btintel.c
+@@ -24,6 +24,14 @@
+ #define ECDSA_OFFSET          644
+ #define ECDSA_HEADER_LEN      320
++#define CMD_WRITE_BOOT_PARAMS 0xfc0e
++struct cmd_write_boot_params {
++      u32 boot_addr;
++      u8  fw_build_num;
++      u8  fw_build_ww;
++      u8  fw_build_yy;
++} __packed;
++
+ int btintel_check_bdaddr(struct hci_dev *hdev)
+ {
+       struct hci_rp_read_bd_addr *bda;
+@@ -841,7 +849,7 @@ static int btintel_sfi_ecdsa_header_secu
+ static int btintel_download_firmware_payload(struct hci_dev *hdev,
+                                            const struct firmware *fw,
+-                                           u32 *boot_param, size_t offset)
++                                           size_t offset)
+ {
+       int err;
+       const u8 *fw_ptr;
+@@ -854,21 +862,6 @@ static int btintel_download_firmware_pay
+       while (fw_ptr - fw->data < fw->size) {
+               struct hci_command_hdr *cmd = (void *)(fw_ptr + frag_len);
+-              /* Each SKU has a different reset parameter to use in the
+-               * HCI_Intel_Reset command and it is embedded in the firmware
+-               * data. So, instead of using static value per SKU, check
+-               * the firmware data and save it for later use.
+-               */
+-              if (le16_to_cpu(cmd->opcode) == 0xfc0e) {
+-                      /* The boot parameter is the first 32-bit value
+-                       * and rest of 3 octets are reserved.
+-                       */
+-                      *boot_param = get_unaligned_le32(fw_ptr + frag_len +
+-                                                       sizeof(*cmd));
+-
+-                      bt_dev_dbg(hdev, "boot_param=0x%x", *boot_param);
+-              }
+-
+               frag_len += sizeof(*cmd) + cmd->plen;
+               /* The parameter length of the secure send command requires
+@@ -897,28 +890,101 @@ done:
+       return err;
+ }
++static bool btintel_firmware_version(struct hci_dev *hdev,
++                                   u8 num, u8 ww, u8 yy,
++                                   const struct firmware *fw,
++                                   u32 *boot_addr)
++{
++      const u8 *fw_ptr;
++
++      fw_ptr = fw->data;
++
++      while (fw_ptr - fw->data < fw->size) {
++              struct hci_command_hdr *cmd = (void *)(fw_ptr);
++
++              /* Each SKU has a different reset parameter to use in the
++               * HCI_Intel_Reset command and it is embedded in the firmware
++               * data. So, instead of using static value per SKU, check
++               * the firmware data and save it for later use.
++               */
++              if (le16_to_cpu(cmd->opcode) == CMD_WRITE_BOOT_PARAMS) {
++                      struct cmd_write_boot_params *params;
++
++                      params = (void *)(fw_ptr + sizeof(*cmd));
++
++                      bt_dev_info(hdev, "Boot Address: 0x%x",
++                                  le32_to_cpu(params->boot_addr));
++
++                      bt_dev_info(hdev, "Firmware Version: %u-%u.%u",
++                                  params->fw_build_num, params->fw_build_ww,
++                                  params->fw_build_yy);
++
++                      return (num == params->fw_build_num &&
++                              ww == params->fw_build_ww &&
++                              yy == params->fw_build_yy);
++              }
++
++              fw_ptr += sizeof(*cmd) + cmd->plen;
++      }
++
++      return false;
++}
++
+ int btintel_download_firmware(struct hci_dev *hdev,
++                            struct intel_version *ver,
+                             const struct firmware *fw,
+                             u32 *boot_param)
+ {
+       int err;
++      /* SfP and WsP don't seem to update the firmware version on file
++       * so version checking is currently not possible.
++       */
++      switch (ver->hw_variant) {
++      case 0x0b:      /* SfP */
++      case 0x0c:      /* WsP */
++              /* Skip version checking */
++              break;
++      default:
++              /* Skip download if firmware has the same version */
++              if (btintel_firmware_version(hdev, ver->fw_build_num,
++                                           ver->fw_build_ww, ver->fw_build_yy,
++                                           fw, boot_param)) {
++                      bt_dev_info(hdev, "Firmware already loaded");
++                      /* Return -EALREADY to indicate that the firmware has
++                       * already been loaded.
++                       */
++                      return -EALREADY;
++              }
++      }
++
+       err = btintel_sfi_rsa_header_secure_send(hdev, fw);
+       if (err)
+               return err;
+-      return btintel_download_firmware_payload(hdev, fw, boot_param,
+-                                               RSA_HEADER_LEN);
++      return btintel_download_firmware_payload(hdev, fw, RSA_HEADER_LEN);
+ }
+ EXPORT_SYMBOL_GPL(btintel_download_firmware);
+ int btintel_download_firmware_newgen(struct hci_dev *hdev,
++                                   struct intel_version_tlv *ver,
+                                    const struct firmware *fw, u32 *boot_param,
+                                    u8 hw_variant, u8 sbe_type)
+ {
+       int err;
+       u32 css_header_ver;
++      /* Skip download if firmware has the same version */
++      if (btintel_firmware_version(hdev, ver->min_fw_build_nn,
++                                   ver->min_fw_build_cw, ver->min_fw_build_yy,
++                                   fw, boot_param)) {
++              bt_dev_info(hdev, "Firmware already loaded");
++              /* Return -EALREADY to indicate that firmware has already been
++               * loaded.
++               */
++              return -EALREADY;
++      }
++
+       /* iBT hardware variants 0x0b, 0x0c, 0x11, 0x12, 0x13, 0x14 support
+        * only RSA secure boot engine. Hence, the corresponding sfi file will
+        * have RSA header of 644 bytes followed by Command Buffer.
+@@ -948,7 +1014,7 @@ int btintel_download_firmware_newgen(str
+               if (err)
+                       return err;
+-              err = btintel_download_firmware_payload(hdev, fw, boot_param, RSA_HEADER_LEN);
++              err = btintel_download_firmware_payload(hdev, fw, RSA_HEADER_LEN);
+               if (err)
+                       return err;
+       } else if (hw_variant >= 0x17) {
+@@ -969,7 +1035,6 @@ int btintel_download_firmware_newgen(str
+                               return err;
+                       err = btintel_download_firmware_payload(hdev, fw,
+-                                                              boot_param,
+                                                               RSA_HEADER_LEN + ECDSA_HEADER_LEN);
+                       if (err)
+                               return err;
+@@ -979,7 +1044,6 @@ int btintel_download_firmware_newgen(str
+                               return err;
+                       err = btintel_download_firmware_payload(hdev, fw,
+-                                                              boot_param,
+                                                               RSA_HEADER_LEN + ECDSA_HEADER_LEN);
+                       if (err)
+                               return err;
+--- a/drivers/bluetooth/btintel.h
++++ b/drivers/bluetooth/btintel.h
+@@ -157,9 +157,10 @@ struct regmap *btintel_regmap_init(struc
+ int btintel_send_intel_reset(struct hci_dev *hdev, u32 boot_param);
+ int btintel_read_boot_params(struct hci_dev *hdev,
+                            struct intel_boot_params *params);
+-int btintel_download_firmware(struct hci_dev *dev, const struct firmware *fw,
+-                            u32 *boot_param);
++int btintel_download_firmware(struct hci_dev *dev, struct intel_version *ver,
++                            const struct firmware *fw, u32 *boot_param);
+ int btintel_download_firmware_newgen(struct hci_dev *hdev,
++                                   struct intel_version_tlv *ver,
+                                    const struct firmware *fw,
+                                    u32 *boot_param, u8 hw_variant,
+                                    u8 sbe_type);
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -2602,8 +2602,15 @@ static int btusb_intel_download_firmware
+       set_bit(BTUSB_DOWNLOADING, &data->flags);
+       /* Start firmware downloading and get boot parameter */
+-      err = btintel_download_firmware(hdev, fw, boot_param);
++      err = btintel_download_firmware(hdev, ver, fw, boot_param);
+       if (err < 0) {
++              if (err == -EALREADY) {
++                      /* Firmware has already been loaded */
++                      set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
++                      err = 0;
++                      goto done;
++              }
++
+               /* When FW download fails, send Intel Reset to retry
+                * FW download.
+                */
+--- a/drivers/bluetooth/hci_intel.c
++++ b/drivers/bluetooth/hci_intel.c
+@@ -735,7 +735,7 @@ static int intel_setup(struct hci_uart *
+       set_bit(STATE_DOWNLOADING, &intel->flags);
+       /* Start firmware downloading and get boot parameter */
+-      err = btintel_download_firmware(hdev, fw, &boot_param);
++      err = btintel_download_firmware(hdev, &ver, fw, &boot_param);
+       if (err < 0)
+               goto done;
+@@ -784,7 +784,10 @@ static int intel_setup(struct hci_uart *
+ done:
+       release_firmware(fw);
+-      if (err < 0)
++      /* Check if there was an error and if is not -EALREADY which means the
++       * firmware has already been loaded.
++       */
++      if (err < 0 && err != -EALREADY)
+               return err;
+       /* We need to restore the default speed before Intel reset */
diff --git a/queue-5.10/bluetooth-btintel-fix-offset-calculation-boot-address-parameter.patch b/queue-5.10/bluetooth-btintel-fix-offset-calculation-boot-address-parameter.patch
new file mode 100644 (file)
index 0000000..60fdd44
--- /dev/null
@@ -0,0 +1,36 @@
+From stable+bounces-274237-greg=kroah.com@vger.kernel.org Tue Jul 14 15:35:43 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 09:26:47 -0400
+Subject: Bluetooth: btintel: Fix offset calculation boot address parameter
+To: stable@vger.kernel.org
+Cc: Kiran K <kiran.k@intel.com>, Marcel Holtmann <marcel@holtmann.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714132650.2663656-1-sashal@kernel.org>
+
+From: Kiran K <kiran.k@intel.com>
+
+[ Upstream commit d00745da644d42c2f97293eb3fe19cfd5c0b073c ]
+
+Boot address parameter was not getting updated properly
+due to wrong offset
+
+Signed-off-by: Kiran K <kiran.k@intel.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Stable-dep-of: c5b600a3c05b ("Bluetooth: btusb: fix use-after-free on marvell probe failure")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bluetooth/btintel.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/bluetooth/btintel.c
++++ b/drivers/bluetooth/btintel.c
+@@ -863,7 +863,8 @@ static int btintel_download_firmware_pay
+                       /* The boot parameter is the first 32-bit value
+                        * and rest of 3 octets are reserved.
+                        */
+-                      *boot_param = get_unaligned_le32(fw_ptr + sizeof(*cmd));
++                      *boot_param = get_unaligned_le32(fw_ptr + frag_len +
++                                                       sizeof(*cmd));
+                       bt_dev_dbg(hdev, "boot_param=0x%x", *boot_param);
+               }
diff --git a/queue-5.10/bluetooth-btusb-fix-use-after-free-on-marvell-probe-failure.patch b/queue-5.10/bluetooth-btusb-fix-use-after-free-on-marvell-probe-failure.patch
new file mode 100644 (file)
index 0000000..a5fed6e
--- /dev/null
@@ -0,0 +1,60 @@
+From stable+bounces-274240-greg=kroah.com@vger.kernel.org Tue Jul 14 15:31:58 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 09:26:50 -0400
+Subject: Bluetooth: btusb: fix use-after-free on marvell probe failure
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Rajat Jain <rajatja@google.com>, Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714132650.2663656-4-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit c5b600a3c05b1a7a110d558df935a8fc8a471c79 ]
+
+Make sure to stop any TX URBs submitted during Marvell OOB wakeup
+configuration on later probe failures to avoid use-after-free in the
+completion callback.
+
+This issue was reported by Sashiko while reviewing a fix for a wakeup
+source leak in the btusb probe errors paths.
+
+Link: https://sashiko.dev/#/patchset/20260402092704.2346710-1-johan%40kernel.org
+Fixes: a4ccc9e33d2f ("Bluetooth: btusb: Configure Marvell to use one of the pins for oob wakeup")
+Cc: stable@vger.kernel.org     # 4.11
+Cc: Rajat Jain <rajatja@google.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bluetooth/btusb.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -4352,7 +4352,7 @@ static int btusb_probe(struct usb_interf
+               err = usb_set_interface(data->udev, 0, 0);
+               if (err < 0) {
+                       BT_ERR("failed to set interface 0, alt 0 %d", err);
+-                      goto out_free_dev;
++                      goto err_kill_tx_urbs;
+               }
+       }
+@@ -4360,7 +4360,7 @@ static int btusb_probe(struct usb_interf
+               err = usb_driver_claim_interface(&btusb_driver,
+                                                data->isoc, data);
+               if (err < 0)
+-                      goto out_free_dev;
++                      goto err_kill_tx_urbs;
+       }
+       if (IS_ENABLED(CONFIG_BT_HCIBTUSB_BCM) && data->diag) {
+@@ -4391,6 +4391,8 @@ err_release_siblings:
+               usb_set_intfdata(data->isoc, NULL);
+               usb_driver_release_interface(&btusb_driver, data->isoc);
+       }
++err_kill_tx_urbs:
++      usb_kill_anchored_urbs(&data->tx_anchor);
+ out_free_dev:
+       if (data->reset_gpio)
+               gpiod_put(data->reset_gpio);
diff --git a/queue-5.10/bluetooth-btusb-fix-wakeup-source-leak-on-probe-failure.patch b/queue-5.10/bluetooth-btusb-fix-wakeup-source-leak-on-probe-failure.patch
new file mode 100644 (file)
index 0000000..b3a53f7
--- /dev/null
@@ -0,0 +1,82 @@
+From stable+bounces-274245-greg=kroah.com@vger.kernel.org Tue Jul 14 15:27:22 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 09:26:57 -0400
+Subject: Bluetooth: btusb: fix wakeup source leak on probe failure
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Rajat Jain <rajatja@google.com>, Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714132657.2663805-5-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 3d93e1bb0fb881fe3ef961d1120556658e9cac4d ]
+
+Make sure to disable wakeup on probe failure to avoid leaking the wakeup
+source.
+
+Fixes: fd913ef7ce61 ("Bluetooth: btusb: Add out-of-band wakeup support")
+Cc: stable@vger.kernel.org     # 4.11
+Cc: Rajat Jain <rajatja@google.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bluetooth/btusb.c |   18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -3501,6 +3501,11 @@ static int marvell_config_oob_wake(struc
+       return 0;
+ }
++#else
++static inline int marvell_config_oob_wake(struct hci_dev *hdev)
++{
++      return 0;
++}
+ #endif
+ static int btusb_set_bdaddr_marvell(struct hci_dev *hdev,
+@@ -4011,6 +4016,11 @@ static int btusb_config_oob_wake(struct
+       bt_dev_info(hdev, "OOB Wake-on-BT configured at IRQ %u", irq);
+       return 0;
+ }
++#else
++static inline int btusb_config_oob_wake(struct hci_dev *hdev)
++{
++      return 0;
++}
+ #endif
+ static void btusb_check_needs_reset_resume(struct usb_interface *intf)
+@@ -4164,7 +4174,6 @@ static int btusb_probe(struct usb_interf
+       hdev->notify = btusb_notify;
+       hdev->prevent_wake = btusb_prevent_wake;
+-#ifdef CONFIG_PM
+       err = btusb_config_oob_wake(hdev);
+       if (err)
+               goto out_free_dev;
+@@ -4173,9 +4182,9 @@ static int btusb_probe(struct usb_interf
+       if (id->driver_info & BTUSB_MARVELL && data->oob_wake_irq) {
+               err = marvell_config_oob_wake(hdev);
+               if (err)
+-                      goto out_free_dev;
++                      goto err_disable_wakeup;
+       }
+-#endif
++
+       if (id->driver_info & BTUSB_CW6622)
+               set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
+@@ -4393,6 +4402,9 @@ err_release_siblings:
+       }
+ err_kill_tx_urbs:
+       usb_kill_anchored_urbs(&data->tx_anchor);
++err_disable_wakeup:
++      if (data->oob_wake_irq)
++              device_init_wakeup(&data->udev->dev, false);
+ out_free_dev:
+       if (data->reset_gpio)
+               gpiod_put(data->reset_gpio);
diff --git a/queue-5.10/bluetooth-l2cap-cancel-pending_rx_work-before-taking-conn-lock.patch b/queue-5.10/bluetooth-l2cap-cancel-pending_rx_work-before-taking-conn-lock.patch
new file mode 100644 (file)
index 0000000..13fdb41
--- /dev/null
@@ -0,0 +1,67 @@
+From stable+bounces-275107-greg=kroah.com@vger.kernel.org Thu Jul 16 02:17:01 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 20:16:50 -0400
+Subject: Bluetooth: L2CAP: cancel pending_rx_work before taking conn->lock
+To: stable@vger.kernel.org
+Cc: Runyu Xiao <runyu.xiao@seu.edu.cn>, Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260716001650.589781-3-sashal@kernel.org>
+
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+
+[ Upstream commit 2641a9e0a1dd4af2e21995470a21d55dd35e5203 ]
+
+l2cap_conn_del() takes conn->lock and then calls cancel_work_sync() for
+pending_rx_work.  process_pending_rx() takes the same mutex, so teardown
+can deadlock against the worker it is flushing.
+
+This issue was found by our static analysis tool and then manually
+reviewed against the current tree.
+
+The grounded PoC kept the l2cap_conn_ready() -> queue_work(...,
+&conn->pending_rx_work) submit path, the l2cap_conn_del() ->
+cancel_work_sync(&conn->pending_rx_work) teardown path, and the
+process_pending_rx() -> mutex_lock(&conn->lock) worker edge.  Lockdep
+reported:
+
+  WARNING: possible circular locking dependency detected
+  process_pending_rx+0x21/0x2a [vuln_msv]
+  l2cap_conn_del.constprop.0+0x3f/0x4e [vuln_msv]
+  *** DEADLOCK ***
+
+Cancel pending_rx_work before taking conn->lock, matching the existing
+lock-before-drain ordering used for the two delayed works in the same
+teardown path.  The pending_rx queue is still purged after the work has
+been cancelled and conn->lock has been acquired.
+
+Fixes: 7ab56c3a6ecc ("Bluetooth: Fix deadlock in l2cap_conn_del()")
+Cc: stable@vger.kernel.org
+Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/l2cap_core.c |   10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -1901,17 +1901,11 @@ static void l2cap_conn_del(struct hci_co
+       cancel_delayed_work_sync(&conn->info_timer);
+       cancel_work_sync(&conn->id_addr_update_work);
++      cancel_work_sync(&conn->pending_rx_work);
++
+       kfree_skb(conn->rx_skb);
+       skb_queue_purge(&conn->pending_rx);
+-
+-      /* We can not call flush_work(&conn->pending_rx_work) here since we
+-       * might block if we are running on a worker from the same workqueue
+-       * pending_rx_work is waiting on.
+-       */
+-      if (work_pending(&conn->pending_rx_work))
+-              cancel_work_sync(&conn->pending_rx_work);
+-
+       ida_destroy(&conn->tx_ida);
+       l2cap_unregister_all_users(conn);
diff --git a/queue-5.10/bluetooth-l2cap-fix-deadlock-in-l2cap_conn_del.patch b/queue-5.10/bluetooth-l2cap-fix-deadlock-in-l2cap_conn_del.patch
new file mode 100644 (file)
index 0000000..6d0554b
--- /dev/null
@@ -0,0 +1,65 @@
+From stable+bounces-275106-greg=kroah.com@vger.kernel.org Thu Jul 16 02:16:59 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 20:16:49 -0400
+Subject: Bluetooth: L2CAP: Fix deadlock in l2cap_conn_del()
+To: stable@vger.kernel.org
+Cc: Hyunwoo Kim <imv4bel@gmail.com>, Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260716001650.589781-2-sashal@kernel.org>
+
+From: Hyunwoo Kim <imv4bel@gmail.com>
+
+[ Upstream commit 00fdebbbc557a2fc21321ff2eaa22fd70c078608 ]
+
+l2cap_conn_del() calls cancel_delayed_work_sync() for both info_timer
+and id_addr_timer while holding conn->lock. However, the work functions
+l2cap_info_timeout() and l2cap_conn_update_id_addr() both acquire
+conn->lock, creating a potential AB-BA deadlock if the work is already
+executing when l2cap_conn_del() takes the lock.
+
+Move the work cancellations before acquiring conn->lock and use
+disable_delayed_work_sync() to additionally prevent the works from
+being rearmed after cancellation, consistent with the pattern used in
+hci_conn_del().
+
+Fixes: ab4eedb790ca ("Bluetooth: L2CAP: Fix corrupted list in hci_chan_del")
+Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 2641a9e0a1dd ("Bluetooth: L2CAP: cancel pending_rx_work before taking conn->lock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/l2cap_core.c |    9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -1898,6 +1898,9 @@ static void l2cap_conn_del(struct hci_co
+       BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
++      cancel_delayed_work_sync(&conn->info_timer);
++      cancel_work_sync(&conn->id_addr_update_work);
++
+       kfree_skb(conn->rx_skb);
+       skb_queue_purge(&conn->pending_rx);
+@@ -1911,9 +1914,6 @@ static void l2cap_conn_del(struct hci_co
+       ida_destroy(&conn->tx_ida);
+-      if (work_pending(&conn->id_addr_update_work))
+-              cancel_work_sync(&conn->id_addr_update_work);
+-
+       l2cap_unregister_all_users(conn);
+       /* Force the connection to be immediately dropped */
+@@ -1938,9 +1938,6 @@ static void l2cap_conn_del(struct hci_co
+       hci_chan_del(conn->hchan);
+-      if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
+-              cancel_delayed_work_sync(&conn->info_timer);
+-
+       hcon->l2cap_data = NULL;
+       conn->hchan = NULL;
+       l2cap_conn_put(conn);
diff --git a/queue-5.10/bluetooth-l2cap-fix-not-tracking-outstanding-tx-ident.patch b/queue-5.10/bluetooth-l2cap-fix-not-tracking-outstanding-tx-ident.patch
new file mode 100644 (file)
index 0000000..35bf8ec
--- /dev/null
@@ -0,0 +1,154 @@
+From stable+bounces-275105-greg=kroah.com@vger.kernel.org Thu Jul 16 02:16:57 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 20:16:48 -0400
+Subject: Bluetooth: L2CAP: Fix not tracking outstanding TX ident
+To: stable@vger.kernel.org
+Cc: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Paul Menzel <pmenzel@molgen.mpg.de>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260716001650.589781-1-sashal@kernel.org>
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 6c3ea155e5ee3e56606233acde8309afda66d483 ]
+
+This attempts to proper track outstanding request by using struct ida
+and allocating from it in l2cap_get_ident using ida_alloc_range which
+would reuse ids as they are free, then upon completion release
+the id using ida_free.
+
+This fixes the qualification test case L2CAP/COS/CED/BI-29-C which
+attempts to check if the host stack is able to work after 256 attempts
+to connect which requires Ident field to use the full range of possible
+values in order to pass the test.
+
+Link: https://github.com/bluez/bluez/issues/1829
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Stable-dep-of: 2641a9e0a1dd ("Bluetooth: L2CAP: cancel pending_rx_work before taking conn->lock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/bluetooth/l2cap.h |    3 --
+ net/bluetooth/l2cap_core.c    |   53 ++++++++++++++++++++++++++++++------------
+ 2 files changed, 40 insertions(+), 16 deletions(-)
+
+--- a/include/net/bluetooth/l2cap.h
++++ b/include/net/bluetooth/l2cap.h
+@@ -690,8 +690,7 @@ struct l2cap_conn {
+       struct sk_buff          *rx_skb;
+       __u32                   rx_len;
+-      __u8                    tx_ident;
+-      struct mutex            ident_lock;
++      struct ida              tx_ida;
+       struct sk_buff_head     pending_rx;
+       struct work_struct      pending_rx_work;
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -939,26 +939,18 @@ int l2cap_chan_check_security(struct l2c
+                                initiator);
+ }
+-static u8 l2cap_get_ident(struct l2cap_conn *conn)
++static int l2cap_get_ident(struct l2cap_conn *conn)
+ {
+-      u8 id;
++      /* LE link does not support tools like l2ping so use the full range */
++      if (conn->hcon->type == LE_LINK)
++              return ida_alloc_range(&conn->tx_ida, 1, 255, GFP_ATOMIC);
+       /* Get next available identificator.
+        *    1 - 128 are used by kernel.
+        *  129 - 199 are reserved.
+        *  200 - 254 are used by utilities like l2ping, etc.
+        */
+-
+-      mutex_lock(&conn->ident_lock);
+-
+-      if (++conn->tx_ident > 128)
+-              conn->tx_ident = 1;
+-
+-      id = conn->tx_ident;
+-
+-      mutex_unlock(&conn->ident_lock);
+-
+-      return id;
++      return ida_alloc_range(&conn->tx_ida, 1, 128, GFP_ATOMIC);
+ }
+ static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
+@@ -1917,6 +1909,8 @@ static void l2cap_conn_del(struct hci_co
+       if (work_pending(&conn->pending_rx_work))
+               cancel_work_sync(&conn->pending_rx_work);
++      ida_destroy(&conn->tx_ida);
++
+       if (work_pending(&conn->id_addr_update_work))
+               cancel_work_sync(&conn->id_addr_update_work);
+@@ -5788,12 +5782,41 @@ unlock:
+       return err;
+ }
++static void l2cap_put_ident(struct l2cap_conn *conn, u8 code, u8 id)
++{
++      int ret;
++
++      switch (code) {
++      case L2CAP_COMMAND_REJ:
++      case L2CAP_CONN_RSP:
++      case L2CAP_CONF_RSP:
++      case L2CAP_DISCONN_RSP:
++      case L2CAP_ECHO_RSP:
++      case L2CAP_INFO_RSP:
++      case L2CAP_CONN_PARAM_UPDATE_RSP:
++      case L2CAP_ECRED_CONN_RSP:
++      case L2CAP_ECRED_RECONF_RSP:
++              /* The remote may send bogus ids that would make ida_free
++               * generate warnings, so only free ids that are actually
++               * allocated: probing the exact id returns -ENOSPC when it
++               * is in use, otherwise the probe allocated it and freeing
++               * is safe either way.  Only on -ENOMEM is the id known to
++               * be unallocated and the free must be skipped.
++               */
++              ret = ida_alloc_range(&conn->tx_ida, id, id, GFP_ATOMIC);
++              if (ret >= 0 || ret == -ENOSPC)
++                      ida_free(&conn->tx_ida, id);
++      }
++}
++
+ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
+                                     struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+                                     u8 *data)
+ {
+       int err = 0;
++      l2cap_put_ident(conn, cmd->code, cmd->ident);
++
+       switch (cmd->code) {
+       case L2CAP_COMMAND_REJ:
+               l2cap_command_rej(conn, cmd, cmd_len, data);
+@@ -6532,6 +6555,8 @@ static inline int l2cap_le_sig_cmd(struc
+ {
+       int err = 0;
++      l2cap_put_ident(conn, cmd->code, cmd->ident);
++
+       switch (cmd->code) {
+       case L2CAP_COMMAND_REJ:
+               l2cap_le_command_rej(conn, cmd, cmd_len, data);
+@@ -8085,13 +8110,13 @@ static struct l2cap_conn *l2cap_conn_add
+            hci_dev_test_flag(hcon->hdev, HCI_FORCE_BREDR_SMP)))
+               conn->local_fixed_chan |= L2CAP_FC_SMP_BREDR;
+-      mutex_init(&conn->ident_lock);
+       mutex_init(&conn->chan_lock);
+       INIT_LIST_HEAD(&conn->chan_l);
+       INIT_LIST_HEAD(&conn->users);
+       INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
++      ida_init(&conn->tx_ida);
+       skb_queue_head_init(&conn->pending_rx);
+       INIT_WORK(&conn->pending_rx_work, process_pending_rx);
diff --git a/queue-5.10/btrfs-do-not-trim-a-device-which-is-not-writeable.patch b/queue-5.10/btrfs-do-not-trim-a-device-which-is-not-writeable.patch
new file mode 100644 (file)
index 0000000..b4b097e
--- /dev/null
@@ -0,0 +1,144 @@
+From stable+bounces-278192-greg=kroah.com@vger.kernel.org Mon Jul 20 20:38:45 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jul 2026 14:38:37 -0400
+Subject: btrfs: do not trim a device which is not writeable
+To: stable@vger.kernel.org
+Cc: Qu Wenruo <wqu@suse.com>, Su Yue <glass.su@suse.com>, Filipe Manana <fdmanana@suse.com>, David Sterba <dsterba@suse.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260720183837.3080301-1-sashal@kernel.org>
+
+From: Qu Wenruo <wqu@suse.com>
+
+[ Upstream commit 1b1937eb08f51319bf71575484cde2b8c517aedc ]
+
+[BUG]
+There is a bug report that btrfs/242 can randomly fail with the
+following NULL pointer dereference:
+
+  run fstests btrfs/242 at 2026-06-01 10:25:08
+  BTRFS: device fsid d4d7f234-487c-4787-88e4-47a8b68c9874 devid 1 transid 9 /dev/sdc (8:32) scanned by mount (122609)
+  BTRFS info (device sdc): first mount of filesystem d4d7f234-487c-4787-88e4-47a8b68c9874
+  BTRFS info (device sdc): using crc32c checksum algorithm
+  BTRFS warning (device sdc): devid 2 uuid fbe72d72-3272-482d-80fb-ab88ed398192 is missing
+  BTRFS warning (device sdc): devid 2 uuid fbe72d72-3272-482d-80fb-ab88ed398192 is missing
+  BTRFS info (device sdc): allowing degraded mounts
+  BTRFS info (device sdc): turning on async discard
+  BTRFS info (device sdc): enabling free space tree
+  Unable to handle kernel NULL pointer dereference at virtual address 0000000000000018
+  user pgtable: 4k pages, 48-bit VAs, pgdp=000000013fd6b000
+  CPU: 4 UID: 0 PID: 122625 Comm: fstrim Not tainted 7.0.10-2-default #1 PREEMPT(full) openSUSE Tumbleweed e9a5f6b24978fba3bf015a992f865837fdfff3dd
+  Hardware name: QEMU KVM Virtual Machine, BIOS edk2-20250812-19.fc42 08/12/2025
+  pstate: 01400005 (nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
+  pc : btrfs_trim_fs+0x34c/0xa00 [btrfs]
+  lr : btrfs_trim_fs+0x1f0/0xa00 [btrfs]
+  Call trace:
+   btrfs_trim_fs+0x34c/0xa00 [btrfs f02c1d570ceea621c69d302ba75dd61868083840] (P)
+   btrfs_ioctl_fitrim+0xe8/0x178 [btrfs f02c1d570ceea621c69d302ba75dd61868083840]
+   btrfs_ioctl+0xdd4/0x2bd8 [btrfs f02c1d570ceea621c69d302ba75dd61868083840]
+   __arm64_sys_ioctl+0xac/0x108
+   invoke_syscall.constprop.0+0x5c/0xd0
+   el0_svc_common.constprop.0+0x40/0xf0
+   do_el0_svc+0x24/0x40
+   el0_svc+0x40/0x1d0
+   el0t_64_sync_handler+0xa0/0xe8
+   el0t_64_sync+0x1b0/0x1b8
+  Code: 17ffff83 f94017e0 f9002be0 f9402ea0 (f9400c00)
+  ---[ end trace 0000000000000000  ]---
+
+Also the reporter is very kind to test the following ASSERT() added to
+btrfs_trim_free_extents_throttle():
+
+       ASSERT(device->bdev,
+              "devid=%llu path=%s dev_state=0x%lx\n",
+              device->devid, btrfs_dev_name(device), device->dev_state);
+
+And it shows the following output:
+
+  assertion failed: device->bdev, in extent-tree.c:6630 (devid=2 path=/dev/sdd dev_state=0x82)
+
+Which means the device->bdev is NULL, and the dev_state is
+BTRFS_DEV_STATE_IN_FS_METADATA | BTRFS_DEV_STATE_ITEM_FOUND, without
+BTRFS_DEV_STATE_WRITEABLE flag set.
+
+[CAUSE]
+The pc points to the following call chain:
+
+  btrfs_trim_fs()
+  |- btrfs_trim_free_extents()
+     |- btrfs_trim_free_extents_throttle()
+        |- bdev_max_discard_sectors(device->bdev)
+
+So the NULL pointer dereference is caused by device->bdev being NULL.
+
+This looks impossible by a quick glance, as just before calling
+btrfs_trim_free_extents_throttle(), we have skipped any device that has
+BTRFS_DEV_STATE_MISSING flag set.
+
+However in this particular case, there is a window where the missing
+device is later re-scanned, causing btrfs to remove the
+BTRFS_DEV_STATE_MISSING flag:
+
+  btrfs_control_ioctl()
+  |- btrfs_scan_one_device()
+     |- device_list_add()
+        |- rcu_assign_pointer(device->name, name);
+        |  This updates the missing device's path to the new good path.
+        |
+        |- clear_bit(BTRFS_DEV_STATE_MISSING, &device->dev_state)
+           This removes the BTRFS_DEV_STATE_MISSING flag.
+
+This allows the missing device to re-appear and clear the
+BTRFS_DEV_STATE_MISSING flag.  However the device still does not have
+the BTRFS_DEV_STATE_WRITEABLE flag set, nor is its bdev pointer updated.
+
+The bdev pointer remains NULL, triggering the crash later.
+
+[FIX]
+This is a big de-synchronization between BTRFS_DEV_STATE_MISSING and
+device->bdev pointer, and shows a gap in btrfs's re-appearing-device
+handling.
+
+The proper handling of re-appearing device will need quite some extra
+work, which is out of the context of this small fix.
+
+Thankfully the regular bbio submission path has already handled it well
+by checking if the device->bdev is NULL before submitting.
+
+So here we just fix the crash by checking if the device is writeable and
+has a bdev pointer before calling bdev_max_discard_sectors().
+
+Reported-by: Su Yue <glass.su@suse.com>
+Link: https://lore.kernel.org/linux-btrfs/wlwir19t.fsf@damenly.org/
+Fixes: 499f377f49f0 ("btrfs: iterate over unused chunk space in FITRIM")
+CC: stable@vger.kernel.org # 5.10+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/extent-tree.c |   12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -5762,12 +5762,16 @@ static int btrfs_trim_free_extents(struc
+       *trimmed = 0;
+-      /* Discard not supported = nothing to do. */
+-      if (!blk_queue_discard(bdev_get_queue(device->bdev)))
++      /*
++       * The caller only filters out MISSING devices, but a device that was
++       * missing at mount and later rescanned has MISSING cleared while bdev
++       * is still NULL and WRITEABLE is still unset. Skip those here.
++       */
++      if (!test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state) || !device->bdev)
+               return 0;
+-      /* Not writable = nothing to do. */
+-      if (!test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state))
++      /* Discard not supported = nothing to do. */
++      if (!blk_queue_discard(bdev_get_queue(device->bdev)))
+               return 0;
+       /* No free space = nothing to do. */
diff --git a/queue-5.10/cifs-create-a-new-shared-file-holding-smb2-pdu-definitions.patch b/queue-5.10/cifs-create-a-new-shared-file-holding-smb2-pdu-definitions.patch
new file mode 100644 (file)
index 0000000..b69e2dc
--- /dev/null
@@ -0,0 +1,2030 @@
+From stable+bounces-274571-greg=kroah.com@vger.kernel.org Wed Jul 15 00:04:19 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 18:04:01 -0400
+Subject: cifs: Create a new shared file holding smb2 pdu definitions
+To: stable@vger.kernel.org
+Cc: Ronnie Sahlberg <lsahlber@redhat.com>, Namjae Jeon <linkinjeon@kernel.org>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714220405.3333589-1-sashal@kernel.org>
+
+From: Ronnie Sahlberg <lsahlber@redhat.com>
+
+[ Upstream commit 0d35e382e4e96a4fd97a1438bc1b11a91d2d85a6 ]
+
+This file will contain all the definitions we need for SMB2 packets
+and will follow the naming convention of MS-SMB2.PDF as closely
+as possible to make it easier to cross-reference beween the definitions
+and the standard.
+
+The content of this file will mostly consist of migration of existing
+definitions in the cifs/smb2.pdu.h and ksmbd/smb2pdu.h files
+with some additional tweaks as the two files have diverged.
+
+This patch introduces the new smbfs_common/smb2pdu.h file
+and migrates the SMB2 header as well as TREE_CONNECT and TREE_DISCONNECT
+to the shared file.
+
+Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
+Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 53b7c271f06b ("smb: client: restrict implied bcc[0] exemption to responses without data area")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/cifsfs.c          |    1 
+ fs/cifs/cifsglob.h        |    3 
+ fs/cifs/connect.c         |    4 
+ fs/cifs/misc.c            |    2 
+ fs/cifs/smb2maperror.c    |   16 +-
+ fs/cifs/smb2misc.c        |   43 ++---
+ fs/cifs/smb2ops.c         |   61 +++----
+ fs/cifs/smb2pdu.c         |  106 ++++++-------
+ fs/cifs/smb2pdu.h         |  365 ++++------------------------------------------
+ fs/cifs/smb2proto.h       |    2 
+ fs/cifs/smb2transport.c   |   36 ++--
+ fs/smbfs_common/smb2pdu.h |  318 ++++++++++++++++++++++++++++++++++++++++
+ 12 files changed, 491 insertions(+), 466 deletions(-)
+ create mode 100644 fs/smbfs_common/smb2pdu.h
+
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -51,7 +51,6 @@
+ #include <linux/key-type.h>
+ #include "cifs_spnego.h"
+ #include "fscache.h"
+-#include "smb2pdu.h"
+ #ifdef CONFIG_CIFS_DFS_UPCALL
+ #include "dfs_cache.h"
+ #endif
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -32,6 +32,7 @@
+ #include <crypto/internal/hash.h>
+ #include <linux/scatterlist.h>
+ #include <uapi/linux/cifs/cifs_mount.h>
++#include "../smbfs_common/smb2pdu.h"
+ #include "smb2pdu.h"
+ #include "smb2glob.h"
+@@ -866,7 +867,7 @@ revert_current_mid(struct TCP_Server_Inf
+ static inline void
+ revert_current_mid_from_hdr(struct TCP_Server_Info *server,
+-                          const struct smb2_sync_hdr *shdr)
++                          const struct smb2_hdr *shdr)
+ {
+       unsigned int num = le16_to_cpu(shdr->CreditCharge);
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -848,7 +848,7 @@ dequeue_mid(struct mid_q_entry *mid, boo
+ static unsigned int
+ smb2_get_credits_from_hdr(char *buffer, struct TCP_Server_Info *server)
+ {
+-      struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buffer;
++      struct smb2_hdr *shdr = (struct smb2_hdr *)buffer;
+       /*
+        * SMB1 does not use credits.
+@@ -1048,7 +1048,7 @@ cifs_handle_standard(struct TCP_Server_I
+ static void
+ smb2_add_credits_from_hdr(char *buffer, struct TCP_Server_Info *server)
+ {
+-      struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buffer;
++      struct smb2_hdr *shdr = (struct smb2_hdr *)buffer;
+       /*
+        * SMB1 does not use credits.
+--- a/fs/cifs/misc.c
++++ b/fs/cifs/misc.c
+@@ -164,7 +164,7 @@ cifs_buf_get(void)
+        * SMB2 header is bigger than CIFS one - no problems to clean some
+        * more bytes for CIFS.
+        */
+-      size_t buf_size = sizeof(struct smb2_sync_hdr);
++      size_t buf_size = sizeof(struct smb2_hdr);
+       /*
+        * We could use negotiated size instead of max_msgsize -
+--- a/fs/cifs/smb2maperror.c
++++ b/fs/cifs/smb2maperror.c
+@@ -2452,14 +2452,16 @@ smb2_print_status(__le32 status)
+ int
+ map_smb2_to_linux_error(char *buf, bool log_err)
+ {
+-      struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
++      struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
+       unsigned int i;
+       int rc = -EIO;
+       __le32 smb2err = shdr->Status;
+       if (smb2err == 0) {
+-              trace_smb3_cmd_done(shdr->TreeId, shdr->SessionId,
+-                      le16_to_cpu(shdr->Command), le64_to_cpu(shdr->MessageId));
++              trace_smb3_cmd_done(le32_to_cpu(shdr->Id.SyncId.TreeId),
++                            le64_to_cpu(shdr->SessionId),
++                            le16_to_cpu(shdr->Command),
++                            le64_to_cpu(shdr->MessageId));
+               return 0;
+       }
+@@ -2483,8 +2485,10 @@ map_smb2_to_linux_error(char *buf, bool
+       cifs_dbg(FYI, "Mapping SMB2 status code 0x%08x to POSIX err %d\n",
+                __le32_to_cpu(smb2err), rc);
+-      trace_smb3_cmd_err(shdr->TreeId, shdr->SessionId,
+-                      le16_to_cpu(shdr->Command),
+-                      le64_to_cpu(shdr->MessageId), le32_to_cpu(smb2err), rc);
++      trace_smb3_cmd_err(le32_to_cpu(shdr->Id.SyncId.TreeId),
++                         le64_to_cpu(shdr->SessionId),
++                         le16_to_cpu(shdr->Command),
++                         le64_to_cpu(shdr->MessageId),
++                         le32_to_cpu(smb2err), rc);
+       return rc;
+ }
+--- a/fs/cifs/smb2misc.c
++++ b/fs/cifs/smb2misc.c
+@@ -21,7 +21,6 @@
+  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+  */
+ #include <linux/ctype.h>
+-#include "smb2pdu.h"
+ #include "cifsglob.h"
+ #include "cifsproto.h"
+ #include "smb2proto.h"
+@@ -32,7 +31,7 @@
+ #include "nterr.h"
+ static int
+-check_smb2_hdr(struct smb2_sync_hdr *shdr, __u64 mid)
++check_smb2_hdr(struct smb2_hdr *shdr, __u64 mid)
+ {
+       __u64 wire_mid = le64_to_cpu(shdr->MessageId);
+@@ -94,9 +93,9 @@ static const __le16 smb2_rsp_struct_size
+       /* SMB2_OPLOCK_BREAK */ cpu_to_le16(24)
+ };
+-#define SMB311_NEGPROT_BASE_SIZE (sizeof(struct smb2_sync_hdr) + sizeof(struct smb2_negotiate_rsp))
++#define SMB311_NEGPROT_BASE_SIZE (sizeof(struct smb2_hdr) + sizeof(struct smb2_negotiate_rsp))
+-static __u32 get_neg_ctxt_len(struct smb2_sync_hdr *hdr, __u32 len,
++static __u32 get_neg_ctxt_len(struct smb2_hdr *hdr, __u32 len,
+                             __u32 non_ctxlen)
+ {
+       __u16 neg_count;
+@@ -139,13 +138,13 @@ static __u32 get_neg_ctxt_len(struct smb
+ int
+ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr)
+ {
+-      struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
+-      struct smb2_sync_pdu *pdu = (struct smb2_sync_pdu *)shdr;
++      struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
++      struct smb2_pdu *pdu = (struct smb2_pdu *)shdr;
+       __u64 mid;
+       __u32 clc_len;  /* calculated length */
+       int command;
+-      int pdu_size = sizeof(struct smb2_sync_pdu);
+-      int hdr_size = sizeof(struct smb2_sync_hdr);
++      int pdu_size = sizeof(struct smb2_pdu);
++      int hdr_size = sizeof(struct smb2_hdr);
+       /*
+        * Add function to do table lookup of StructureSize by command
+@@ -161,7 +160,7 @@ smb2_check_message(char *buf, unsigned i
+               spin_lock(&cifs_tcp_ses_lock);
+               list_for_each(tmp, &srvr->smb_ses_list) {
+                       ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
+-                      if (ses->Suid == thdr->SessionId)
++                      if (ses->Suid == le64_to_cpu(thdr->SessionId))
+                               break;
+                       ses = NULL;
+@@ -303,7 +302,7 @@ static const bool has_smb2_data_area[NUM
+  * area and the offset to it (from the beginning of the smb are also returned.
+  */
+ char *
+-smb2_get_data_area_len(int *off, int *len, struct smb2_sync_hdr *shdr)
++smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *shdr)
+ {
+       const int max_off = 4096;
+       const int max_len = 128 * 1024;
+@@ -402,8 +401,8 @@ smb2_get_data_area_len(int *off, int *le
+ unsigned int
+ smb2_calc_size(void *buf, struct TCP_Server_Info *srvr)
+ {
+-      struct smb2_sync_pdu *pdu = (struct smb2_sync_pdu *)buf;
+-      struct smb2_sync_hdr *shdr = &pdu->sync_hdr;
++      struct smb2_pdu *pdu = (struct smb2_pdu *)buf;
++      struct smb2_hdr *shdr = &pdu->hdr;
+       int offset; /* the offset from the beginning of SMB to data area */
+       int data_length; /* the length of the variable length data area */
+       /* Structure Size has already been checked to make sure it is 64 */
+@@ -679,7 +678,7 @@ smb2_is_valid_oplock_break(char *buffer,
+       cifs_dbg(FYI, "Checking for oplock break\n");
+-      if (rsp->sync_hdr.Command != SMB2_OPLOCK_BREAK)
++      if (rsp->hdr.Command != SMB2_OPLOCK_BREAK)
+               return false;
+       if (rsp->StructureSize !=
+@@ -832,23 +831,23 @@ smb2_handle_cancelled_close(struct cifs_
+ int
+ smb2_handle_cancelled_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server)
+ {
+-      struct smb2_sync_hdr *sync_hdr = mid->resp_buf;
++      struct smb2_hdr *hdr = mid->resp_buf;
+       struct smb2_create_rsp *rsp = mid->resp_buf;
+       struct cifs_tcon *tcon;
+       int rc;
+-      if ((mid->optype & CIFS_CP_CREATE_CLOSE_OP) || sync_hdr->Command != SMB2_CREATE ||
+-          sync_hdr->Status != STATUS_SUCCESS)
++      if ((mid->optype & CIFS_CP_CREATE_CLOSE_OP) || hdr->Command != SMB2_CREATE ||
++          hdr->Status != STATUS_SUCCESS)
+               return 0;
+-      tcon = smb2_find_smb_tcon(server, sync_hdr->SessionId,
+-                                sync_hdr->TreeId);
++      tcon = smb2_find_smb_tcon(server, le64_to_cpu(hdr->SessionId),
++                                le32_to_cpu(hdr->Id.SyncId.TreeId));
+       if (!tcon)
+               return -ENOENT;
+       rc = __smb2_handle_cancelled_cmd(tcon,
+-                                       le16_to_cpu(sync_hdr->Command),
+-                                       le64_to_cpu(sync_hdr->MessageId),
++                                       le16_to_cpu(hdr->Command),
++                                       le64_to_cpu(hdr->MessageId),
+                                        rsp->PersistentFileId,
+                                        rsp->VolatileFileId);
+       if (rc)
+@@ -868,10 +867,10 @@ smb311_update_preauth_hash(struct cifs_s
+ {
+       int i, rc;
+       struct sdesc *d;
+-      struct smb2_sync_hdr *hdr;
++      struct smb2_hdr *hdr;
+       struct TCP_Server_Info *server = cifs_ses_server(ses);
+-      hdr = (struct smb2_sync_hdr *)iov[0].iov_base;
++      hdr = (struct smb2_hdr *)iov[0].iov_base;
+       /* neg prot are always taken */
+       if (hdr->Command == SMB2_NEGOTIATE)
+               goto ok;
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -268,7 +268,7 @@ static struct mid_q_entry *
+ __smb2_find_mid(struct TCP_Server_Info *server, char *buf, bool dequeue)
+ {
+       struct mid_q_entry *mid;
+-      struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
++      struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
+       __u64 wire_mid = le64_to_cpu(shdr->MessageId);
+       if (shdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) {
+@@ -310,11 +310,11 @@ static void
+ smb2_dump_detail(void *buf, struct TCP_Server_Info *server)
+ {
+ #ifdef CONFIG_CIFS_DEBUG2
+-      struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
++      struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
+       cifs_server_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n",
+                shdr->Command, shdr->Status, shdr->Flags, shdr->MessageId,
+-               shdr->ProcessId);
++               shdr->Id.SyncId.ProcessId);
+       cifs_server_dbg(VFS, "smb buf %p len %u\n", buf,
+                server->ops->calc_smb_size(buf, server));
+ #endif
+@@ -817,7 +817,7 @@ int open_shroot(unsigned int xid, struct
+       oparms.fid->persistent_fid = o_rsp->PersistentFileId;
+       oparms.fid->volatile_fid = o_rsp->VolatileFileId;
+ #ifdef CONFIG_CIFS_DEBUG2
+-      oparms.fid->mid = le64_to_cpu(o_rsp->sync_hdr.MessageId);
++      oparms.fid->mid = le64_to_cpu(o_rsp->hdr.MessageId);
+ #endif /* CIFS_DEBUG2 */
+       memcpy(tcon->crfid.fid, pfid, sizeof(struct cifs_fid));
+@@ -2318,7 +2318,7 @@ smb2_query_dir_first(const unsigned int
+       /* If the open failed there is nothing to do */
+       op_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
+-      if (op_rsp == NULL || op_rsp->sync_hdr.Status != STATUS_SUCCESS) {
++      if (op_rsp == NULL || op_rsp->hdr.Status != STATUS_SUCCESS) {
+               cifs_dbg(FYI, "query_dir_first: open failed rc=%d\n", rc);
+               goto qdf_free;
+       }
+@@ -2337,7 +2337,7 @@ smb2_query_dir_first(const unsigned int
+       atomic_inc(&tcon->num_remote_opens);
+       qd_rsp = (struct smb2_query_directory_rsp *)rsp_iov[1].iov_base;
+-      if (qd_rsp->sync_hdr.Status == STATUS_NO_MORE_FILES) {
++      if (qd_rsp->hdr.Status == STATUS_NO_MORE_FILES) {
+               trace_smb3_query_dir_done(xid, fid->persistent_fid,
+                                         tcon->tid, tcon->ses->Suid, 0, 0);
+               srch_inf->endOfSearch = true;
+@@ -2389,7 +2389,7 @@ smb2_close_dir(const unsigned int xid, s
+ static bool
+ smb2_is_status_pending(char *buf, struct TCP_Server_Info *server)
+ {
+-      struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
++      struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
+       if (shdr->Status != STATUS_PENDING)
+               return false;
+@@ -2407,13 +2407,14 @@ smb2_is_status_pending(char *buf, struct
+ static bool
+ smb2_is_session_expired(char *buf)
+ {
+-      struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
++      struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
+       if (shdr->Status != STATUS_NETWORK_SESSION_EXPIRED &&
+           shdr->Status != STATUS_USER_SESSION_DELETED)
+               return false;
+-      trace_smb3_ses_expired(shdr->TreeId, shdr->SessionId,
++      trace_smb3_ses_expired(le32_to_cpu(shdr->Id.SyncId.TreeId),
++                             le64_to_cpu(shdr->SessionId),
+                              le16_to_cpu(shdr->Command),
+                              le64_to_cpu(shdr->MessageId));
+       cifs_dbg(FYI, "Session expired or deleted\n");
+@@ -2424,7 +2425,7 @@ smb2_is_session_expired(char *buf)
+ static bool
+ smb2_is_status_io_timeout(char *buf)
+ {
+-      struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
++      struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
+       if (shdr->Status == STATUS_IO_TIMEOUT)
+               return true;
+@@ -2448,9 +2449,9 @@ smb2_oplock_response(struct cifs_tcon *t
+ void
+ smb2_set_related(struct smb_rqst *rqst)
+ {
+-      struct smb2_sync_hdr *shdr;
++      struct smb2_hdr *shdr;
+-      shdr = (struct smb2_sync_hdr *)(rqst->rq_iov[0].iov_base);
++      shdr = (struct smb2_hdr *)(rqst->rq_iov[0].iov_base);
+       if (shdr == NULL) {
+               cifs_dbg(FYI, "shdr NULL in smb2_set_related\n");
+               return;
+@@ -2463,13 +2464,13 @@ char smb2_padding[7] = {0, 0, 0, 0, 0, 0
+ void
+ smb2_set_next_command(struct cifs_tcon *tcon, struct smb_rqst *rqst)
+ {
+-      struct smb2_sync_hdr *shdr;
++      struct smb2_hdr *shdr;
+       struct cifs_ses *ses = tcon->ses;
+       struct TCP_Server_Info *server = ses->server;
+       unsigned long len = smb_rqst_len(server, rqst);
+       int i, num_padding;
+-      shdr = (struct smb2_sync_hdr *)(rqst->rq_iov[0].iov_base);
++      shdr = (struct smb2_hdr *)(rqst->rq_iov[0].iov_base);
+       if (shdr == NULL) {
+               cifs_dbg(FYI, "shdr NULL in smb2_set_next_command\n");
+               return;
+@@ -3018,7 +3019,7 @@ smb2_query_symlink(const unsigned int xi
+                               resp_buftype, rsp_iov);
+       create_rsp = rsp_iov[0].iov_base;
+-      if (create_rsp && create_rsp->sync_hdr.Status)
++      if (create_rsp && create_rsp->hdr.Status)
+               err_iov = rsp_iov[0];
+       ioctl_rsp = rsp_iov[1].iov_base;
+@@ -4183,8 +4184,8 @@ static void
+ fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, unsigned int orig_len,
+                  struct smb_rqst *old_rq, __le16 cipher_type)
+ {
+-      struct smb2_sync_hdr *shdr =
+-                      (struct smb2_sync_hdr *)old_rq->rq_iov[0].iov_base;
++      struct smb2_hdr *shdr =
++                      (struct smb2_hdr *)old_rq->rq_iov[0].iov_base;
+       memset(tr_hdr, 0, sizeof(struct smb2_transform_hdr));
+       tr_hdr->ProtocolId = SMB2_TRANSFORM_PROTO_NUM;
+@@ -4322,7 +4323,7 @@ crypt_message(struct TCP_Server_Info *se
+       unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
+       void *creq;
+-      rc = smb2_get_enc_key(server, tr_hdr->SessionId, enc, key);
++      rc = smb2_get_enc_key(server, le64_to_cpu(tr_hdr->SessionId), enc, key);
+       if (rc) {
+               cifs_server_dbg(VFS, "%s: Could not get %scryption key\n", __func__,
+                        enc ? "en" : "de");
+@@ -4608,7 +4609,7 @@ handle_read_data(struct TCP_Server_Info
+       unsigned int cur_page_idx;
+       unsigned int pad_len;
+       struct cifs_readdata *rdata = mid->callback_data;
+-      struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
++      struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
+       struct bio_vec *bvec = NULL;
+       struct iov_iter iter;
+       struct kvec iov;
+@@ -4927,7 +4928,7 @@ receive_encrypted_standard(struct TCP_Se
+ {
+       int ret, length;
+       char *buf = server->smallbuf;
+-      struct smb2_sync_hdr *shdr;
++      struct smb2_hdr *shdr;
+       unsigned int pdu_length = server->pdu_size;
+       unsigned int buf_size;
+       unsigned int next_cmd;
+@@ -4958,7 +4959,7 @@ receive_encrypted_standard(struct TCP_Se
+       next_is_large = server->large_buf;
+ one_more:
+-      shdr = (struct smb2_sync_hdr *)buf;
++      shdr = (struct smb2_hdr *)buf;
+       next_cmd = le32_to_cpu(shdr->NextCommand);
+       if (next_cmd) {
+               if (WARN_ON_ONCE(next_cmd > pdu_length))
+@@ -5029,7 +5030,7 @@ smb3_receive_transform(struct TCP_Server
+       unsigned int orig_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
+       if (pdu_length < sizeof(struct smb2_transform_hdr) +
+-                                              sizeof(struct smb2_sync_hdr)) {
++                                              sizeof(struct smb2_hdr)) {
+               cifs_server_dbg(VFS, "Transform message is too small (%u)\n",
+                        pdu_length);
+               cifs_reconnect(server);
+@@ -5062,7 +5063,7 @@ smb3_handle_read_data(struct TCP_Server_
+ static int
+ smb2_next_header(char *buf)
+ {
+-      struct smb2_sync_hdr *hdr = (struct smb2_sync_hdr *)buf;
++      struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
+       struct smb2_transform_hdr *t_hdr = (struct smb2_transform_hdr *)buf;
+       if (hdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM)
+@@ -5602,7 +5603,7 @@ struct smb_version_values smb20_values =
+       .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
+       .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
+       .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
+-      .header_size = sizeof(struct smb2_sync_hdr),
++      .header_size = sizeof(struct smb2_hdr),
+       .header_preamble_size = 0,
+       .max_header_size = MAX_SMB2_HDR_SIZE,
+       .read_rsp_size = sizeof(struct smb2_read_rsp),
+@@ -5624,7 +5625,7 @@ struct smb_version_values smb21_values =
+       .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
+       .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
+       .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
+-      .header_size = sizeof(struct smb2_sync_hdr),
++      .header_size = sizeof(struct smb2_hdr),
+       .header_preamble_size = 0,
+       .max_header_size = MAX_SMB2_HDR_SIZE,
+       .read_rsp_size = sizeof(struct smb2_read_rsp),
+@@ -5645,7 +5646,7 @@ struct smb_version_values smb3any_values
+       .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
+       .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
+       .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
+-      .header_size = sizeof(struct smb2_sync_hdr),
++      .header_size = sizeof(struct smb2_hdr),
+       .header_preamble_size = 0,
+       .max_header_size = MAX_SMB2_HDR_SIZE,
+       .read_rsp_size = sizeof(struct smb2_read_rsp),
+@@ -5666,7 +5667,7 @@ struct smb_version_values smbdefault_val
+       .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
+       .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
+       .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
+-      .header_size = sizeof(struct smb2_sync_hdr),
++      .header_size = sizeof(struct smb2_hdr),
+       .header_preamble_size = 0,
+       .max_header_size = MAX_SMB2_HDR_SIZE,
+       .read_rsp_size = sizeof(struct smb2_read_rsp),
+@@ -5687,7 +5688,7 @@ struct smb_version_values smb30_values =
+       .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
+       .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
+       .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
+-      .header_size = sizeof(struct smb2_sync_hdr),
++      .header_size = sizeof(struct smb2_hdr),
+       .header_preamble_size = 0,
+       .max_header_size = MAX_SMB2_HDR_SIZE,
+       .read_rsp_size = sizeof(struct smb2_read_rsp),
+@@ -5708,7 +5709,7 @@ struct smb_version_values smb302_values
+       .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
+       .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
+       .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
+-      .header_size = sizeof(struct smb2_sync_hdr),
++      .header_size = sizeof(struct smb2_hdr),
+       .header_preamble_size = 0,
+       .max_header_size = MAX_SMB2_HDR_SIZE,
+       .read_rsp_size = sizeof(struct smb2_read_rsp),
+@@ -5729,7 +5730,7 @@ struct smb_version_values smb311_values
+       .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
+       .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
+       .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
+-      .header_size = sizeof(struct smb2_sync_hdr),
++      .header_size = sizeof(struct smb2_hdr),
+       .header_preamble_size = 0,
+       .max_header_size = MAX_SMB2_HDR_SIZE,
+       .read_rsp_size = sizeof(struct smb2_read_rsp),
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -36,7 +36,6 @@
+ #include <linux/uuid.h>
+ #include <linux/pagemap.h>
+ #include <linux/xattr.h>
+-#include "smb2pdu.h"
+ #include "cifsglob.h"
+ #include "cifsacl.h"
+ #include "cifsproto.h"
+@@ -97,7 +96,7 @@ int smb3_encryption_required(const struc
+ }
+ static void
+-smb2_hdr_assemble(struct smb2_sync_hdr *shdr, __le16 smb2_cmd,
++smb2_hdr_assemble(struct smb2_hdr *shdr, __le16 smb2_cmd,
+                 const struct cifs_tcon *tcon,
+                 struct TCP_Server_Info *server)
+ {
+@@ -117,7 +116,7 @@ smb2_hdr_assemble(struct smb2_sync_hdr *
+       } else {
+               shdr->CreditRequest = cpu_to_le16(2);
+       }
+-      shdr->ProcessId = cpu_to_le32((__u16)current->tgid);
++      shdr->Id.SyncId.ProcessId = cpu_to_le32((__u16)current->tgid);
+       if (!tcon)
+               goto out;
+@@ -128,10 +127,10 @@ smb2_hdr_assemble(struct smb2_sync_hdr *
+               shdr->CreditCharge = cpu_to_le16(1);
+       /* else CreditCharge MBZ */
+-      shdr->TreeId = tcon->tid;
++      shdr->Id.SyncId.TreeId = cpu_to_le32(tcon->tid);
+       /* Uid is not converted */
+       if (tcon->ses)
+-              shdr->SessionId = tcon->ses->Suid;
++              shdr->SessionId = cpu_to_le64(tcon->ses->Suid);
+       /*
+        * If we would set SMB2_FLAGS_DFS_OPERATIONS on open we also would have
+@@ -347,7 +346,7 @@ fill_small_buf(__le16 smb2_command, stru
+              void *buf,
+              unsigned int *total_len)
+ {
+-      struct smb2_sync_pdu *spdu = (struct smb2_sync_pdu *)buf;
++      struct smb2_pdu *spdu = (struct smb2_pdu *)buf;
+       /* lookup word count ie StructureSize from table */
+       __u16 parmsize = smb2_req_struct_sizes[le16_to_cpu(smb2_command)];
+@@ -357,10 +356,10 @@ fill_small_buf(__le16 smb2_command, stru
+        */
+       memset(buf, 0, 256);
+-      smb2_hdr_assemble(&spdu->sync_hdr, smb2_command, tcon, server);
++      smb2_hdr_assemble(&spdu->hdr, smb2_command, tcon, server);
+       spdu->StructureSize2 = cpu_to_le16(parmsize);
+-      *total_len = parmsize + sizeof(struct smb2_sync_hdr);
++      *total_len = parmsize + sizeof(struct smb2_hdr);
+ }
+ /*
+@@ -388,7 +387,7 @@ static int __smb2_plain_req_init(__le16
+       }
+       fill_small_buf(smb2_command, tcon, server,
+-                     (struct smb2_sync_hdr *)(*request_buf),
++                     (struct smb2_hdr *)(*request_buf),
+                      total_len);
+       if (tcon != NULL) {
+@@ -813,7 +812,7 @@ SMB2_negotiate(const unsigned int xid, s
+       if (rc)
+               return rc;
+-      req->sync_hdr.SessionId = 0;
++      req->hdr.SessionId = 0;
+       memset(server->preauth_sha_hash, 0, SMB2_PREAUTH_HASH_SIZE);
+       memset(ses->preauth_sha_hash, 0, SMB2_PREAUTH_HASH_SIZE);
+@@ -969,7 +968,7 @@ SMB2_negotiate(const unsigned int xid, s
+               server->cipher_type = SMB2_ENCRYPTION_AES128_CCM;
+       security_blob = smb2_get_data_area_len(&blob_offset, &blob_length,
+-                                             (struct smb2_sync_hdr *)rsp);
++                                             (struct smb2_hdr *)rsp);
+       /*
+        * See MS-SMB2 section 2.2.4: if no blob, client picks default which
+        * for us will be
+@@ -1206,13 +1205,13 @@ SMB2_sess_alloc_buffer(struct SMB2_sess_
+               return rc;
+       if (sess_data->ses->binding) {
+-              req->sync_hdr.SessionId = sess_data->ses->Suid;
+-              req->sync_hdr.Flags |= SMB2_FLAGS_SIGNED;
++              req->hdr.SessionId = cpu_to_le64(sess_data->ses->Suid);
++              req->hdr.Flags |= SMB2_FLAGS_SIGNED;
+               req->PreviousSessionId = 0;
+               req->Flags = SMB2_SESSION_REQ_FLAG_BINDING;
+       } else {
+               /* First session, not a reauthenticate */
+-              req->sync_hdr.SessionId = 0;
++              req->hdr.SessionId = 0;
+               /*
+                * if reconnect, we need to send previous sess id
+                * otherwise it is 0
+@@ -1222,7 +1221,7 @@ SMB2_sess_alloc_buffer(struct SMB2_sess_
+       }
+       /* enough to enable echos and oplocks and one max size write */
+-      req->sync_hdr.CreditRequest = cpu_to_le16(130);
++      req->hdr.CreditRequest = cpu_to_le16(130);
+       /* only one of SMB2 signing flags may be set in SMB2 request */
+       if (server->sign)
+@@ -1381,7 +1380,7 @@ SMB2_auth_kerberos(struct SMB2_sess_data
+       rsp = (struct smb2_sess_setup_rsp *)sess_data->iov[0].iov_base;
+       /* keep session id and flags if binding */
+       if (!ses->binding) {
+-              ses->Suid = rsp->sync_hdr.SessionId;
++              ses->Suid = le64_to_cpu(rsp->hdr.SessionId);
+               ses->session_flags = le16_to_cpu(rsp->SessionFlags);
+       }
+@@ -1457,7 +1456,7 @@ SMB2_sess_auth_rawntlmssp_negotiate(stru
+       /* If true, rc here is expected and not an error */
+       if (sess_data->buf0_type != CIFS_NO_BUFFER &&
+-              rsp->sync_hdr.Status == STATUS_MORE_PROCESSING_REQUIRED)
++              rsp->hdr.Status == STATUS_MORE_PROCESSING_REQUIRED)
+               rc = 0;
+       if (rc)
+@@ -1479,7 +1478,7 @@ SMB2_sess_auth_rawntlmssp_negotiate(stru
+       /* keep existing ses id and flags if binding */
+       if (!ses->binding) {
+-              ses->Suid = rsp->sync_hdr.SessionId;
++              ses->Suid = le64_to_cpu(rsp->hdr.SessionId);
+               ses->session_flags = le16_to_cpu(rsp->SessionFlags);
+       }
+@@ -1514,7 +1513,7 @@ SMB2_sess_auth_rawntlmssp_authenticate(s
+               goto out;
+       req = (struct smb2_sess_setup_req *) sess_data->iov[0].iov_base;
+-      req->sync_hdr.SessionId = ses->Suid;
++      req->hdr.SessionId = cpu_to_le64(ses->Suid);
+       rc = build_ntlmssp_auth_blob(&ntlmssp_blob, &blob_length, ses,
+                                       sess_data->nls_cp);
+@@ -1540,7 +1539,7 @@ SMB2_sess_auth_rawntlmssp_authenticate(s
+       /* keep existing ses id and flags if binding */
+       if (!ses->binding) {
+-              ses->Suid = rsp->sync_hdr.SessionId;
++              ses->Suid = le64_to_cpu(rsp->hdr.SessionId);
+               ses->session_flags = le16_to_cpu(rsp->SessionFlags);
+       }
+@@ -1671,12 +1670,12 @@ SMB2_logoff(const unsigned int xid, stru
+               return rc;
+        /* since no tcon, smb2_init can not do this, so do here */
+-      req->sync_hdr.SessionId = ses->Suid;
++      req->hdr.SessionId = cpu_to_le64(ses->Suid);
+       if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA)
+               flags |= CIFS_TRANSFORM_REQ;
+       else if (server->sign)
+-              req->sync_hdr.Flags |= SMB2_FLAGS_SIGNED;
++              req->hdr.Flags |= SMB2_FLAGS_SIGNED;
+       flags |= CIFS_NO_RSP_BUF;
+@@ -1783,14 +1782,14 @@ SMB2_tcon(const unsigned int xid, struct
+           !(ses->session_flags &
+                   (SMB2_SESSION_FLAG_IS_GUEST|SMB2_SESSION_FLAG_IS_NULL)) &&
+           ((ses->user_name != NULL) || (ses->sectype == Kerberos)))
+-              req->sync_hdr.Flags |= SMB2_FLAGS_SIGNED;
++              req->hdr.Flags |= SMB2_FLAGS_SIGNED;
+       memset(&rqst, 0, sizeof(struct smb_rqst));
+       rqst.rq_iov = iov;
+       rqst.rq_nvec = 2;
+       /* Need 64 for max size write so ask for more in case not there yet */
+-      req->sync_hdr.CreditRequest = cpu_to_le16(64);
++      req->hdr.CreditRequest = cpu_to_le16(64);
+       rc = cifs_send_recv(xid, ses, server,
+                           &rqst, &resp_buftype, flags, &rsp_iov);
+@@ -1828,7 +1827,7 @@ SMB2_tcon(const unsigned int xid, struct
+       tcon->maximal_access = le32_to_cpu(rsp->MaximalAccess);
+       tcon->tidStatus = CifsGood;
+       tcon->need_reconnect = false;
+-      tcon->tid = rsp->sync_hdr.TreeId;
++      tcon->tid = le32_to_cpu(rsp->hdr.Id.SyncId.TreeId);
+       strlcpy(tcon->treeName, tree, sizeof(tcon->treeName));
+       if ((rsp->Capabilities & SMB2_SHARE_CAP_DFS) &&
+@@ -1849,9 +1848,8 @@ tcon_exit:
+       return rc;
+ tcon_error_exit:
+-      if (rsp && rsp->sync_hdr.Status == STATUS_BAD_NETWORK_NAME) {
++      if (rsp && rsp->hdr.Status == STATUS_BAD_NETWORK_NAME)
+               cifs_tcon_dbg(VFS, "BAD_NETWORK_NAME: %s\n", tree);
+-      }
+       goto tcon_exit;
+ }
+@@ -2585,7 +2583,7 @@ int smb311_posix_mkdir(const unsigned in
+       if (tcon->share_flags & SHI1005_FLAGS_DFS) {
+               int name_len;
+-              req->sync_hdr.Flags |= SMB2_FLAGS_DFS_OPERATIONS;
++              req->hdr.Flags |= SMB2_FLAGS_DFS_OPERATIONS;
+               rc = alloc_path_with_tree_prefix(&copy_path, &copy_size,
+                                                &name_len,
+                                                tcon->treeName, utf16_path);
+@@ -2717,7 +2715,7 @@ SMB2_open_init(struct cifs_tcon *tcon, s
+       if (tcon->share_flags & SHI1005_FLAGS_DFS) {
+               int name_len;
+-              req->sync_hdr.Flags |= SMB2_FLAGS_DFS_OPERATIONS;
++              req->hdr.Flags |= SMB2_FLAGS_DFS_OPERATIONS;
+               rc = alloc_path_with_tree_prefix(&copy_path, &copy_size,
+                                                &name_len,
+                                                tcon->treeName, path);
+@@ -2929,7 +2927,7 @@ SMB2_open(const unsigned int xid, struct
+       oparms->fid->volatile_fid = rsp->VolatileFileId;
+       oparms->fid->access = oparms->desired_access;
+ #ifdef CONFIG_CIFS_DEBUG2
+-      oparms->fid->mid = le64_to_cpu(rsp->sync_hdr.MessageId);
++      oparms->fid->mid = le64_to_cpu(rsp->hdr.MessageId);
+ #endif /* CIFS_DEBUG2 */
+       if (buf) {
+@@ -3035,7 +3033,7 @@ SMB2_ioctl_init(struct cifs_tcon *tcon,
+        * response size smaller.
+        */
+       req->MaxOutputResponse = cpu_to_le32(max_response_size);
+-      req->sync_hdr.CreditCharge =
++      req->hdr.CreditCharge =
+               cpu_to_le16(DIV_ROUND_UP(max(indatalen, max_response_size),
+                                        SMB2_MAX_BUFFER_SIZE));
+       /* always an FSCTL (for now) */
+@@ -3043,7 +3041,7 @@ SMB2_ioctl_init(struct cifs_tcon *tcon,
+       /* validate negotiate request must be signed - see MS-SMB2 3.2.5.5 */
+       if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO)
+-              req->sync_hdr.Flags |= SMB2_FLAGS_SIGNED;
++              req->hdr.Flags |= SMB2_FLAGS_SIGNED;
+       return 0;
+ }
+@@ -3668,7 +3666,7 @@ smb2_echo_callback(struct mid_q_entry *m
+       if (mid->mid_state == MID_RESPONSE_RECEIVED
+           || mid->mid_state == MID_RESPONSE_MALFORMED) {
+-              credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest);
++              credits.value = le16_to_cpu(rsp->hdr.CreditRequest);
+               credits.instance = server->reconnect_instance;
+       }
+@@ -3768,7 +3766,7 @@ SMB2_echo(struct TCP_Server_Info *server
+       if (rc)
+               return rc;
+-      req->sync_hdr.CreditRequest = cpu_to_le16(1);
++      req->hdr.CreditRequest = cpu_to_le16(1);
+       iov[0].iov_len = total_len;
+       iov[0].iov_base = (char *)req;
+@@ -3872,7 +3870,7 @@ smb2_new_read_req(void **buf, unsigned i
+ {
+       int rc = -EACCES;
+       struct smb2_read_plain_req *req = NULL;
+-      struct smb2_sync_hdr *shdr;
++      struct smb2_hdr *shdr;
+       struct TCP_Server_Info *server = io_parms->server;
+       rc = smb2_plain_req_init(SMB2_READ, io_parms->tcon, server,
+@@ -3883,8 +3881,8 @@ smb2_new_read_req(void **buf, unsigned i
+       if (server == NULL)
+               return -ECONNABORTED;
+-      shdr = &req->sync_hdr;
+-      shdr->ProcessId = cpu_to_le32(io_parms->pid);
++      shdr = &req->hdr;
++      shdr->Id.SyncId.ProcessId = cpu_to_le32(io_parms->pid);
+       req->PersistentFileId = io_parms->persistent_fid;
+       req->VolatileFileId = io_parms->volatile_fid;
+@@ -3945,8 +3943,8 @@ smb2_new_read_req(void **buf, unsigned i
+                        * Related requests use info from previous read request
+                        * in chain.
+                        */
+-                      shdr->SessionId = 0xFFFFFFFFFFFFFFFF;
+-                      shdr->TreeId = 0xFFFFFFFF;
++                      shdr->SessionId = cpu_to_le64(0xFFFFFFFFFFFFFFFF);
++                      shdr->Id.SyncId.TreeId = cpu_to_le32(0xFFFFFFFF);
+                       req->PersistentFileId = 0xFFFFFFFFFFFFFFFF;
+                       req->VolatileFileId = 0xFFFFFFFFFFFFFFFF;
+               }
+@@ -3966,8 +3964,8 @@ smb2_readv_callback(struct mid_q_entry *
+       struct cifs_readdata *rdata = mid->callback_data;
+       struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
+       struct TCP_Server_Info *server = rdata->server;
+-      struct smb2_sync_hdr *shdr =
+-                              (struct smb2_sync_hdr *)rdata->iov[0].iov_base;
++      struct smb2_hdr *shdr =
++                              (struct smb2_hdr *)rdata->iov[0].iov_base;
+       struct cifs_credits credits = { .value = 0, .instance = 0 };
+       struct smb_rqst rqst = { .rq_iov = &rdata->iov[1],
+                                .rq_nvec = 1, };
+@@ -4056,7 +4054,7 @@ smb2_async_readv(struct cifs_readdata *r
+ {
+       int rc, flags = 0;
+       char *buf;
+-      struct smb2_sync_hdr *shdr;
++      struct smb2_hdr *shdr;
+       struct cifs_io_parms io_parms;
+       struct smb_rqst rqst = { .rq_iov = rdata->iov,
+                                .rq_nvec = 1 };
+@@ -4089,7 +4087,7 @@ smb2_async_readv(struct cifs_readdata *r
+       rdata->iov[0].iov_base = buf;
+       rdata->iov[0].iov_len = total_len;
+-      shdr = (struct smb2_sync_hdr *)buf;
++      shdr = (struct smb2_hdr *)buf;
+       if (rdata->credits.value > 0) {
+               shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes,
+@@ -4222,7 +4220,7 @@ smb2_writev_callback(struct mid_q_entry
+       switch (mid->mid_state) {
+       case MID_RESPONSE_RECEIVED:
+-              credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest);
++              credits.value = le16_to_cpu(rsp->hdr.CreditRequest);
+               credits.instance = server->reconnect_instance;
+               wdata->result = smb2_check_receive(mid, server, 0);
+               if (wdata->result != 0)
+@@ -4248,7 +4246,7 @@ smb2_writev_callback(struct mid_q_entry
+               wdata->result = -EAGAIN;
+               break;
+       case MID_RESPONSE_MALFORMED:
+-              credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest);
++              credits.value = le16_to_cpu(rsp->hdr.CreditRequest);
+               credits.instance = server->reconnect_instance;
+               fallthrough;
+       default:
+@@ -4295,7 +4293,7 @@ smb2_async_writev(struct cifs_writedata
+ {
+       int rc = -EACCES, flags = 0;
+       struct smb2_write_req *req = NULL;
+-      struct smb2_sync_hdr *shdr;
++      struct smb2_hdr *shdr;
+       struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
+       struct TCP_Server_Info *server = wdata->server;
+       struct kvec iov[1];
+@@ -4313,8 +4311,8 @@ smb2_async_writev(struct cifs_writedata
+       if (smb3_encryption_required(tcon))
+               flags |= CIFS_TRANSFORM_REQ;
+-      shdr = (struct smb2_sync_hdr *)req;
+-      shdr->ProcessId = cpu_to_le32(wdata->cfile->pid);
++      shdr = (struct smb2_hdr *)req;
++      shdr->Id.SyncId.ProcessId = cpu_to_le32(wdata->cfile->pid);
+       req->PersistentFileId = wdata->cfile->fid.persistent_fid;
+       req->VolatileFileId = wdata->cfile->fid.volatile_fid;
+@@ -4465,7 +4463,7 @@ SMB2_write(const unsigned int xid, struc
+       if (smb3_encryption_required(io_parms->tcon))
+               flags |= CIFS_TRANSFORM_REQ;
+-      req->sync_hdr.ProcessId = cpu_to_le32(io_parms->pid);
++      req->hdr.Id.SyncId.ProcessId = cpu_to_le32(io_parms->pid);
+       req->PersistentFileId = io_parms->persistent_fid;
+       req->VolatileFileId = io_parms->volatile_fid;
+@@ -4852,7 +4850,7 @@ SMB2_query_directory(const unsigned int
+       if (rc) {
+               if (rc == -ENODATA &&
+-                  rsp->sync_hdr.Status == STATUS_NO_MORE_FILES) {
++                  rsp->hdr.Status == STATUS_NO_MORE_FILES) {
+                       trace_smb3_query_dir_done(xid, persistent_fid,
+                               tcon->tid, tcon->ses->Suid, index, 0);
+                       srch_inf->endOfSearch = true;
+@@ -4900,7 +4898,7 @@ SMB2_set_info_init(struct cifs_tcon *tco
+       if (rc)
+               return rc;
+-      req->sync_hdr.ProcessId = cpu_to_le32(pid);
++      req->hdr.Id.SyncId.ProcessId = cpu_to_le32(pid);
+       req->InfoType = info_type;
+       req->FileInfoClass = info_class;
+       req->PersistentFileId = persistent_fid;
+@@ -5060,7 +5058,7 @@ SMB2_oplock_break(const unsigned int xid
+       req->VolatileFid = volatile_fid;
+       req->PersistentFid = persistent_fid;
+       req->OplockLevel = oplock_level;
+-      req->sync_hdr.CreditRequest = cpu_to_le16(1);
++      req->hdr.CreditRequest = cpu_to_le16(1);
+       flags |= CIFS_NO_RSP_BUF;
+@@ -5367,7 +5365,7 @@ smb2_lockv(const unsigned int xid, struc
+       if (smb3_encryption_required(tcon))
+               flags |= CIFS_TRANSFORM_REQ;
+-      req->sync_hdr.ProcessId = cpu_to_le32(pid);
++      req->hdr.Id.SyncId.ProcessId = cpu_to_le32(pid);
+       req->LockCount = cpu_to_le16(num_lock);
+       req->PersistentFileId = persist_fid;
+@@ -5443,7 +5441,7 @@ SMB2_lease_break(const unsigned int xid,
+       if (smb3_encryption_required(tcon))
+               flags |= CIFS_TRANSFORM_REQ;
+-      req->sync_hdr.CreditRequest = cpu_to_le16(1);
++      req->hdr.CreditRequest = cpu_to_le16(1);
+       req->StructureSize = cpu_to_le16(36);
+       total_len += 12;
+--- a/fs/cifs/smb2pdu.h
++++ b/fs/cifs/smb2pdu.h
+@@ -27,149 +27,12 @@
+ #include <net/sock.h>
+ #include <cifsacl.h>
+-/*
+- * Note that, due to trying to use names similar to the protocol specifications,
+- * there are many mixed case field names in the structures below.  Although
+- * this does not match typical Linux kernel style, it is necessary to be
+- * able to match against the protocol specfication.
+- *
+- * SMB2 commands
+- * Some commands have minimal (wct=0,bcc=0), or uninteresting, responses
+- * (ie no useful data other than the SMB error code itself) and are marked such.
+- * Knowing this helps avoid response buffer allocations and copy in some cases.
+- */
+-
+-/* List of commands in host endian */
+-#define SMB2_NEGOTIATE_HE     0x0000
+-#define SMB2_SESSION_SETUP_HE 0x0001
+-#define SMB2_LOGOFF_HE                0x0002 /* trivial request/resp */
+-#define SMB2_TREE_CONNECT_HE  0x0003
+-#define SMB2_TREE_DISCONNECT_HE       0x0004 /* trivial req/resp */
+-#define SMB2_CREATE_HE                0x0005
+-#define SMB2_CLOSE_HE         0x0006
+-#define SMB2_FLUSH_HE         0x0007 /* trivial resp */
+-#define SMB2_READ_HE          0x0008
+-#define SMB2_WRITE_HE         0x0009
+-#define SMB2_LOCK_HE          0x000A
+-#define SMB2_IOCTL_HE         0x000B
+-#define SMB2_CANCEL_HE                0x000C
+-#define SMB2_ECHO_HE          0x000D
+-#define SMB2_QUERY_DIRECTORY_HE       0x000E
+-#define SMB2_CHANGE_NOTIFY_HE 0x000F
+-#define SMB2_QUERY_INFO_HE    0x0010
+-#define SMB2_SET_INFO_HE      0x0011
+-#define SMB2_OPLOCK_BREAK_HE  0x0012
+-
+-/* The same list in little endian */
+-#define SMB2_NEGOTIATE                cpu_to_le16(SMB2_NEGOTIATE_HE)
+-#define SMB2_SESSION_SETUP    cpu_to_le16(SMB2_SESSION_SETUP_HE)
+-#define SMB2_LOGOFF           cpu_to_le16(SMB2_LOGOFF_HE)
+-#define SMB2_TREE_CONNECT     cpu_to_le16(SMB2_TREE_CONNECT_HE)
+-#define SMB2_TREE_DISCONNECT  cpu_to_le16(SMB2_TREE_DISCONNECT_HE)
+-#define SMB2_CREATE           cpu_to_le16(SMB2_CREATE_HE)
+-#define SMB2_CLOSE            cpu_to_le16(SMB2_CLOSE_HE)
+-#define SMB2_FLUSH            cpu_to_le16(SMB2_FLUSH_HE)
+-#define SMB2_READ             cpu_to_le16(SMB2_READ_HE)
+-#define SMB2_WRITE            cpu_to_le16(SMB2_WRITE_HE)
+-#define SMB2_LOCK             cpu_to_le16(SMB2_LOCK_HE)
+-#define SMB2_IOCTL            cpu_to_le16(SMB2_IOCTL_HE)
+-#define SMB2_CANCEL           cpu_to_le16(SMB2_CANCEL_HE)
+-#define SMB2_ECHO             cpu_to_le16(SMB2_ECHO_HE)
+-#define SMB2_QUERY_DIRECTORY  cpu_to_le16(SMB2_QUERY_DIRECTORY_HE)
+-#define SMB2_CHANGE_NOTIFY    cpu_to_le16(SMB2_CHANGE_NOTIFY_HE)
+-#define SMB2_QUERY_INFO               cpu_to_le16(SMB2_QUERY_INFO_HE)
+-#define SMB2_SET_INFO         cpu_to_le16(SMB2_SET_INFO_HE)
+-#define SMB2_OPLOCK_BREAK     cpu_to_le16(SMB2_OPLOCK_BREAK_HE)
+-
+-#define SMB2_INTERNAL_CMD     cpu_to_le16(0xFFFF)
+-
+-#define NUMBER_OF_SMB2_COMMANDS       0x0013
+-
+ /* 52 transform hdr + 64 hdr + 88 create rsp */
+ #define SMB2_TRANSFORM_HEADER_SIZE 52
+ #define MAX_SMB2_HDR_SIZE 204
+-#define SMB2_PROTO_NUMBER cpu_to_le32(0x424d53fe)
+-#define SMB2_TRANSFORM_PROTO_NUM cpu_to_le32(0x424d53fd)
+-#define SMB2_COMPRESSION_TRANSFORM_ID cpu_to_le32(0x424d53fc)
+-
+-/*
+- * SMB2 Header Definition
+- *
+- * "MBZ" :  Must be Zero
+- * "BB"  :  BugBug, Something to check/review/analyze later
+- * "PDU" :  "Protocol Data Unit" (ie a network "frame")
+- *
+- */
+-
+-#define SMB2_HEADER_STRUCTURE_SIZE cpu_to_le16(64)
+-
+-struct smb2_sync_hdr {
+-      __le32 ProtocolId;      /* 0xFE 'S' 'M' 'B' */
+-      __le16 StructureSize;   /* 64 */
+-      __le16 CreditCharge;    /* MBZ */
+-      __le32 Status;          /* Error from server */
+-      __le16 Command;
+-      __le16 CreditRequest;  /* CreditResponse */
+-      __le32 Flags;
+-      __le32 NextCommand;
+-      __le64 MessageId;
+-      __le32 ProcessId;
+-      __u32  TreeId;          /* opaque - so do not make little endian */
+-      __u64  SessionId;       /* opaque - so do not make little endian */
+-      __u8   Signature[16];
+-} __packed;
+-
+ /* The total header size for SMB2 read and write */
+-#define SMB2_READWRITE_PDU_HEADER_SIZE (48 + sizeof(struct smb2_sync_hdr))
+-
+-struct smb2_sync_pdu {
+-      struct smb2_sync_hdr sync_hdr;
+-      __le16 StructureSize2; /* size of wct area (varies, request specific) */
+-} __packed;
+-
+-#define SMB3_AES_CCM_NONCE 11
+-#define SMB3_AES_GCM_NONCE 12
+-
+-/* Transform flags (for 3.0 dialect this flag indicates CCM */
+-#define TRANSFORM_FLAG_ENCRYPTED      0x0001
+-struct smb2_transform_hdr {
+-      __le32 ProtocolId;      /* 0xFD 'S' 'M' 'B' */
+-      __u8   Signature[16];
+-      __u8   Nonce[16];
+-      __le32 OriginalMessageSize;
+-      __u16  Reserved1;
+-      __le16 Flags; /* EncryptionAlgorithm for 3.0, enc enabled for 3.1.1 */
+-      __u64  SessionId;
+-} __packed;
+-
+-/* See MS-SMB2 2.2.42 */
+-struct smb2_compression_transform_hdr {
+-      __le32 ProtocolId;      /* 0xFC 'S' 'M' 'B' */
+-      __le32 OriginalCompressedSegmentSize;
+-      __le16 CompressionAlgorithm;
+-      __le16 Flags;
+-      __le16 Length; /* if chained it is length, else offset */
+-} __packed;
+-
+-/* See MS-SMB2 2.2.42.1 */
+-#define SMB2_COMPRESSION_FLAG_NONE    0x0000
+-#define SMB2_COMPRESSION_FLAG_CHAINED 0x0001
+-
+-struct compression_payload_header {
+-      __le16  CompressionAlgorithm;
+-      __le16  Flags;
+-      __le32  Length; /* length of compressed playload including field below if present */
+-      /* __le32 OriginalPayloadSize; */ /* optional */
+-} __packed;
+-
+-/* See MS-SMB2 2.2.42.2 */
+-struct compression_pattern_payload_v1 {
+-      __le16  Pattern;
+-      __le16  Reserved1;
+-      __le16  Reserved2;
+-      __le32  Repetitions;
+-} __packed;
++#define SMB2_READWRITE_PDU_HEADER_SIZE (48 + sizeof(struct smb2_hdr))
+ /* See MS-SMB2 2.2.43 */
+ struct smb2_rdma_transform {
+@@ -192,17 +55,6 @@ struct smb2_rdma_encryption_transform {
+ } __packed;
+ /*
+- *    SMB2 flag definitions
+- */
+-#define SMB2_FLAGS_SERVER_TO_REDIR    cpu_to_le32(0x00000001)
+-#define SMB2_FLAGS_ASYNC_COMMAND      cpu_to_le32(0x00000002)
+-#define SMB2_FLAGS_RELATED_OPERATIONS cpu_to_le32(0x00000004)
+-#define SMB2_FLAGS_SIGNED             cpu_to_le32(0x00000008)
+-#define SMB2_FLAGS_PRIORITY_MASK      cpu_to_le32(0x00000070) /* SMB3.1.1 */
+-#define SMB2_FLAGS_DFS_OPERATIONS     cpu_to_le32(0x10000000)
+-#define SMB2_FLAGS_REPLAY_OPERATION   cpu_to_le32(0x20000000) /* SMB3 & up */
+-
+-/*
+  *    Definitions for SMB2 Protocol Data Units (network frames)
+  *
+  *  See MS-SMB2.PDF specification for protocol details.
+@@ -216,7 +68,7 @@ struct smb2_rdma_encryption_transform {
+ #define SMB2_ERROR_STRUCTURE_SIZE2 cpu_to_le16(9)
+ struct smb2_err_rsp {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize;
+       __le16 Reserved; /* MBZ */
+       __le32 ByteCount;  /* even if zero, at least one byte follows */
+@@ -275,7 +127,7 @@ struct share_redirect_error_context_rsp
+ #define SMB2_CLIENT_GUID_SIZE 16
+ struct smb2_negotiate_req {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize; /* Must be 36 */
+       __le16 DialectCount;
+       __le16 SecurityMode;
+@@ -449,7 +301,7 @@ struct smb2_posix_neg_context {
+ } __packed;
+ struct smb2_negotiate_rsp {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize;   /* Must be 65 */
+       __le16 SecurityMode;
+       __le16 DialectRevision;
+@@ -472,7 +324,7 @@ struct smb2_negotiate_rsp {
+ #define SMB2_SESSION_REQ_FLAG_ENCRYPT_DATA    0x04
+ struct smb2_sess_setup_req {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize; /* Must be 25 */
+       __u8   Flags;
+       __u8   SecurityMode;
+@@ -489,7 +341,7 @@ struct smb2_sess_setup_req {
+ #define SMB2_SESSION_FLAG_IS_NULL     0x0002
+ #define SMB2_SESSION_FLAG_ENCRYPT_DATA        0x0004
+ struct smb2_sess_setup_rsp {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize; /* Must be 9 */
+       __le16 SessionFlags;
+       __le16 SecurityBufferOffset;
+@@ -498,160 +350,13 @@ struct smb2_sess_setup_rsp {
+ } __packed;
+ struct smb2_logoff_req {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize;   /* Must be 4 */
+       __le16 Reserved;
+ } __packed;
+ struct smb2_logoff_rsp {
+-      struct smb2_sync_hdr sync_hdr;
+-      __le16 StructureSize;   /* Must be 4 */
+-      __le16 Reserved;
+-} __packed;
+-
+-/* Flags/Reserved for SMB3.1.1 */
+-#define SMB2_TREE_CONNECT_FLAG_CLUSTER_RECONNECT cpu_to_le16(0x0001)
+-#define SMB2_TREE_CONNECT_FLAG_REDIRECT_TO_OWNER cpu_to_le16(0x0002)
+-#define SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT cpu_to_le16(0x0004)
+-
+-struct smb2_tree_connect_req {
+-      struct smb2_sync_hdr sync_hdr;
+-      __le16 StructureSize;   /* Must be 9 */
+-      __le16 Flags; /* Reserved MBZ for dialects prior to SMB3.1.1 */
+-      __le16 PathOffset;
+-      __le16 PathLength;
+-      __u8   Buffer[];        /* variable length */
+-} __packed;
+-
+-/* See MS-SMB2 section 2.2.9.2 */
+-/* Context Types */
+-#define SMB2_RESERVED_TREE_CONNECT_CONTEXT_ID 0x0000
+-#define SMB2_REMOTED_IDENTITY_TREE_CONNECT_CONTEXT_ID cpu_to_le16(0x0001)
+-
+-struct tree_connect_contexts {
+-      __le16 ContextType;
+-      __le16 DataLength;
+-      __le32 Reserved;
+-      __u8   Data[];
+-} __packed;
+-
+-/* Remoted identity tree connect context structures - see MS-SMB2 2.2.9.2.1 */
+-struct smb3_blob_data {
+-      __le16 BlobSize;
+-      __u8   BlobData[];
+-} __packed;
+-
+-/* Valid values for Attr */
+-#define SE_GROUP_MANDATORY            0x00000001
+-#define SE_GROUP_ENABLED_BY_DEFAULT   0x00000002
+-#define SE_GROUP_ENABLED              0x00000004
+-#define SE_GROUP_OWNER                        0x00000008
+-#define SE_GROUP_USE_FOR_DENY_ONLY    0x00000010
+-#define SE_GROUP_INTEGRITY            0x00000020
+-#define SE_GROUP_INTEGRITY_ENABLED    0x00000040
+-#define SE_GROUP_RESOURCE             0x20000000
+-#define SE_GROUP_LOGON_ID             0xC0000000
+-
+-/* struct sid_attr_data is SidData array in BlobData format then le32 Attr */
+-
+-struct sid_array_data {
+-      __le16 SidAttrCount;
+-      /* SidAttrList - array of sid_attr_data structs */
+-} __packed;
+-
+-struct luid_attr_data {
+-
+-} __packed;
+-
+-/*
+- * struct privilege_data is the same as BLOB_DATA - see MS-SMB2 2.2.9.2.1.5
+- * but with size of LUID_ATTR_DATA struct and BlobData set to LUID_ATTR DATA
+- */
+-
+-struct privilege_array_data {
+-      __le16 PrivilegeCount;
+-      /* array of privilege_data structs */
+-} __packed;
+-
+-struct remoted_identity_tcon_context {
+-      __le16 TicketType; /* must be 0x0001 */
+-      __le16 TicketSize; /* total size of this struct */
+-      __le16 User; /* offset to SID_ATTR_DATA struct with user info */
+-      __le16 UserName; /* offset to null terminated Unicode username string */
+-      __le16 Domain; /* offset to null terminated Unicode domain name */
+-      __le16 Groups; /* offset to SID_ARRAY_DATA struct with group info */
+-      __le16 RestrictedGroups; /* similar to above */
+-      __le16 Privileges; /* offset to PRIVILEGE_ARRAY_DATA struct */
+-      __le16 PrimaryGroup; /* offset to SID_ARRAY_DATA struct */
+-      __le16 Owner; /* offset to BLOB_DATA struct */
+-      __le16 DefaultDacl; /* offset to BLOB_DATA struct */
+-      __le16 DeviceGroups; /* offset to SID_ARRAY_DATA struct */
+-      __le16 UserClaims; /* offset to BLOB_DATA struct */
+-      __le16 DeviceClaims; /* offset to BLOB_DATA struct */
+-      __u8   TicketInfo[]; /* variable length buf - remoted identity data */
+-} __packed;
+-
+-struct smb2_tree_connect_req_extension {
+-      __le32 TreeConnectContextOffset;
+-      __le16 TreeConnectContextCount;
+-      __u8  Reserved[10];
+-      __u8  PathName[]; /* variable sized array */
+-      /* followed by array of TreeConnectContexts */
+-} __packed;
+-
+-struct smb2_tree_connect_rsp {
+-      struct smb2_sync_hdr sync_hdr;
+-      __le16 StructureSize;   /* Must be 16 */
+-      __u8   ShareType;  /* see below */
+-      __u8   Reserved;
+-      __le32 ShareFlags; /* see below */
+-      __le32 Capabilities; /* see below */
+-      __le32 MaximalAccess;
+-} __packed;
+-
+-/* Possible ShareType values */
+-#define SMB2_SHARE_TYPE_DISK  0x01
+-#define SMB2_SHARE_TYPE_PIPE  0x02
+-#define       SMB2_SHARE_TYPE_PRINT   0x03
+-
+-/*
+- * Possible ShareFlags - exactly one and only one of the first 4 caching flags
+- * must be set (any of the remaining, SHI1005, flags may be set individually
+- * or in combination.
+- */
+-#define SMB2_SHAREFLAG_MANUAL_CACHING                 0x00000000
+-#define SMB2_SHAREFLAG_AUTO_CACHING                   0x00000010
+-#define SMB2_SHAREFLAG_VDO_CACHING                    0x00000020
+-#define SMB2_SHAREFLAG_NO_CACHING                     0x00000030
+-#define SHI1005_FLAGS_DFS                             0x00000001
+-#define SHI1005_FLAGS_DFS_ROOT                                0x00000002
+-#define SHI1005_FLAGS_RESTRICT_EXCLUSIVE_OPENS                0x00000100
+-#define SHI1005_FLAGS_FORCE_SHARED_DELETE             0x00000200
+-#define SHI1005_FLAGS_ALLOW_NAMESPACE_CACHING         0x00000400
+-#define SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM     0x00000800
+-#define SHI1005_FLAGS_FORCE_LEVELII_OPLOCK            0x00001000
+-#define SHI1005_FLAGS_ENABLE_HASH_V1                  0x00002000
+-#define SHI1005_FLAGS_ENABLE_HASH_V2                  0x00004000
+-#define SHI1005_FLAGS_ENCRYPT_DATA                    0x00008000
+-#define SMB2_SHAREFLAG_IDENTITY_REMOTING              0x00040000 /* 3.1.1 */
+-#define SHI1005_FLAGS_ALL                             0x0004FF33
+-
+-/* Possible share capabilities */
+-#define SMB2_SHARE_CAP_DFS    cpu_to_le32(0x00000008) /* all dialects */
+-#define SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY cpu_to_le32(0x00000010) /* 3.0 */
+-#define SMB2_SHARE_CAP_SCALEOUT       cpu_to_le32(0x00000020) /* 3.0 */
+-#define SMB2_SHARE_CAP_CLUSTER        cpu_to_le32(0x00000040) /* 3.0 */
+-#define SMB2_SHARE_CAP_ASYMMETRIC cpu_to_le32(0x00000080) /* 3.02 */
+-#define SMB2_SHARE_CAP_REDIRECT_TO_OWNER cpu_to_le32(0x00000100) /* 3.1.1 */
+-
+-struct smb2_tree_disconnect_req {
+-      struct smb2_sync_hdr sync_hdr;
+-      __le16 StructureSize;   /* Must be 4 */
+-      __le16 Reserved;
+-} __packed;
+-
+-struct smb2_tree_disconnect_rsp {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize;   /* Must be 4 */
+       __le16 Reserved;
+ } __packed;
+@@ -784,7 +489,7 @@ struct smb2_tree_disconnect_rsp {
+ #define SMB2_CREATE_IOV_SIZE 8
+ struct smb2_create_req {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize;   /* Must be 57 */
+       __u8   SecurityFlags;
+       __u8   RequestedOplockLevel;
+@@ -811,7 +516,7 @@ struct smb2_create_req {
+ #define MAX_SMB2_CREATE_RESPONSE_SIZE 880
+ struct smb2_create_rsp {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize;   /* Must be 89 */
+       __u8   OplockLevel;
+       __u8   Flag;  /* 0x01 if reparse point */
+@@ -1186,7 +891,7 @@ struct duplicate_extents_to_file {
+ #define SMB2_IOCTL_IOV_SIZE 2
+ struct smb2_ioctl_req {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize;   /* Must be 57 */
+       __u16 Reserved;
+       __le32 CtlCode;
+@@ -1204,7 +909,7 @@ struct smb2_ioctl_req {
+ } __packed;
+ struct smb2_ioctl_rsp {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize;   /* Must be 57 */
+       __u16 Reserved;
+       __le32 CtlCode;
+@@ -1222,7 +927,7 @@ struct smb2_ioctl_rsp {
+ /* Currently defined values for close flags */
+ #define SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB      cpu_to_le16(0x0001)
+ struct smb2_close_req {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize;   /* Must be 24 */
+       __le16 Flags;
+       __le32 Reserved;
+@@ -1236,7 +941,7 @@ struct smb2_close_req {
+ #define MAX_SMB2_CLOSE_RESPONSE_SIZE 124
+ struct smb2_close_rsp {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize; /* 60 */
+       __le16 Flags;
+       __le32 Reserved;
+@@ -1250,7 +955,7 @@ struct smb2_close_rsp {
+ } __packed;
+ struct smb2_flush_req {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize;   /* Must be 24 */
+       __le16 Reserved1;
+       __le32 Reserved2;
+@@ -1259,7 +964,7 @@ struct smb2_flush_req {
+ } __packed;
+ struct smb2_flush_rsp {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize;
+       __le16 Reserved;
+ } __packed;
+@@ -1276,7 +981,7 @@ struct smb2_flush_rsp {
+ /* SMB2 read request without RFC1001 length at the beginning */
+ struct smb2_read_plain_req {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize; /* Must be 49 */
+       __u8   Padding; /* offset from start of SMB2 header to place read */
+       __u8   Flags; /* MBZ unless SMB3.02 or later */
+@@ -1297,7 +1002,7 @@ struct smb2_read_plain_req {
+ #define SMB2_READFLAG_RESPONSE_RDMA_TRANSFORM 0x00000001
+ struct smb2_read_rsp {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize; /* Must be 17 */
+       __u8   DataOffset;
+       __u8   Reserved;
+@@ -1312,7 +1017,7 @@ struct smb2_read_rsp {
+ #define SMB2_WRITEFLAG_WRITE_UNBUFFERED       0x00000002      /* SMB3.02 or later */
+ struct smb2_write_req {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize; /* Must be 49 */
+       __le16 DataOffset; /* offset from start of SMB2 header to write data */
+       __le32 Length;
+@@ -1328,7 +1033,7 @@ struct smb2_write_req {
+ } __packed;
+ struct smb2_write_rsp {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize; /* Must be 17 */
+       __u8   DataOffset;
+       __u8   Reserved;
+@@ -1356,7 +1061,7 @@ struct smb2_write_rsp {
+ #define FILE_NOTIFY_CHANGE_STREAM_WRITE               0x00000800
+ struct smb2_change_notify_req {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16  StructureSize;
+       __le16  Flags;
+       __le32  OutputBufferLength;
+@@ -1367,7 +1072,7 @@ struct smb2_change_notify_req {
+ } __packed;
+ struct smb2_change_notify_rsp {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16  StructureSize;  /* Must be 9 */
+       __le16  OutputBufferOffset;
+       __le32  OutputBufferLength;
+@@ -1387,7 +1092,7 @@ struct smb2_lock_element {
+ } __packed;
+ struct smb2_lock_req {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize; /* Must be 48 */
+       __le16 LockCount;
+       __le32 Reserved;
+@@ -1401,19 +1106,19 @@ struct smb2_lock_req {
+ } __packed;
+ struct smb2_lock_rsp {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize; /* Must be 4 */
+       __le16 Reserved;
+ } __packed;
+ struct smb2_echo_req {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize;   /* Must be 4 */
+       __u16  Reserved;
+ } __packed;
+ struct smb2_echo_rsp {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize;   /* Must be 4 */
+       __u16  Reserved;
+ } __packed;
+@@ -1427,7 +1132,7 @@ struct smb2_echo_rsp {
+ #define SMB2_QUERY_DIRECTORY_IOV_SIZE 2
+ struct smb2_query_directory_req {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize; /* Must be 33 */
+       __u8   FileInformationClass;
+       __u8   Flags;
+@@ -1441,7 +1146,7 @@ struct smb2_query_directory_req {
+ } __packed;
+ struct smb2_query_directory_rsp {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize; /* Must be 9 */
+       __le16 OutputBufferOffset;
+       __le32 OutputBufferLength;
+@@ -1474,7 +1179,7 @@ struct smb2_query_directory_rsp {
+ #define SL_INDEX_SPECIFIED    0x00000004
+ struct smb2_query_info_req {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize; /* Must be 41 */
+       __u8   InfoType;
+       __u8   FileInfoClass;
+@@ -1490,7 +1195,7 @@ struct smb2_query_info_req {
+ } __packed;
+ struct smb2_query_info_rsp {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize; /* Must be 9 */
+       __le16 OutputBufferOffset;
+       __le32 OutputBufferLength;
+@@ -1507,7 +1212,7 @@ struct smb2_query_info_rsp {
+ #define SMB2_SET_INFO_IOV_SIZE 3
+ struct smb2_set_info_req {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize; /* Must be 33 */
+       __u8   InfoType;
+       __u8   FileInfoClass;
+@@ -1521,12 +1226,12 @@ struct smb2_set_info_req {
+ } __packed;
+ struct smb2_set_info_rsp {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize; /* Must be 2 */
+ } __packed;
+ struct smb2_oplock_break {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize; /* Must be 24 */
+       __u8   OplockLevel;
+       __u8   Reserved;
+@@ -1538,7 +1243,7 @@ struct smb2_oplock_break {
+ #define SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED cpu_to_le32(0x01)
+ struct smb2_lease_break {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize; /* Must be 44 */
+       __le16 Epoch;
+       __le32 Flags;
+@@ -1551,7 +1256,7 @@ struct smb2_lease_break {
+ } __packed;
+ struct smb2_lease_ack {
+-      struct smb2_sync_hdr sync_hdr;
++      struct smb2_hdr hdr;
+       __le16 StructureSize; /* Must be 36 */
+       __le16 Reserved;
+       __le32 Flags;
+--- a/fs/cifs/smb2proto.h
++++ b/fs/cifs/smb2proto.h
+@@ -38,7 +38,7 @@ extern int smb2_check_message(char *buf,
+                             struct TCP_Server_Info *server);
+ extern unsigned int smb2_calc_size(void *buf, struct TCP_Server_Info *server);
+ extern char *smb2_get_data_area_len(int *off, int *len,
+-                                  struct smb2_sync_hdr *shdr);
++                                  struct smb2_hdr *shdr);
+ extern __le16 *cifs_convert_path_to_utf16(const char *from,
+                                         struct cifs_sb_info *cifs_sb);
+--- a/fs/cifs/smb2transport.c
++++ b/fs/cifs/smb2transport.c
+@@ -33,7 +33,6 @@
+ #include <linux/highmem.h>
+ #include <crypto/algapi.h>
+ #include <crypto/aead.h>
+-#include "smb2pdu.h"
+ #include "cifsglob.h"
+ #include "cifsproto.h"
+ #include "smb2proto.h"
+@@ -227,14 +226,14 @@ smb2_calc_signature(struct smb_rqst *rqs
+       unsigned char smb2_signature[SMB2_HMACSHA256_SIZE];
+       unsigned char *sigptr = smb2_signature;
+       struct kvec *iov = rqst->rq_iov;
+-      struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base;
++      struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base;
+       struct cifs_ses *ses;
+       struct shash_desc *shash;
+       struct crypto_shash *hash;
+       struct sdesc *sdesc = NULL;
+       struct smb_rqst drqst;
+-      ses = smb2_find_smb_ses(server, shdr->SessionId);
++      ses = smb2_find_smb_ses(server, le64_to_cpu(shdr->SessionId));
+       if (!ses) {
+               cifs_server_dbg(VFS, "%s: Could not find session\n", __func__);
+               return 0;
+@@ -563,14 +562,14 @@ smb3_calc_signature(struct smb_rqst *rqs
+       unsigned char smb3_signature[SMB2_CMACAES_SIZE];
+       unsigned char *sigptr = smb3_signature;
+       struct kvec *iov = rqst->rq_iov;
+-      struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base;
++      struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base;
+       struct shash_desc *shash;
+       struct crypto_shash *hash;
+       struct sdesc *sdesc = NULL;
+       struct smb_rqst drqst;
+       u8 key[SMB3_SIGN_KEY_SIZE];
+-      rc = smb2_get_sign_key(shdr->SessionId, server, key);
++      rc = smb2_get_sign_key(le64_to_cpu(shdr->SessionId), server, key);
+       if (rc)
+               return 0;
+@@ -640,12 +639,12 @@ static int
+ smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
+ {
+       int rc = 0;
+-      struct smb2_sync_hdr *shdr;
++      struct smb2_hdr *shdr;
+       struct smb2_sess_setup_req *ssr;
+       bool is_binding;
+       bool is_signed;
+-      shdr = (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
++      shdr = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
+       ssr = (struct smb2_sess_setup_req *)shdr;
+       is_binding = shdr->Command == SMB2_SESSION_SETUP &&
+@@ -671,8 +670,8 @@ smb2_verify_signature(struct smb_rqst *r
+ {
+       unsigned int rc;
+       char server_response_sig[SMB2_SIGNATURE_SIZE];
+-      struct smb2_sync_hdr *shdr =
+-                      (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
++      struct smb2_hdr *shdr =
++                      (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
+       if ((shdr->Command == SMB2_NEGOTIATE) ||
+           (shdr->Command == SMB2_SESSION_SETUP) ||
+@@ -719,7 +718,7 @@ smb2_verify_signature(struct smb_rqst *r
+  */
+ static inline void
+ smb2_seq_num_into_buf(struct TCP_Server_Info *server,
+-                    struct smb2_sync_hdr *shdr)
++                    struct smb2_hdr *shdr)
+ {
+       unsigned int i, num = le16_to_cpu(shdr->CreditCharge);
+@@ -730,7 +729,7 @@ smb2_seq_num_into_buf(struct TCP_Server_
+ }
+ static struct mid_q_entry *
+-smb2_mid_entry_alloc(const struct smb2_sync_hdr *shdr,
++smb2_mid_entry_alloc(const struct smb2_hdr *shdr,
+                    struct TCP_Server_Info *server)
+ {
+       struct mid_q_entry *temp;
+@@ -762,14 +761,15 @@ smb2_mid_entry_alloc(const struct smb2_s
+       atomic_inc(&midCount);
+       temp->mid_state = MID_REQUEST_ALLOCATED;
+-      trace_smb3_cmd_enter(shdr->TreeId, shdr->SessionId,
+-              le16_to_cpu(shdr->Command), temp->mid);
++      trace_smb3_cmd_enter(le32_to_cpu(shdr->Id.SyncId.TreeId),
++                           le64_to_cpu(shdr->SessionId),
++                           le16_to_cpu(shdr->Command), temp->mid);
+       return temp;
+ }
+ static int
+ smb2_get_mid_entry(struct cifs_ses *ses, struct TCP_Server_Info *server,
+-                 struct smb2_sync_hdr *shdr, struct mid_q_entry **mid)
++                 struct smb2_hdr *shdr, struct mid_q_entry **mid)
+ {
+       if (server->tcpStatus == CifsExiting)
+               return -ENOENT;
+@@ -837,8 +837,8 @@ smb2_setup_request(struct cifs_ses *ses,
+                  struct smb_rqst *rqst)
+ {
+       int rc;
+-      struct smb2_sync_hdr *shdr =
+-                      (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
++      struct smb2_hdr *shdr =
++                      (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
+       struct mid_q_entry *mid;
+       smb2_seq_num_into_buf(server, shdr);
+@@ -863,8 +863,8 @@ struct mid_q_entry *
+ smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
+ {
+       int rc;
+-      struct smb2_sync_hdr *shdr =
+-                      (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
++      struct smb2_hdr *shdr =
++                      (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
+       struct mid_q_entry *mid;
+       if (server->tcpStatus == CifsNeedNegotiate &&
+--- /dev/null
++++ b/fs/smbfs_common/smb2pdu.h
+@@ -0,0 +1,318 @@
++/* SPDX-License-Identifier: LGPL-2.1 */
++#ifndef _COMMON_SMB2PDU_H
++#define _COMMON_SMB2PDU_H
++
++/*
++ * Note that, due to trying to use names similar to the protocol specifications,
++ * there are many mixed case field names in the structures below.  Although
++ * this does not match typical Linux kernel style, it is necessary to be
++ * able to match against the protocol specfication.
++ *
++ * SMB2 commands
++ * Some commands have minimal (wct=0,bcc=0), or uninteresting, responses
++ * (ie no useful data other than the SMB error code itself) and are marked such.
++ * Knowing this helps avoid response buffer allocations and copy in some cases.
++ */
++
++/* List of commands in host endian */
++#define SMB2_NEGOTIATE_HE     0x0000
++#define SMB2_SESSION_SETUP_HE 0x0001
++#define SMB2_LOGOFF_HE                0x0002 /* trivial request/resp */
++#define SMB2_TREE_CONNECT_HE  0x0003
++#define SMB2_TREE_DISCONNECT_HE       0x0004 /* trivial req/resp */
++#define SMB2_CREATE_HE                0x0005
++#define SMB2_CLOSE_HE         0x0006
++#define SMB2_FLUSH_HE         0x0007 /* trivial resp */
++#define SMB2_READ_HE          0x0008
++#define SMB2_WRITE_HE         0x0009
++#define SMB2_LOCK_HE          0x000A
++#define SMB2_IOCTL_HE         0x000B
++#define SMB2_CANCEL_HE                0x000C
++#define SMB2_ECHO_HE          0x000D
++#define SMB2_QUERY_DIRECTORY_HE       0x000E
++#define SMB2_CHANGE_NOTIFY_HE 0x000F
++#define SMB2_QUERY_INFO_HE    0x0010
++#define SMB2_SET_INFO_HE      0x0011
++#define SMB2_OPLOCK_BREAK_HE  0x0012
++
++/* The same list in little endian */
++#define SMB2_NEGOTIATE                cpu_to_le16(SMB2_NEGOTIATE_HE)
++#define SMB2_SESSION_SETUP    cpu_to_le16(SMB2_SESSION_SETUP_HE)
++#define SMB2_LOGOFF           cpu_to_le16(SMB2_LOGOFF_HE)
++#define SMB2_TREE_CONNECT     cpu_to_le16(SMB2_TREE_CONNECT_HE)
++#define SMB2_TREE_DISCONNECT  cpu_to_le16(SMB2_TREE_DISCONNECT_HE)
++#define SMB2_CREATE           cpu_to_le16(SMB2_CREATE_HE)
++#define SMB2_CLOSE            cpu_to_le16(SMB2_CLOSE_HE)
++#define SMB2_FLUSH            cpu_to_le16(SMB2_FLUSH_HE)
++#define SMB2_READ             cpu_to_le16(SMB2_READ_HE)
++#define SMB2_WRITE            cpu_to_le16(SMB2_WRITE_HE)
++#define SMB2_LOCK             cpu_to_le16(SMB2_LOCK_HE)
++#define SMB2_IOCTL            cpu_to_le16(SMB2_IOCTL_HE)
++#define SMB2_CANCEL           cpu_to_le16(SMB2_CANCEL_HE)
++#define SMB2_ECHO             cpu_to_le16(SMB2_ECHO_HE)
++#define SMB2_QUERY_DIRECTORY  cpu_to_le16(SMB2_QUERY_DIRECTORY_HE)
++#define SMB2_CHANGE_NOTIFY    cpu_to_le16(SMB2_CHANGE_NOTIFY_HE)
++#define SMB2_QUERY_INFO               cpu_to_le16(SMB2_QUERY_INFO_HE)
++#define SMB2_SET_INFO         cpu_to_le16(SMB2_SET_INFO_HE)
++#define SMB2_OPLOCK_BREAK     cpu_to_le16(SMB2_OPLOCK_BREAK_HE)
++
++#define SMB2_INTERNAL_CMD     cpu_to_le16(0xFFFF)
++
++#define NUMBER_OF_SMB2_COMMANDS       0x0013
++
++/*
++ * SMB2 Header Definition
++ *
++ * "MBZ" :  Must be Zero
++ * "BB"  :  BugBug, Something to check/review/analyze later
++ * "PDU" :  "Protocol Data Unit" (ie a network "frame")
++ *
++ */
++
++#define __SMB2_HEADER_STRUCTURE_SIZE  64
++#define SMB2_HEADER_STRUCTURE_SIZE                            \
++      cpu_to_le16(__SMB2_HEADER_STRUCTURE_SIZE)
++
++#define SMB2_PROTO_NUMBER cpu_to_le32(0x424d53fe)
++#define SMB2_TRANSFORM_PROTO_NUM cpu_to_le32(0x424d53fd)
++#define SMB2_COMPRESSION_TRANSFORM_ID cpu_to_le32(0x424d53fc)
++
++/*
++ *    SMB2 flag definitions
++ */
++#define SMB2_FLAGS_SERVER_TO_REDIR    cpu_to_le32(0x00000001)
++#define SMB2_FLAGS_ASYNC_COMMAND      cpu_to_le32(0x00000002)
++#define SMB2_FLAGS_RELATED_OPERATIONS cpu_to_le32(0x00000004)
++#define SMB2_FLAGS_SIGNED             cpu_to_le32(0x00000008)
++#define SMB2_FLAGS_PRIORITY_MASK      cpu_to_le32(0x00000070) /* SMB3.1.1 */
++#define SMB2_FLAGS_DFS_OPERATIONS     cpu_to_le32(0x10000000)
++#define SMB2_FLAGS_REPLAY_OPERATION   cpu_to_le32(0x20000000) /* SMB3 & up */
++
++/* See MS-SMB2 section 2.2.1 */
++struct smb2_hdr {
++      __le32 ProtocolId;      /* 0xFE 'S' 'M' 'B' */
++      __le16 StructureSize;   /* 64 */
++      __le16 CreditCharge;    /* MBZ */
++      __le32 Status;          /* Error from server */
++      __le16 Command;
++      __le16 CreditRequest;   /* CreditResponse */
++      __le32 Flags;
++      __le32 NextCommand;
++      __le64 MessageId;
++      union {
++              struct {
++                      __le32 ProcessId;
++                      __le32  TreeId;
++              } __packed SyncId;
++              __le64  AsyncId;
++      } __packed Id;
++      __le64  SessionId;
++      __u8   Signature[16];
++} __packed;
++
++struct smb2_pdu {
++      struct smb2_hdr hdr;
++      __le16 StructureSize2; /* size of wct area (varies, request specific) */
++} __packed;
++
++#define SMB3_AES_CCM_NONCE 11
++#define SMB3_AES_GCM_NONCE 12
++
++/* Transform flags (for 3.0 dialect this flag indicates CCM */
++#define TRANSFORM_FLAG_ENCRYPTED      0x0001
++struct smb2_transform_hdr {
++      __le32 ProtocolId;      /* 0xFD 'S' 'M' 'B' */
++      __u8   Signature[16];
++      __u8   Nonce[16];
++      __le32 OriginalMessageSize;
++      __u16  Reserved1;
++      __le16 Flags; /* EncryptionAlgorithm for 3.0, enc enabled for 3.1.1 */
++      __le64  SessionId;
++} __packed;
++
++
++/* See MS-SMB2 2.2.42 */
++struct smb2_compression_transform_hdr_unchained {
++      __le32 ProtocolId;      /* 0xFC 'S' 'M' 'B' */
++      __le32 OriginalCompressedSegmentSize;
++      __le16 CompressionAlgorithm;
++      __le16 Flags;
++      __le16 Length; /* if chained it is length, else offset */
++} __packed;
++
++/* See MS-SMB2 2.2.42.1 */
++#define SMB2_COMPRESSION_FLAG_NONE    0x0000
++#define SMB2_COMPRESSION_FLAG_CHAINED 0x0001
++
++struct compression_payload_header {
++      __le16  CompressionAlgorithm;
++      __le16  Flags;
++      __le32  Length; /* length of compressed playload including field below if present */
++      /* __le32 OriginalPayloadSize; */ /* optional, present when LZNT1, LZ77, LZ77+Huffman */
++} __packed;
++
++/* See MS-SMB2 2.2.42.2 */
++struct smb2_compression_transform_hdr_chained {
++      __le32 ProtocolId;      /* 0xFC 'S' 'M' 'B' */
++      __le32 OriginalCompressedSegmentSize;
++      /* struct compression_payload_header[] */
++} __packed;
++
++/* See MS-SMB2 2.2.42.2.2 */
++struct compression_pattern_payload_v1 {
++      __le16  Pattern;
++      __le16  Reserved1;
++      __le16  Reserved2;
++      __le32  Repetitions;
++} __packed;
++
++/* See MS-SMB2 section 2.2.9.2 */
++/* Context Types */
++#define SMB2_RESERVED_TREE_CONNECT_CONTEXT_ID 0x0000
++#define SMB2_REMOTED_IDENTITY_TREE_CONNECT_CONTEXT_ID cpu_to_le16(0x0001)
++
++struct tree_connect_contexts {
++      __le16 ContextType;
++      __le16 DataLength;
++      __le32 Reserved;
++      __u8   Data[];
++} __packed;
++
++/* Remoted identity tree connect context structures - see MS-SMB2 2.2.9.2.1 */
++struct smb3_blob_data {
++      __le16 BlobSize;
++      __u8   BlobData[];
++} __packed;
++
++/* Valid values for Attr */
++#define SE_GROUP_MANDATORY            0x00000001
++#define SE_GROUP_ENABLED_BY_DEFAULT   0x00000002
++#define SE_GROUP_ENABLED              0x00000004
++#define SE_GROUP_OWNER                        0x00000008
++#define SE_GROUP_USE_FOR_DENY_ONLY    0x00000010
++#define SE_GROUP_INTEGRITY            0x00000020
++#define SE_GROUP_INTEGRITY_ENABLED    0x00000040
++#define SE_GROUP_RESOURCE             0x20000000
++#define SE_GROUP_LOGON_ID             0xC0000000
++
++/* struct sid_attr_data is SidData array in BlobData format then le32 Attr */
++
++struct sid_array_data {
++      __le16 SidAttrCount;
++      /* SidAttrList - array of sid_attr_data structs */
++} __packed;
++
++struct luid_attr_data {
++
++} __packed;
++
++/*
++ * struct privilege_data is the same as BLOB_DATA - see MS-SMB2 2.2.9.2.1.5
++ * but with size of LUID_ATTR_DATA struct and BlobData set to LUID_ATTR DATA
++ */
++
++struct privilege_array_data {
++      __le16 PrivilegeCount;
++      /* array of privilege_data structs */
++} __packed;
++
++struct remoted_identity_tcon_context {
++      __le16 TicketType; /* must be 0x0001 */
++      __le16 TicketSize; /* total size of this struct */
++      __le16 User; /* offset to SID_ATTR_DATA struct with user info */
++      __le16 UserName; /* offset to null terminated Unicode username string */
++      __le16 Domain; /* offset to null terminated Unicode domain name */
++      __le16 Groups; /* offset to SID_ARRAY_DATA struct with group info */
++      __le16 RestrictedGroups; /* similar to above */
++      __le16 Privileges; /* offset to PRIVILEGE_ARRAY_DATA struct */
++      __le16 PrimaryGroup; /* offset to SID_ARRAY_DATA struct */
++      __le16 Owner; /* offset to BLOB_DATA struct */
++      __le16 DefaultDacl; /* offset to BLOB_DATA struct */
++      __le16 DeviceGroups; /* offset to SID_ARRAY_DATA struct */
++      __le16 UserClaims; /* offset to BLOB_DATA struct */
++      __le16 DeviceClaims; /* offset to BLOB_DATA struct */
++      __u8   TicketInfo[]; /* variable length buf - remoted identity data */
++} __packed;
++
++struct smb2_tree_connect_req_extension {
++      __le32 TreeConnectContextOffset;
++      __le16 TreeConnectContextCount;
++      __u8  Reserved[10];
++      __u8  PathName[]; /* variable sized array */
++      /* followed by array of TreeConnectContexts */
++} __packed;
++
++/* Flags/Reserved for SMB3.1.1 */
++#define SMB2_TREE_CONNECT_FLAG_CLUSTER_RECONNECT cpu_to_le16(0x0001)
++#define SMB2_TREE_CONNECT_FLAG_REDIRECT_TO_OWNER cpu_to_le16(0x0002)
++#define SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT cpu_to_le16(0x0004)
++
++struct smb2_tree_connect_req {
++      struct smb2_hdr hdr;
++      __le16 StructureSize;   /* Must be 9 */
++      __le16 Flags;           /* Flags in SMB3.1.1 */
++      __le16 PathOffset;
++      __le16 PathLength;
++      __u8   Buffer[];        /* variable length */
++} __packed;
++
++/* Possible ShareType values */
++#define SMB2_SHARE_TYPE_DISK  0x01
++#define SMB2_SHARE_TYPE_PIPE  0x02
++#define       SMB2_SHARE_TYPE_PRINT   0x03
++
++/*
++ * Possible ShareFlags - exactly one and only one of the first 4 caching flags
++ * must be set (any of the remaining, SHI1005, flags may be set individually
++ * or in combination.
++ */
++#define SMB2_SHAREFLAG_MANUAL_CACHING                 0x00000000
++#define SMB2_SHAREFLAG_AUTO_CACHING                   0x00000010
++#define SMB2_SHAREFLAG_VDO_CACHING                    0x00000020
++#define SMB2_SHAREFLAG_NO_CACHING                     0x00000030
++#define SHI1005_FLAGS_DFS                             0x00000001
++#define SHI1005_FLAGS_DFS_ROOT                                0x00000002
++#define SHI1005_FLAGS_RESTRICT_EXCLUSIVE_OPENS                0x00000100
++#define SHI1005_FLAGS_FORCE_SHARED_DELETE             0x00000200
++#define SHI1005_FLAGS_ALLOW_NAMESPACE_CACHING         0x00000400
++#define SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM     0x00000800
++#define SHI1005_FLAGS_FORCE_LEVELII_OPLOCK            0x00001000
++#define SHI1005_FLAGS_ENABLE_HASH_V1                  0x00002000
++#define SHI1005_FLAGS_ENABLE_HASH_V2                  0x00004000
++#define SHI1005_FLAGS_ENCRYPT_DATA                    0x00008000
++#define SMB2_SHAREFLAG_IDENTITY_REMOTING              0x00040000 /* 3.1.1 */
++#define SMB2_SHAREFLAG_COMPRESS_DATA                  0x00100000 /* 3.1.1 */
++#define SHI1005_FLAGS_ALL                             0x0014FF33
++
++/* Possible share capabilities */
++#define SMB2_SHARE_CAP_DFS    cpu_to_le32(0x00000008) /* all dialects */
++#define SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY cpu_to_le32(0x00000010) /* 3.0 */
++#define SMB2_SHARE_CAP_SCALEOUT       cpu_to_le32(0x00000020) /* 3.0 */
++#define SMB2_SHARE_CAP_CLUSTER        cpu_to_le32(0x00000040) /* 3.0 */
++#define SMB2_SHARE_CAP_ASYMMETRIC cpu_to_le32(0x00000080) /* 3.02 */
++#define SMB2_SHARE_CAP_REDIRECT_TO_OWNER cpu_to_le32(0x00000100) /* 3.1.1 */
++
++struct smb2_tree_connect_rsp {
++      struct smb2_hdr hdr;
++      __le16 StructureSize;   /* Must be 16 */
++      __u8   ShareType;       /* see below */
++      __u8   Reserved;
++      __le32 ShareFlags;      /* see below */
++      __le32 Capabilities;    /* see below */
++      __le32 MaximalAccess;
++} __packed;
++
++struct smb2_tree_disconnect_req {
++      struct smb2_hdr hdr;
++      __le16 StructureSize;   /* Must be 4 */
++      __le16 Reserved;
++} __packed;
++
++struct smb2_tree_disconnect_rsp {
++      struct smb2_hdr hdr;
++      __le16 StructureSize;   /* Must be 4 */
++      __le16 Reserved;
++} __packed;
++
++
++#endif                                /* _COMMON_SMB2PDU_H */
diff --git a/queue-5.10/cifs-remove-check-of-list-iterator-against-head-past-the-loop-body.patch b/queue-5.10/cifs-remove-check-of-list-iterator-against-head-past-the-loop-body.patch
new file mode 100644 (file)
index 0000000..8cc53a8
--- /dev/null
@@ -0,0 +1,63 @@
+From stable+bounces-274568-greg=kroah.com@vger.kernel.org Wed Jul 15 00:04:17 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 18:04:02 -0400
+Subject: cifs: remove check of list iterator against head past the loop body
+To: stable@vger.kernel.org
+Cc: Jakob Koschel <jakobkoschel@gmail.com>, "Paulo Alcantara (SUSE)" <pc@cjr.nz>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714220405.3333589-2-sashal@kernel.org>
+
+From: Jakob Koschel <jakobkoschel@gmail.com>
+
+[ Upstream commit 00c796eecba4898194ea549679797ee28f89a92f ]
+
+When list_for_each_entry() completes the iteration over the whole list
+without breaking the loop, the iterator value will be a bogus pointer
+computed based on the head element.
+
+While it is safe to use the pointer to determine if it was computed
+based on the head element, either with list_entry_is_head() or
+&pos->member == head, using the iterator variable after the loop should
+be avoided.
+
+In preparation to limit the scope of a list iterator to the list
+traversal loop, use a dedicated pointer to point to the found element [1].
+
+Link: https://lore.kernel.org/all/CAHk-=wgRr_D8CB-D9Kg-c=EHreAsk5SqXPwr9Y7k9sA6cWXJ6w@mail.gmail.com/ [1]
+Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
+Signed-off-by: Jakob Koschel <jakobkoschel@gmail.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 53b7c271f06b ("smb: client: restrict implied bcc[0] exemption to responses without data area")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/smb2misc.c |   13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+--- a/fs/cifs/smb2misc.c
++++ b/fs/cifs/smb2misc.c
+@@ -154,19 +154,18 @@ smb2_check_message(char *buf, unsigned i
+               struct smb2_transform_hdr *thdr =
+                       (struct smb2_transform_hdr *)buf;
+               struct cifs_ses *ses = NULL;
+-              struct list_head *tmp;
++              struct cifs_ses *iter;
+               /* decrypt frame now that it is completely read in */
+               spin_lock(&cifs_tcp_ses_lock);
+-              list_for_each(tmp, &srvr->smb_ses_list) {
+-                      ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
+-                      if (ses->Suid == le64_to_cpu(thdr->SessionId))
++              list_for_each_entry(iter, &srvr->smb_ses_list, smb_ses_list) {
++                      if (iter->Suid == le64_to_cpu(thdr->SessionId)) {
++                              ses = iter;
+                               break;
+-
+-                      ses = NULL;
++                      }
+               }
+               spin_unlock(&cifs_tcp_ses_lock);
+-              if (ses == NULL) {
++              if (!ses) {
+                       cifs_dbg(VFS, "no decryption - session id not found\n");
+                       return 1;
+               }
diff --git a/queue-5.10/cifs-remove-unused-server-parameter-from-calc_smb_size.patch b/queue-5.10/cifs-remove-unused-server-parameter-from-calc_smb_size.patch
new file mode 100644 (file)
index 0000000..7bd0ae5
--- /dev/null
@@ -0,0 +1,151 @@
+From stable+bounces-274570-greg=kroah.com@vger.kernel.org Wed Jul 15 00:04:16 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 18:04:04 -0400
+Subject: cifs: remove unused server parameter from calc_smb_size()
+To: stable@vger.kernel.org
+Cc: Enzo Matsumiya <ematsumiya@suse.de>, "Paulo Alcantara (SUSE)" <pc@cjr.nz>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714220405.3333589-4-sashal@kernel.org>
+
+From: Enzo Matsumiya <ematsumiya@suse.de>
+
+[ Upstream commit 68ed14496b032b0c9ef21b38ee45c6c8f3a18ff1 ]
+
+This parameter is unused by the called function
+
+Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
+Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 53b7c271f06b ("smb: client: restrict implied bcc[0] exemption to responses without data area")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/cifs_debug.c |    2 +-
+ fs/cifs/cifsglob.h   |    2 +-
+ fs/cifs/cifsproto.h  |    2 +-
+ fs/cifs/misc.c       |    2 +-
+ fs/cifs/netmisc.c    |    2 +-
+ fs/cifs/readdir.c    |    6 ++----
+ fs/cifs/smb2misc.c   |    4 ++--
+ fs/cifs/smb2ops.c    |    2 +-
+ fs/cifs/smb2proto.h  |    2 +-
+ 9 files changed, 11 insertions(+), 13 deletions(-)
+
+--- a/fs/cifs/cifs_debug.c
++++ b/fs/cifs/cifs_debug.c
+@@ -41,7 +41,7 @@ void cifs_dump_detail(void *buf, struct
+                smb->Command, smb->Status.CifsError,
+                smb->Flags, smb->Flags2, smb->Mid, smb->Pid);
+       cifs_dbg(VFS, "smb buf %p len %u\n", smb,
+-               server->ops->calc_smb_size(smb, server));
++               server->ops->calc_smb_size(smb));
+ #endif /* CONFIG_CIFS_DEBUG2 */
+ }
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -397,7 +397,7 @@ struct smb_version_operations {
+       int (*close_dir)(const unsigned int, struct cifs_tcon *,
+                        struct cifs_fid *);
+       /* calculate a size of SMB message */
+-      unsigned int (*calc_smb_size)(void *buf, struct TCP_Server_Info *ptcpi);
++      unsigned int (*calc_smb_size)(void *buf);
+       /* check for STATUS_PENDING and process the response if yes */
+       bool (*is_status_pending)(char *buf, struct TCP_Server_Info *server);
+       /* check for STATUS_NETWORK_SESSION_EXPIRED */
+--- a/fs/cifs/cifsproto.h
++++ b/fs/cifs/cifsproto.h
+@@ -148,7 +148,7 @@ extern int cifs_get_writable_path(struct
+ extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
+ extern int cifs_get_readable_path(struct cifs_tcon *tcon, const char *name,
+                                 struct cifsFileInfo **ret_file);
+-extern unsigned int smbCalcSize(void *buf, struct TCP_Server_Info *server);
++extern unsigned int smbCalcSize(void *buf);
+ extern int decode_negTokenInit(unsigned char *security_blob, int length,
+                       struct TCP_Server_Info *server);
+ extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
+--- a/fs/cifs/misc.c
++++ b/fs/cifs/misc.c
+@@ -370,7 +370,7 @@ checkSMB(char *buf, unsigned int total_r
+       /* otherwise, there is enough to get to the BCC */
+       if (check_smb_hdr(smb))
+               return -EIO;
+-      clc_len = smbCalcSize(smb, server);
++      clc_len = smbCalcSize(smb);
+       if (4 + rfclen != total_read) {
+               cifs_dbg(VFS, "Length read does not match RFC1001 length %d\n",
+--- a/fs/cifs/netmisc.c
++++ b/fs/cifs/netmisc.c
+@@ -913,7 +913,7 @@ map_and_check_smb_error(struct mid_q_ent
+  * portion, the number of word parameters and the data portion of the message
+  */
+ unsigned int
+-smbCalcSize(void *buf, struct TCP_Server_Info *server)
++smbCalcSize(void *buf)
+ {
+       struct smb_hdr *ptr = (struct smb_hdr *)buf;
+       return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +
+--- a/fs/cifs/readdir.c
++++ b/fs/cifs/readdir.c
+@@ -801,8 +801,7 @@ find_cifs_entry(const unsigned int xid,
+               end_of_smb = cfile->srch_inf.ntwrk_buf_start +
+                       server->ops->calc_smb_size(
+-                                      cfile->srch_inf.ntwrk_buf_start,
+-                                      server);
++                                      cfile->srch_inf.ntwrk_buf_start);
+               cur_ent = cfile->srch_inf.srch_entries_start;
+               first_entry_in_buffer = cfile->srch_inf.index_of_last_entry
+@@ -1000,8 +999,7 @@ int cifs_readdir(struct file *file, stru
+       cifs_dbg(FYI, "loop through %d times filling dir for net buf %p\n",
+                num_to_fill, cifsFile->srch_inf.ntwrk_buf_start);
+       max_len = tcon->ses->server->ops->calc_smb_size(
+-                      cifsFile->srch_inf.ntwrk_buf_start,
+-                      tcon->ses->server);
++                      cifsFile->srch_inf.ntwrk_buf_start);
+       end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len;
+       tmp_buf = kmalloc(UNICODE_NAME_MAX, GFP_KERNEL);
+--- a/fs/cifs/smb2misc.c
++++ b/fs/cifs/smb2misc.c
+@@ -225,7 +225,7 @@ smb2_check_message(char *buf, unsigned i
+               }
+       }
+-      calc_len = smb2_calc_size(buf, server);
++      calc_len = smb2_calc_size(buf);
+       /* For SMB2_IOCTL, OutputOffset and OutputLength are optional, so might
+        * be 0, and not a real miscalculation */
+@@ -407,7 +407,7 @@ smb2_get_data_area_len(int *off, int *le
+  * portion, the number of word parameters and the data portion of the message.
+  */
+ unsigned int
+-smb2_calc_size(void *buf, struct TCP_Server_Info *srvr)
++smb2_calc_size(void *buf)
+ {
+       struct smb2_pdu *pdu = (struct smb2_pdu *)buf;
+       struct smb2_hdr *shdr = &pdu->hdr;
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -316,7 +316,7 @@ smb2_dump_detail(void *buf, struct TCP_S
+                shdr->Command, shdr->Status, shdr->Flags, shdr->MessageId,
+                shdr->Id.SyncId.ProcessId);
+       cifs_server_dbg(VFS, "smb buf %p len %u\n", buf,
+-               server->ops->calc_smb_size(buf, server));
++               server->ops->calc_smb_size(buf));
+ #endif
+ }
+--- a/fs/cifs/smb2proto.h
++++ b/fs/cifs/smb2proto.h
+@@ -36,7 +36,7 @@ struct smb_rqst;
+ extern int map_smb2_to_linux_error(char *buf, bool log_err);
+ extern int smb2_check_message(char *buf, unsigned int length,
+                             struct TCP_Server_Info *server);
+-extern unsigned int smb2_calc_size(void *buf, struct TCP_Server_Info *server);
++extern unsigned int smb2_calc_size(void *buf);
+ extern char *smb2_get_data_area_len(int *off, int *len,
+                                   struct smb2_hdr *shdr);
+ extern __le16 *cifs_convert_path_to_utf16(const char *from,
diff --git a/queue-5.10/coresight-etb10-restore-atomic_t-for-shared-reading-state.patch b/queue-5.10/coresight-etb10-restore-atomic_t-for-shared-reading-state.patch
new file mode 100644 (file)
index 0000000..9a88ae2
--- /dev/null
@@ -0,0 +1,123 @@
+From stable+bounces-275001-greg=kroah.com@vger.kernel.org Wed Jul 15 18:54:20 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 12:54:05 -0400
+Subject: coresight: etb10: restore atomic_t for shared reading state
+To: stable@vger.kernel.org
+Cc: Runyu Xiao <runyu.xiao@seu.edu.cn>, James Clark <james.clark@linaro.org>, Suzuki K Poulose <suzuki.poulose@arm.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260715165405.963048-1-sashal@kernel.org>
+
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+
+[ Upstream commit fa09f08ede3db3050ae16ae1ed92c902d0cada23 ]
+
+The etb10 miscdevice uses drvdata->reading as a shared exclusivity gate
+for userspace buffer access. etb_open() claims that gate with
+local_cmpxchg(), and etb_release() clears it with local_set().
+
+That gate is shared per-device state rather than CPU-local state. A
+running system can reach it whenever /dev/<etb> is opened, closed, and
+reopened by different tasks while the device remains registered, so the
+same drvdata->reading variable may be claimed on one CPU and later
+cleared on another.
+
+This code used to use atomic_t for the same gate, but commit
+27b10da8fff2 ("coresight: etb10: moving to local atomic operations")
+changed it to local_t even though the access pattern remained cross-task
+and cross-CPU. Restore atomic_t together with atomic_cmpxchg() and
+atomic_set() so the exclusivity gate again uses a primitive intended
+for shared state.
+
+The issue was found on Linux v6.18.21 by our static analysis tool while
+scanning surviving local_t-on-shared-state sites, and then manually
+reviewed against the live etb10 file-op path.
+
+It was runtime-validated with a reproducible QEMU no-device KCSAN PoC
+that kept the same report-local contract:
+
+  1. use one shared struct etb_drvdata carrier and its
+     drvdata->reading gate;
+  2. call etb_open() and etb_release() sequentially on that gate to
+     confirm the original claim/clear path;
+  3. bind the open side to CPU0 and the release side to CPU1 for the
+     same gate to show cross-CPU ownership;
+  4. run bound workers that repeatedly race etb_open() and
+     etb_release() on the same gate until KCSAN reports a target hit.
+
+The harness recorded:
+
+  L1 passed open=1 release=1
+  reading_after_open=1 reading_after_release=0
+  L2 passed open_cpu=0 release_cpu=1
+  cross_cpu_release=1 reading_after=0 open_ret=0
+
+Representative KCSAN excerpt from the no-device validation run:
+
+  BUG: KCSAN: data-race in etb_open.constprop.0.isra.0 [vuln_msv]
+
+  write to 0xffffffffc0003810 of 4 bytes by task 216 on cpu 1:
+   etb_open.constprop.0.isra.0+0x38/0x80 [vuln_msv]
+   l3_worker_thread_fn+0x4f/0xf0 [vuln_msv]
+   kthread+0x17e/0x1c0
+   ret_from_fork+0x22/0x30
+
+  read to 0xffffffffc0003810 of 4 bytes by task 215 on cpu 0:
+   etb_open.constprop.0.isra.0+0x18/0x80 [vuln_msv]
+   l3_worker_thread_fn+0x4f/0xf0 [vuln_msv]
+   kthread+0x17e/0x1c0
+   ret_from_fork+0x22/0x30
+
+  value changed: 0x00000000 -> 0x00000001
+
+  Reported by Kernel Concurrency Sanitizer on:
+  CPU: 0 PID: 215 Comm: etb10_l3_a Tainted: G           O       6.1.66 #2
+
+This no-device harness is not a real ETB10 hardware end-to-end run, but
+it preserves the same shared drvdata->reading gate and the same
+etb_open()/etb_release() claim/clear contract. No real ETB10 hardware
+was available for runtime testing.
+
+Build-tested with:
+  make olddefconfig
+  make -j"$(nproc)" drivers/hwtracing/coresight/coresight-etb10.o
+
+Fixes: 27b10da8fff2 ("coresight: etb10: moving to local atomic operations")
+Cc: stable@vger.kernel.org
+Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Reviewed-by: James Clark <james.clark@linaro.org>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20260528165201.319452-1-runyu.xiao@seu.edu.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hwtracing/coresight/coresight-etb10.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/hwtracing/coresight/coresight-etb10.c
++++ b/drivers/hwtracing/coresight/coresight-etb10.c
+@@ -86,7 +86,7 @@ struct etb_drvdata {
+       struct coresight_device *csdev;
+       struct miscdevice       miscdev;
+       spinlock_t              spinlock;
+-      local_t                 reading;
++      atomic_t                reading;
+       pid_t                   pid;
+       u8                      *buf;
+       u32                     mode;
+@@ -603,7 +603,7 @@ static int etb_open(struct inode *inode,
+       struct etb_drvdata *drvdata = container_of(file->private_data,
+                                                  struct etb_drvdata, miscdev);
+-      if (local_cmpxchg(&drvdata->reading, 0, 1))
++      if (atomic_cmpxchg(&drvdata->reading, 0, 1))
+               return -EBUSY;
+       dev_dbg(&drvdata->csdev->dev, "%s: successfully opened\n", __func__);
+@@ -641,7 +641,7 @@ static int etb_release(struct inode *ino
+ {
+       struct etb_drvdata *drvdata = container_of(file->private_data,
+                                                  struct etb_drvdata, miscdev);
+-      local_set(&drvdata->reading, 0);
++      atomic_set(&drvdata->reading, 0);
+       dev_dbg(&drvdata->csdev->dev, "%s: released\n", __func__);
+       return 0;
diff --git a/queue-5.10/cpufreq-intel_pstate-sync-policy-cur-during-cpu-offline.patch b/queue-5.10/cpufreq-intel_pstate-sync-policy-cur-during-cpu-offline.patch
new file mode 100644 (file)
index 0000000..fc2b922
--- /dev/null
@@ -0,0 +1,56 @@
+From stable+bounces-277188-greg=kroah.com@vger.kernel.org Fri Jul 17 21:23:55 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2026 15:23:48 -0400
+Subject: cpufreq: intel_pstate: Sync policy->cur during CPU offline
+To: stable@vger.kernel.org
+Cc: Fushuai Wang <wangfushuai@baidu.com>, Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>, "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260717192348.2131400-1-sashal@kernel.org>
+
+From: Fushuai Wang <wangfushuai@baidu.com>
+
+[ Upstream commit bcbdaa1086c25a8a5d48e04e1b82fdfb0682b681 ]
+
+When a CPU goes offline with HWP disabled, intel_pstate_set_min_pstate()
+sets the MSR_IA32_PERF_CTL to minimum frequency to prevent SMT siblings
+from being restricted. However, the policy->cur value was not updated,
+leaving it at the previous value.
+
+When the CPU comes back online, governor->limits() checks if target_freq
+equals policy->cur and skips the frequency adjustment if they match. Since
+policy->cur still holds the previous value, the governor does not call
+cpufreq_driver->target to update MSR_IA32_PERF_CTL.
+
+Fix this by synchronizing policy->cur with the hardware state when setting
+minimum pstate during CPU offline.
+
+Fixes: bb18008f8086 ("intel_pstate: Set core to min P state during core offline")
+Cc: stable@vger.kernel.org # 3.15+
+Suggested-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Signed-off-by: Fushuai Wang <wangfushuai@baidu.com>
+[ rjw: Subject refinement ]
+Link: https://patch.msgid.link/20260520032119.30615-1-fushuai.wang@linux.dev
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+[ replaced `cpu->pstate.min_freq` with `cpu->pstate.min_pstate * cpu->pstate.scaling` since 5.10 lacks the min_freq field ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/cpufreq/intel_pstate.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/cpufreq/intel_pstate.c
++++ b/drivers/cpufreq/intel_pstate.c
+@@ -2355,10 +2355,12 @@ static int intel_pstate_cpu_offline(stru
+        * from getting to lower performance levels, so force the minimum
+        * performance on CPU offline to prevent that from happening.
+        */
+-      if (hwp_active)
++      if (hwp_active) {
+               intel_pstate_hwp_offline(cpu);
+-      else
++      } else {
+               intel_pstate_set_min_pstate(cpu);
++              policy->cur = cpu->pstate.min_pstate * cpu->pstate.scaling;
++      }
+       intel_pstate_exit_perf_limits(policy);
diff --git a/queue-5.10/crypto-atmel-drop-explicit-initialization-of-struct-i2c_device_id-driver_data-to-0.patch b/queue-5.10/crypto-atmel-drop-explicit-initialization-of-struct-i2c_device_id-driver_data-to-0.patch
new file mode 100644 (file)
index 0000000..615da35
--- /dev/null
@@ -0,0 +1,39 @@
+From stable+bounces-278069-greg=kroah.com@vger.kernel.org Mon Jul 20 18:03:54 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jul 2026 11:48:12 -0400
+Subject: crypto: atmel - Drop explicit initialization of struct i2c_device_id::driver_data to 0
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@baylibre.com>, "Herbert Xu" <herbert@gondor.apana.org.au>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260720154813.2319486-2-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+
+[ Upstream commit d86ad3911a5d4549297ed810ee450e5772fd665f ]
+
+These drivers don't use the driver_data member of struct i2c_device_id,
+so don't explicitly initialize this member.
+
+This prepares putting driver_data in an anonymous union which requires
+either no initialization or named designators. But it's also a nice
+cleanup on its own.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: ea5e57cc9718 ("crypto: atmel-sha204a - drop hwrng quality reduction for ATSHA204A")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/atmel-ecc.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/crypto/atmel-ecc.c
++++ b/drivers/crypto/atmel-ecc.c
+@@ -387,7 +387,7 @@ MODULE_DEVICE_TABLE(of, atmel_ecc_dt_ids
+ #endif
+ static const struct i2c_device_id atmel_ecc_id[] = {
+-      { "atecc508a", 0 },
++      { "atecc508a" },
+       { }
+ };
+ MODULE_DEVICE_TABLE(i2c, atmel_ecc_id);
diff --git a/queue-5.10/crypto-atmel-sha204a-drop-hwrng-quality-reduction-for-atsha204a.patch b/queue-5.10/crypto-atmel-sha204a-drop-hwrng-quality-reduction-for-atsha204a.patch
new file mode 100644 (file)
index 0000000..c9c6af2
--- /dev/null
@@ -0,0 +1,101 @@
+From stable+bounces-278070-greg=kroah.com@vger.kernel.org Mon Jul 20 17:48:33 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jul 2026 11:48:13 -0400
+Subject: crypto: atmel-sha204a - drop hwrng quality reduction for ATSHA204A
+To: stable@vger.kernel.org
+Cc: Thorsten Blum <thorsten.blum@linux.dev>, Ard Biesheuvel <ardb@kernel.org>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260720154813.2319486-3-sashal@kernel.org>
+
+From: Thorsten Blum <thorsten.blum@linux.dev>
+
+[ Upstream commit ea5e57cc97185329dcc5ebdcaae7e1500bf0ad0b ]
+
+Commit 8006aff15516 ("crypto: atmel-sha204a - Set hwrng quality to
+lowest possible") reduced the hwrng quality to 1 based on a review by
+Bill Cox [1]. However, despite its title, the review only tested the
+ATSHA204, not the ATSHA204A.
+
+In the same thread, Atmel engineer Landon Cox wrote "this behavior has
+been eliminated entirely"[2] in the ATSHA204A and "this problem does not
+affect the ATECC108 or the ATECC108A (or the ATSHA204A)"[3].
+
+According to the official ATSHA204A datasheet [4], the device contains a
+high-quality hardware RNG that combines its output with an internal seed
+value stored in EEPROM or SRAM to generate random numbers. The device
+also implements all security functions using SHA-256, and the driver
+uses the chip's Random command in seed-update mode.
+
+Keep 'quality = 1' for ATSHA204, but drop the explicit hwrng quality
+reduction for ATSHA204A and fall back to the hwrng core default.
+
+[1] https://www.metzdowd.com/pipermail/cryptography/2014-December/023858.html
+[2] https://www.metzdowd.com/pipermail/cryptography/2014-December/023852.html
+[3] https://www.metzdowd.com/pipermail/cryptography/2014-December/023886.html
+[4] https://ww1.microchip.com/downloads/en/DeviceDoc/ATSHA204A-Data-Sheet-40002025A.pdf
+
+Fixes: 8006aff15516 ("crypto: atmel-sha204a - Set hwrng quality to lowest possible")
+Cc: stable@vger.kernel.org
+Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
+Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/atmel-sha204a.c |   19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+--- a/drivers/crypto/atmel-sha204a.c
++++ b/drivers/crypto/atmel-sha204a.c
+@@ -18,6 +18,12 @@
+ #include <linux/workqueue.h>
+ #include "atmel-i2c.h"
++/*
++ * According to review by Bill Cox [1], the ATSHA204 has very low entropy.
++ * [1] https://www.metzdowd.com/pipermail/cryptography/2014-December/023858.html
++ */
++static const unsigned short atsha204_quality = 1;
++
+ static void atmel_sha204a_rng_done(struct atmel_i2c_work_data *work_data,
+                                  void *areq, int status)
+ {
+@@ -96,6 +102,7 @@ static int atmel_sha204a_probe(struct i2
+                              const struct i2c_device_id *id)
+ {
+       struct atmel_i2c_client_priv *i2c_priv;
++      const unsigned short *quality;
+       int ret;
+       ret = atmel_i2c_probe(client, id);
+@@ -109,11 +116,9 @@ static int atmel_sha204a_probe(struct i2
+       i2c_priv->hwrng.name = dev_name(&client->dev);
+       i2c_priv->hwrng.read = atmel_sha204a_rng_read;
+-      /*
+-       * According to review by Bill Cox [1], this HWRNG has very low entropy.
+-       * [1] https://www.metzdowd.com/pipermail/cryptography/2014-December/023858.html
+-       */
+-      i2c_priv->hwrng.quality = 1;
++      quality = i2c_get_match_data(client);
++      if (quality)
++              i2c_priv->hwrng.quality = *quality;
+       ret = devm_hwrng_register(&client->dev, &i2c_priv->hwrng);
+       if (ret)
+@@ -138,14 +143,14 @@ static int atmel_sha204a_remove(struct i
+ }
+ static const struct of_device_id atmel_sha204a_dt_ids[] __maybe_unused = {
+-      { .compatible = "atmel,atsha204", },
++      { .compatible = "atmel,atsha204", .data = &atsha204_quality },
+       { .compatible = "atmel,atsha204a", },
+       { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, atmel_sha204a_dt_ids);
+ static const struct i2c_device_id atmel_sha204a_id[] = {
+-      { "atsha204" },
++      { "atsha204", (kernel_ulong_t)&atsha204_quality },
+       { "atsha204a" },
+       { /* sentinel */ }
+ };
diff --git a/queue-5.10/crypto-atmel-sha204a-mark-of-related-data-as-maybe-unused.patch b/queue-5.10/crypto-atmel-sha204a-mark-of-related-data-as-maybe-unused.patch
new file mode 100644 (file)
index 0000000..c81c2c8
--- /dev/null
@@ -0,0 +1,47 @@
+From stable+bounces-278068-greg=kroah.com@vger.kernel.org Mon Jul 20 18:03:53 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jul 2026 11:48:11 -0400
+Subject: crypto: atmel-sha204a - Mark OF related data as maybe unused
+To: stable@vger.kernel.org
+Cc: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260720154813.2319486-1-sashal@kernel.org>
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 75f3d950054389e2556277e42170e37dd97cd872 ]
+
+The driver can be compile tested with !CONFIG_OF making certain data
+unused:
+
+  drivers/crypto/atmel-sha204a.c:129:34: error: â€˜atmel_sha204a_dt_ids’ defined but not used [-Werror=unused-const-variable=]
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: ea5e57cc9718 ("crypto: atmel-sha204a - drop hwrng quality reduction for ATSHA204A")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/atmel-sha204a.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/crypto/atmel-sha204a.c
++++ b/drivers/crypto/atmel-sha204a.c
+@@ -137,14 +137,16 @@ static int atmel_sha204a_remove(struct i
+       return 0;
+ }
+-static const struct of_device_id atmel_sha204a_dt_ids[] = {
++static const struct of_device_id atmel_sha204a_dt_ids[] __maybe_unused = {
++      { .compatible = "atmel,atsha204", },
+       { .compatible = "atmel,atsha204a", },
+       { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, atmel_sha204a_dt_ids);
+ static const struct i2c_device_id atmel_sha204a_id[] = {
+-      { "atsha204a", 0 },
++      { "atsha204" },
++      { "atsha204a" },
+       { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(i2c, atmel_sha204a_id);
diff --git a/queue-5.10/crypto-qat-fix-restarting-state-leak-on-allocation-failure.patch b/queue-5.10/crypto-qat-fix-restarting-state-leak-on-allocation-failure.patch
new file mode 100644 (file)
index 0000000..b8a1805
--- /dev/null
@@ -0,0 +1,57 @@
+From stable+bounces-278234-greg=kroah.com@vger.kernel.org Mon Jul 20 22:46:18 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jul 2026 16:44:29 -0400
+Subject: crypto: qat - fix restarting state leak on allocation failure
+To: stable@vger.kernel.org
+Cc: Ahsan Atta <ahsan.atta@intel.com>, Maksim Lukoshkov <maksim.lukoshkov@intel.com>, Giovanni Cabiddu <giovanni.cabiddu@intel.com>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260720204429.3338926-1-sashal@kernel.org>
+
+From: Ahsan Atta <ahsan.atta@intel.com>
+
+[ Upstream commit 7d3ed20f7e46b3e991936fedd7a28f3ff4aec8d2 ]
+
+In adf_dev_aer_schedule_reset(), ADF_STATUS_RESTARTING is set before
+allocating reset_data. If the allocation fails, the function returns
+-ENOMEM without queuing reset work, so nothing ever clears the bit.
+This leaves the device permanently stuck in the restarting state,
+causing all subsequent reset attempts to be silently skipped.
+
+Fix this by using test_and_set_bit() to atomically claim the
+RESTARTING state, preventing duplicate reset scheduling races under
+concurrent fatal error reporting. If the subsequent allocation fails,
+clear the bit to restore clean state so future reset attempts can
+proceed.
+
+Cc: stable@vger.kernel.org
+Fixes: d8cba25d2c68 ("crypto: qat - Intel(R) QAT driver framework")
+Signed-off-by: Ahsan Atta <ahsan.atta@intel.com>
+Co-developed-by: Maksim Lukoshkov <maksim.lukoshkov@intel.com>
+Signed-off-by: Maksim Lukoshkov <maksim.lukoshkov@intel.com>
+Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/qat/qat_common/adf_aer.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/crypto/qat/qat_common/adf_aer.c
++++ b/drivers/crypto/qat/qat_common/adf_aer.c
+@@ -116,13 +116,14 @@ static int adf_dev_aer_schedule_reset(st
+       struct adf_reset_dev_data *reset_data;
+       if (!adf_dev_started(accel_dev) ||
+-          test_bit(ADF_STATUS_RESTARTING, &accel_dev->status))
++          test_and_set_bit(ADF_STATUS_RESTARTING, &accel_dev->status))
+               return 0;
+-      set_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
+       reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL);
+-      if (!reset_data)
++      if (!reset_data) {
++              clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
+               return -ENOMEM;
++      }
+       reset_data->accel_dev = accel_dev;
+       init_completion(&reset_data->compl);
+       reset_data->mode = mode;
diff --git a/queue-5.10/crypto-qat-fix-vf2pf-work-teardown-race-in-adf_disable_sriov.patch b/queue-5.10/crypto-qat-fix-vf2pf-work-teardown-race-in-adf_disable_sriov.patch
new file mode 100644 (file)
index 0000000..09d21de
--- /dev/null
@@ -0,0 +1,251 @@
+From stable+bounces-274890-greg=kroah.com@vger.kernel.org Wed Jul 15 13:15:33 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 07:15:23 -0400
+Subject: crypto: qat - fix VF2PF work teardown race in adf_disable_sriov()
+To: stable@vger.kernel.org
+Cc: Giovanni Cabiddu <giovanni.cabiddu@intel.com>, Ahsan Atta <ahsan.atta@intel.com>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260715111523.644545-1-sashal@kernel.org>
+
+From: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+
+[ Upstream commit 277281c10c63791067d24d421f7c43a15faa9096 ]
+
+The VF2PF interrupt handler queues PF-side response work that stores a
+raw pointer to per-VF state (struct adf_accel_vf_info). Currently,
+adf_disable_sriov() destroys per-VF mutexes and frees vf_info without
+stopping new VF2PF work or waiting for in-flight workers to complete. A
+concurrently scheduled or already queued worker can then dereference
+freed memory.
+
+This manifests as a use-after-free when KASAN is enabled:
+
+  BUG: KASAN: null-ptr-deref in mutex_lock+0x76/0xe0
+  Write of size 8 at addr 0000000000000260 by task kworker/24:2/...
+  Workqueue: qat_pf2vf_resp_wq adf_iov_send_resp [intel_qat]
+  Call Trace:
+    kasan_report+0x119/0x140
+    mutex_lock+0x76/0xe0
+    adf_gen4_pfvf_send+0xd4/0x1f0 [intel_qat]
+    adf_recv_and_handle_vf2pf_msg+0x290/0x360 [intel_qat]
+    adf_iov_send_resp+0x8c/0xe0 [intel_qat]
+    process_one_work+0x6ac/0xfd0
+    worker_thread+0x4dd/0xd30
+    kthread+0x326/0x410
+    ret_from_fork+0x33b/0x670
+
+Add a PF-local flag, vf2pf_disabled, that gates work queueing, worker
+processing, and interrupt re-enabling during teardown. Set this flag
+atomically with the hardware interrupt mask inside
+adf_disable_all_vf2pf_interrupts(). After masking, synchronize the AE
+cluster MSI-X interrupt and flush the PF response workqueue before
+tearing down per-VF locks and state so all in-flight work completes
+before vf_info is destroyed.
+
+Introduce adf_enable_all_vf2pf_interrupts() to clear the flag and
+unmask all VF2PF interrupts under the same lock when SR-IOV is
+re-enabled. This ensures the software flag and hardware state transition
+atomically on both the enable and disable paths.
+
+Cc: stable@vger.kernel.org
+Fixes: ed8ccaef52fa ("crypto: qat - Add support for SRIOV")
+Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Reviewed-by: Ahsan Atta <ahsan.atta@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/qat/qat_common/adf_accel_devices.h |    2 +
+ drivers/crypto/qat/qat_common/adf_common_drv.h    |    4 ++
+ drivers/crypto/qat/qat_common/adf_isr.c           |   18 ++++++++++
+ drivers/crypto/qat/qat_common/adf_pf2vf_msg.c     |   22 ++++++++++++
+ drivers/crypto/qat/qat_common/adf_sriov.c         |   38 +++++++++++++++++-----
+ 5 files changed, 76 insertions(+), 8 deletions(-)
+
+--- a/drivers/crypto/qat/qat_common/adf_accel_devices.h
++++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
+@@ -191,6 +191,8 @@ struct adf_accel_dev {
+       struct adf_accel_pci accel_pci_dev;
+       union {
+               struct {
++                      /* prevents VF2PF handling from racing with VF state teardown */
++                      bool vf2pf_disabled;
+                       /* vf_info is non-zero when SR-IOV is init'ed */
+                       struct adf_accel_vf_info *vf_info;
+               } pf;
+--- a/drivers/crypto/qat/qat_common/adf_common_drv.h
++++ b/drivers/crypto/qat/qat_common/adf_common_drv.h
+@@ -125,6 +125,7 @@ void qat_asym_algs_unregister(void);
+ int adf_isr_resource_alloc(struct adf_accel_dev *accel_dev);
+ void adf_isr_resource_free(struct adf_accel_dev *accel_dev);
++void adf_isr_sync_ae_cluster(struct adf_accel_dev *accel_dev);
+ int adf_vf_isr_resource_alloc(struct adf_accel_dev *accel_dev);
+ void adf_vf_isr_resource_free(struct adf_accel_dev *accel_dev);
+@@ -189,6 +190,9 @@ void adf_disable_vf2pf_interrupts(struct
+                                 u32 vf_mask);
+ void adf_enable_vf2pf_interrupts(struct adf_accel_dev *accel_dev,
+                                u32 vf_mask);
++void adf_enable_all_vf2pf_interrupts(struct adf_accel_dev *accel_dev,
++                                   u32 num_vfs);
++void adf_disable_all_vf2pf_interrupts(struct adf_accel_dev *accel_dev);
+ void adf_enable_pf2vf_interrupts(struct adf_accel_dev *accel_dev);
+ void adf_disable_pf2vf_interrupts(struct adf_accel_dev *accel_dev);
+--- a/drivers/crypto/qat/qat_common/adf_isr.c
++++ b/drivers/crypto/qat/qat_common/adf_isr.c
+@@ -117,6 +117,24 @@ static irqreturn_t adf_msix_isr_ae(int i
+       return IRQ_NONE;
+ }
++void adf_isr_sync_ae_cluster(struct adf_accel_dev *accel_dev)
++{
++      struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev;
++      struct adf_hw_device_data *hw_data = accel_dev->hw_device;
++      struct msix_entry *msixe = pci_dev_info->msix_entries.entries;
++      u32 num_entries = pci_dev_info->msix_entries.num_entries;
++      u32 irq_idx;
++
++      if (!test_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status) || !msixe)
++              return;
++
++      irq_idx = num_entries > 1 ? hw_data->num_banks : 0;
++      if (irq_idx >= num_entries)
++              return;
++
++      synchronize_irq(msixe[irq_idx].vector);
++}
++
+ static int adf_request_irqs(struct adf_accel_dev *accel_dev)
+ {
+       struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev;
+--- a/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c
++++ b/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c
+@@ -40,6 +40,9 @@ void adf_enable_vf2pf_interrupts(struct
+       void __iomem *pmisc_addr = pmisc->virt_addr;
+       u32 reg;
++      if (READ_ONCE(accel_dev->pf.vf2pf_disabled))
++              return;
++
+       /* Enable VF2PF Messaging Ints - VFs 1 through 16 per vf_mask[15:0] */
+       if (vf_mask & 0xFFFF) {
+               reg = ADF_CSR_RD(pmisc_addr, ADF_DH895XCC_ERRMSK3);
+@@ -55,6 +58,19 @@ void adf_enable_vf2pf_interrupts(struct
+       }
+ }
++void adf_enable_all_vf2pf_interrupts(struct adf_accel_dev *accel_dev,
++                                   u32 num_vfs)
++{
++      u32 vf_mask;
++
++      vf_mask = BIT_ULL(num_vfs) - 1;
++      if (!vf_mask)
++              return;
++
++      WRITE_ONCE(accel_dev->pf.vf2pf_disabled, false);
++      adf_enable_vf2pf_interrupts(accel_dev, vf_mask);
++}
++
+ void adf_disable_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 vf_mask)
+ {
+       struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+@@ -78,6 +94,12 @@ void adf_disable_vf2pf_interrupts(struct
+       }
+ }
++void adf_disable_all_vf2pf_interrupts(struct adf_accel_dev *accel_dev)
++{
++      WRITE_ONCE(accel_dev->pf.vf2pf_disabled, true);
++      adf_disable_vf2pf_interrupts(accel_dev, GENMASK(31, 0));
++}
++
+ static int __adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr)
+ {
+       struct adf_accel_pci *pci_info = &accel_dev->accel_pci_dev;
+--- a/drivers/crypto/qat/qat_common/adf_sriov.c
++++ b/drivers/crypto/qat/qat_common/adf_sriov.c
+@@ -44,16 +44,27 @@ static void adf_iov_send_resp(struct wor
+ {
+       struct adf_pf2vf_resp *pf2vf_resp =
+               container_of(work, struct adf_pf2vf_resp, pf2vf_resp_work);
++      struct adf_accel_vf_info *vf_info = pf2vf_resp->vf_info;
++      struct adf_accel_dev *accel_dev = vf_info->accel_dev;
+-      adf_vf2pf_req_hndl(pf2vf_resp->vf_info);
++      if (READ_ONCE(accel_dev->pf.vf2pf_disabled))
++              goto out;
++
++      adf_vf2pf_req_hndl(vf_info);
++
++out:
+       kfree(pf2vf_resp);
+ }
+ static void adf_vf2pf_bh_handler(void *data)
+ {
+       struct adf_accel_vf_info *vf_info = (struct adf_accel_vf_info *)data;
++      struct adf_accel_dev *accel_dev = vf_info->accel_dev;
+       struct adf_pf2vf_resp *pf2vf_resp;
++      if (READ_ONCE(accel_dev->pf.vf2pf_disabled))
++              return;
++
+       pf2vf_resp = kzalloc(sizeof(*pf2vf_resp), GFP_ATOMIC);
+       if (!pf2vf_resp)
+               return;
+@@ -63,6 +74,12 @@ static void adf_vf2pf_bh_handler(void *d
+       queue_work(pf2vf_resp_wq, &pf2vf_resp->pf2vf_resp_work);
+ }
++static void adf_flush_pf2vf_resp_wq(void)
++{
++      if (pf2vf_resp_wq)
++              flush_workqueue(pf2vf_resp_wq);
++}
++
+ static int adf_enable_sriov(struct adf_accel_dev *accel_dev)
+ {
+       struct pci_dev *pdev = accel_to_pci_dev(accel_dev);
+@@ -105,7 +122,7 @@ static int adf_enable_sriov(struct adf_a
+       }
+       /* Enable VF to PF interrupts for all VFs */
+-      adf_enable_vf2pf_interrupts(accel_dev, GENMASK_ULL(totalvfs - 1, 0));
++      adf_enable_all_vf2pf_interrupts(accel_dev, totalvfs);
+       /*
+        * Due to the hardware design, when SR-IOV and the ring arbiter
+@@ -142,8 +159,16 @@ void adf_disable_sriov(struct adf_accel_
+       pci_disable_sriov(accel_to_pci_dev(accel_dev));
+-      /* Disable VF to PF interrupts */
+-      adf_disable_vf2pf_interrupts(accel_dev, 0xFFFFFFFF);
++      /* Block VF2PF work and disable VF to PF interrupts */
++      adf_disable_all_vf2pf_interrupts(accel_dev);
++      adf_isr_sync_ae_cluster(accel_dev);
++
++      for (i = 0, vf = accel_dev->pf.vf_info; i < totalvfs; i++, vf++) {
++              tasklet_disable(&vf->vf2pf_bh_tasklet);
++              tasklet_kill(&vf->vf2pf_bh_tasklet);
++      }
++
++      adf_flush_pf2vf_resp_wq();
+       /* Clear Valid bits in ME Thread to PCIe Function Mapping Group A */
+       for (i = 0; i < ME2FUNCTION_MAP_A_NUM_REGS; i++) {
+@@ -159,11 +184,8 @@ void adf_disable_sriov(struct adf_accel_
+               WRITE_CSR_ME2FUNCTION_MAP_B(pmisc_addr, i, reg);
+       }
+-      for (i = 0, vf = accel_dev->pf.vf_info; i < totalvfs; i++, vf++) {
+-              tasklet_disable(&vf->vf2pf_bh_tasklet);
+-              tasklet_kill(&vf->vf2pf_bh_tasklet);
++      for (i = 0, vf = accel_dev->pf.vf_info; i < totalvfs; i++, vf++)
+               mutex_destroy(&vf->pf2vf_lock);
+-      }
+       kfree(accel_dev->pf.vf_info);
+       accel_dev->pf.vf_info = NULL;
diff --git a/queue-5.10/crypto-qat-validate-rsa-crt-component-lengths.patch b/queue-5.10/crypto-qat-validate-rsa-crt-component-lengths.patch
new file mode 100644 (file)
index 0000000..4b2cd05
--- /dev/null
@@ -0,0 +1,87 @@
+From stable+bounces-278317-greg=kroah.com@vger.kernel.org Tue Jul 21 03:28:07 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jul 2026 21:27:55 -0400
+Subject: crypto: qat - validate RSA CRT component lengths
+To: stable@vger.kernel.org
+Cc: Giovanni Cabiddu <giovanni.cabiddu@intel.com>, Ahsan Atta <ahsan.atta@intel.com>, Laurent M Coquerel <laurent.m.coquerel@intel.com>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260721012755.3458522-1-sashal@kernel.org>
+
+From: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+
+[ Upstream commit b3ac78756588059729b9195fcc9f4b37d54057a5 ]
+
+The generic RSA key parser (rsa_helper.c) bounds each CRT component (p,
+q, dp, dq, qinv) by the modulus size n_sz, but qat_rsa_setkey_crt()
+allocates half-size DMA buffers (key_sz / 2) and right-aligns each
+component with:
+
+    memcpy(dst + half_key_sz - len, src, len)
+
+When a CRT component is larger than half_key_sz the subtraction
+underflows and memcpy writes past the DMA buffer, causing memory
+corruption.
+
+Add a len > half_key_sz check next to the existing !len check for each
+of the five CRT components so the driver falls back to the non-CRT path
+instead of writing out of bounds.
+
+Fixes: 879f77e9071f ("crypto: qat - Add RSA CRT mode")
+Cc: stable@vger.kernel.org
+Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Reviewed-by: Ahsan Atta <ahsan.atta@intel.com>
+Reviewed-by: Laurent M Coquerel <laurent.m.coquerel@intel.com>
+Tested-by: Laurent M Coquerel <laurent.m.coquerel@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/qat/qat_common/qat_asym_algs.c |   10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/crypto/qat/qat_common/qat_asym_algs.c
++++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c
+@@ -1030,7 +1030,7 @@ static void qat_rsa_setkey_crt(struct qa
+       ptr = rsa_key->p;
+       len = rsa_key->p_sz;
+       qat_rsa_drop_leading_zeros(&ptr, &len);
+-      if (!len)
++      if (!len || len > half_key_sz)
+               goto err;
+       ctx->p = dma_alloc_coherent(dev, half_key_sz, &ctx->dma_p, GFP_KERNEL);
+       if (!ctx->p)
+@@ -1041,7 +1041,7 @@ static void qat_rsa_setkey_crt(struct qa
+       ptr = rsa_key->q;
+       len = rsa_key->q_sz;
+       qat_rsa_drop_leading_zeros(&ptr, &len);
+-      if (!len)
++      if (!len || len > half_key_sz)
+               goto free_p;
+       ctx->q = dma_alloc_coherent(dev, half_key_sz, &ctx->dma_q, GFP_KERNEL);
+       if (!ctx->q)
+@@ -1052,7 +1052,7 @@ static void qat_rsa_setkey_crt(struct qa
+       ptr = rsa_key->dp;
+       len = rsa_key->dp_sz;
+       qat_rsa_drop_leading_zeros(&ptr, &len);
+-      if (!len)
++      if (!len || len > half_key_sz)
+               goto free_q;
+       ctx->dp = dma_alloc_coherent(dev, half_key_sz, &ctx->dma_dp,
+                                    GFP_KERNEL);
+@@ -1064,7 +1064,7 @@ static void qat_rsa_setkey_crt(struct qa
+       ptr = rsa_key->dq;
+       len = rsa_key->dq_sz;
+       qat_rsa_drop_leading_zeros(&ptr, &len);
+-      if (!len)
++      if (!len || len > half_key_sz)
+               goto free_dp;
+       ctx->dq = dma_alloc_coherent(dev, half_key_sz, &ctx->dma_dq,
+                                    GFP_KERNEL);
+@@ -1076,7 +1076,7 @@ static void qat_rsa_setkey_crt(struct qa
+       ptr = rsa_key->qinv;
+       len = rsa_key->qinv_sz;
+       qat_rsa_drop_leading_zeros(&ptr, &len);
+-      if (!len)
++      if (!len || len > half_key_sz)
+               goto free_dq;
+       ctx->qinv = dma_alloc_coherent(dev, half_key_sz, &ctx->dma_qinv,
+                                      GFP_KERNEL);
diff --git a/queue-5.10/drm-i2c-sil164-drop-no-op-remove-function.patch b/queue-5.10/drm-i2c-sil164-drop-no-op-remove-function.patch
new file mode 100644 (file)
index 0000000..f7bd604
--- /dev/null
@@ -0,0 +1,47 @@
+From stable+bounces-277535-greg=kroah.com@vger.kernel.org Mon Jul 20 04:35:47 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 22:35:35 -0400
+Subject: drm/i2c/sil164: Drop no-op remove function
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>, "Wolfram Sang" <wsa@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260720023539.2968115-1-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit eb09882d64807c24228ed1d005dbbae70860ca3f ]
+
+A remove callback that just returns 0 is equivalent to no callback at all
+as can be seen in i2c_device_remove(). So simplify accordingly.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Stable-dep-of: 1f0bdc2884b6 ("usb: typec: ucsi: ccg: Fix use-after-free of ucsi on remove")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i2c/sil164_drv.c |    7 -------
+ 1 file changed, 7 deletions(-)
+
+--- a/drivers/gpu/drm/i2c/sil164_drv.c
++++ b/drivers/gpu/drm/i2c/sil164_drv.c
+@@ -370,12 +370,6 @@ sil164_probe(struct i2c_client *client,
+       return 0;
+ }
+-static int
+-sil164_remove(struct i2c_client *client)
+-{
+-      return 0;
+-}
+-
+ static struct i2c_client *
+ sil164_detect_slave(struct i2c_client *client)
+ {
+@@ -427,7 +421,6 @@ MODULE_DEVICE_TABLE(i2c, sil164_ids);
+ static struct drm_i2c_encoder_driver sil164_driver = {
+       .i2c_driver = {
+               .probe = sil164_probe,
+-              .remove = sil164_remove,
+               .driver = {
+                       .name = "sil164",
+               },
diff --git a/queue-5.10/gpio-pca953x-make-platform-teardown-callback-return-void.patch b/queue-5.10/gpio-pca953x-make-platform-teardown-callback-return-void.patch
new file mode 100644 (file)
index 0000000..a8561fa
--- /dev/null
@@ -0,0 +1,106 @@
+From stable+bounces-277538-greg=kroah.com@vger.kernel.org Mon Jul 20 04:35:51 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 22:35:38 -0400
+Subject: gpio: pca953x: Make platform teardown callback return void
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>, "Andy Shevchenko" <andy.shevchenko@gmail.com>, "Bartosz Golaszewski" <brgl@bgdev.pl>, "Wolfram Sang" <wsa@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260720023539.2968115-4-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 6a8f359c3132e4f51bdb263ad74ec632c65e55fd ]
+
+All platforms that provide a teardown callback return 0. New users are
+supposed to not make use of platform support, so there is no
+functionality lost.
+
+This patch is a preparation for making i2c remove callbacks return void.
+
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Acked-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Stable-dep-of: 1f0bdc2884b6 ("usb: typec: ucsi: ccg: Fix use-after-free of ucsi on remove")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm/mach-davinci/board-da850-evm.c |   12 ++++--------
+ drivers/gpio/gpio-pca953x.c             |   11 +++--------
+ include/linux/platform_data/pca953x.h   |    2 +-
+ 3 files changed, 8 insertions(+), 17 deletions(-)
+
+--- a/arch/arm/mach-davinci/board-da850-evm.c
++++ b/arch/arm/mach-davinci/board-da850-evm.c
+@@ -519,8 +519,8 @@ exp_setup_sela_fail:
+       return ret;
+ }
+-static int da850_evm_ui_expander_teardown(struct i2c_client *client,
+-                                      unsigned gpio, unsigned ngpio, void *c)
++static void da850_evm_ui_expander_teardown(struct i2c_client *client,
++                                         unsigned gpio, unsigned ngpio, void *c)
+ {
+       platform_device_unregister(&da850_evm_ui_keys_device);
+@@ -532,8 +532,6 @@ static int da850_evm_ui_expander_teardow
+       gpio_free(gpio + DA850_EVM_UI_EXP_SEL_C);
+       gpio_free(gpio + DA850_EVM_UI_EXP_SEL_B);
+       gpio_free(gpio + DA850_EVM_UI_EXP_SEL_A);
+-
+-      return 0;
+ }
+ /* assign the baseboard expander's GPIOs after the UI board's */
+@@ -700,13 +698,11 @@ io_exp_setup_sw_fail:
+       return ret;
+ }
+-static int da850_evm_bb_expander_teardown(struct i2c_client *client,
+-                                      unsigned gpio, unsigned ngpio, void *c)
++static void da850_evm_bb_expander_teardown(struct i2c_client *client,
++                                         unsigned gpio, unsigned ngpio, void *c)
+ {
+       platform_device_unregister(&da850_evm_bb_leds_device);
+       platform_device_unregister(&da850_evm_bb_keys_device);
+-
+-      return 0;
+ }
+ static struct pca953x_platform_data da850_evm_ui_expander_info = {
+--- a/drivers/gpio/gpio-pca953x.c
++++ b/drivers/gpio/gpio-pca953x.c
+@@ -1073,20 +1073,15 @@ static int pca953x_remove(struct i2c_cli
+ {
+       struct pca953x_platform_data *pdata = dev_get_platdata(&client->dev);
+       struct pca953x_chip *chip = i2c_get_clientdata(client);
+-      int ret;
+       if (pdata && pdata->teardown) {
+-              ret = pdata->teardown(client, chip->gpio_chip.base,
+-                                    chip->gpio_chip.ngpio, pdata->context);
+-              if (ret < 0)
+-                      dev_err(&client->dev, "teardown failed, %d\n", ret);
+-      } else {
+-              ret = 0;
++              pdata->teardown(client, chip->gpio_chip.base,
++                              chip->gpio_chip.ngpio, pdata->context);
+       }
+       regulator_disable(chip->regulator);
+-      return ret;
++      return 0;
+ }
+ #ifdef CONFIG_PM_SLEEP
+--- a/include/linux/platform_data/pca953x.h
++++ b/include/linux/platform_data/pca953x.h
+@@ -22,7 +22,7 @@ struct pca953x_platform_data {
+       int             (*setup)(struct i2c_client *client,
+                               unsigned gpio, unsigned ngpio,
+                               void *context);
+-      int             (*teardown)(struct i2c_client *client,
++      void            (*teardown)(struct i2c_client *client,
+                               unsigned gpio, unsigned ngpio,
+                               void *context);
+       const char      *const *names;
diff --git a/queue-5.10/hfs-hfsplus-fix-u32-overflow-in-check_and_correct_requested_length.patch b/queue-5.10/hfs-hfsplus-fix-u32-overflow-in-check_and_correct_requested_length.patch
new file mode 100644 (file)
index 0000000..1bf92a9
--- /dev/null
@@ -0,0 +1,69 @@
+From stable+bounces-277336-greg=kroah.com@vger.kernel.org Sat Jul 18 17:13:09 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jul 2026 11:12:56 -0400
+Subject: hfs/hfsplus: fix u32 overflow in check_and_correct_requested_length
+To: stable@vger.kernel.org
+Cc: Tristan Madani <tristan@talencesecurity.com>, syzbot+6df204b70bf3261691c5@syzkaller.appspotmail.com, syzbot+e76bf3d19b85350571ac@syzkaller.appspotmail.com, Viacheslav Dubeyko <slava@dubeyko.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260718151256.3269669-2-sashal@kernel.org>
+
+From: Tristan Madani <tristan@talencesecurity.com>
+
+[ Upstream commit 966cb76fb2857a4242cab6ea2ea17acf818a3da7 ]
+
+check_and_correct_requested_length() compares (off + len) against
+node_size using u32 arithmetic.  When the caller passes a large len
+value (e.g. from an underflowed subtraction in hfs_brec_remove()),
+off + len can wrap past 2^32 and produce a small result, causing the
+bounds check to pass when it should fail.
+
+For example, with off=14 and len=0xFFFFFFF2 (underflowed from
+data_off - keyoffset - size in hfs_brec_remove), off + len wraps to 6,
+which is less than a typical node_size of 512, so the check passes and
+the subsequent memmove reads ~4GB past the node buffer.
+
+Fix this by widening the addition to u64 before comparing against
+node_size.  This prevents the u32 wrap while keeping the logic
+straightforward.
+
+Reported-by: syzbot+6df204b70bf3261691c5@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=6df204b70bf3261691c5
+Tested-by: syzbot+6df204b70bf3261691c5@syzkaller.appspotmail.com
+Reported-by: syzbot+e76bf3d19b85350571ac@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=e76bf3d19b85350571ac
+Tested-by: syzbot+e76bf3d19b85350571ac@syzkaller.appspotmail.com
+Fixes: a431930c9bac ("hfs: fix slab-out-of-bounds in hfs_bnode_read()")
+Cc: stable@vger.kernel.org
+Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
+Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Link: https://lore.kernel.org/r/20260505111300.3592757-2-tristmd@gmail.com
+Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/hfs/bnode.c          |    2 +-
+ fs/hfsplus/hfsplus_fs.h |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/hfs/bnode.c
++++ b/fs/hfs/bnode.c
+@@ -41,7 +41,7 @@ u32 check_and_correct_requested_length(s
+       node_size = node->tree->node_size;
+-      if ((off + len) > node_size) {
++      if ((u64)off + len > node_size) {
+               u32 new_len = node_size - off;
+               pr_err("requested length has been corrected: "
+--- a/fs/hfsplus/hfsplus_fs.h
++++ b/fs/hfsplus/hfsplus_fs.h
+@@ -614,7 +614,7 @@ u32 check_and_correct_requested_length(s
+       node_size = node->tree->node_size;
+-      if ((off + len) > node_size) {
++      if ((u64)off + len > node_size) {
+               u32 new_len = node_size - off;
+               pr_err("requested length has been corrected: "
diff --git a/queue-5.10/hfs-hfsplus-prevent-getting-negative-values-of-offset-length.patch b/queue-5.10/hfs-hfsplus-prevent-getting-negative-values-of-offset-length.patch
new file mode 100644 (file)
index 0000000..68c526b
--- /dev/null
@@ -0,0 +1,956 @@
+From stable+bounces-277337-greg=kroah.com@vger.kernel.org Sat Jul 18 17:13:07 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jul 2026 11:12:55 -0400
+Subject: hfs/hfsplus: prevent getting negative values of offset/length
+To: stable@vger.kernel.org
+Cc: Viacheslav Dubeyko <slava@dubeyko.com>, John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>, Yangtao Li <frank.li@vivo.com>, linux-fsdevel@vger.kernel.org, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260718151256.3269669-1-sashal@kernel.org>
+
+From: Viacheslav Dubeyko <slava@dubeyko.com>
+
+[ Upstream commit 00c14a09a70e10ae18eb3707d0059291425c04bd ]
+
+The syzbot reported KASAN out-of-bounds issue in
+hfs_bnode_move():
+
+[   45.588165][ T9821] hfs: dst 14, src 65536, len -65536
+[   45.588895][ T9821] ==================================================================
+[   45.590114][ T9821] BUG: KASAN: out-of-bounds in hfs_bnode_move+0xfd/0x140
+[   45.591127][ T9821] Read of size 18446744073709486080 at addr ffff888035935400 by task repro/9821
+[   45.592207][ T9821]
+[   45.592420][ T9821] CPU: 0 UID: 0 PID: 9821 Comm: repro Not tainted 6.16.0-rc7-dirty #42 PREEMPT(full)
+[   45.592428][ T9821] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+[   45.592431][ T9821] Call Trace:
+[   45.592434][ T9821]  <TASK>
+[   45.592437][ T9821]  dump_stack_lvl+0x1c1/0x2a0
+[   45.592446][ T9821]  ? __virt_addr_valid+0x1c8/0x5c0
+[   45.592454][ T9821]  ? __pfx_dump_stack_lvl+0x10/0x10
+[   45.592461][ T9821]  ? rcu_is_watching+0x15/0xb0
+[   45.592469][ T9821]  ? lock_release+0x4b/0x3e0
+[   45.592476][ T9821]  ? __virt_addr_valid+0x1c8/0x5c0
+[   45.592483][ T9821]  ? __virt_addr_valid+0x4a5/0x5c0
+[   45.592491][ T9821]  print_report+0x17e/0x7c0
+[   45.592497][ T9821]  ? __virt_addr_valid+0x1c8/0x5c0
+[   45.592504][ T9821]  ? __virt_addr_valid+0x4a5/0x5c0
+[   45.592511][ T9821]  ? __phys_addr+0xd3/0x180
+[   45.592519][ T9821]  ? hfs_bnode_move+0xfd/0x140
+[   45.592526][ T9821]  kasan_report+0x147/0x180
+[   45.592531][ T9821]  ? _printk+0xcf/0x120
+[   45.592537][ T9821]  ? hfs_bnode_move+0xfd/0x140
+[   45.592544][ T9821]  ? hfs_bnode_move+0xfd/0x140
+[   45.592552][ T9821]  kasan_check_range+0x2b0/0x2c0
+[   45.592557][ T9821]  ? hfs_bnode_move+0xfd/0x140
+[   45.592565][ T9821]  __asan_memmove+0x29/0x70
+[   45.592572][ T9821]  hfs_bnode_move+0xfd/0x140
+[   45.592580][ T9821]  hfs_brec_remove+0x473/0x560
+[   45.592589][ T9821]  hfs_cat_move+0x6fb/0x960
+[   45.592598][ T9821]  ? __pfx_hfs_cat_move+0x10/0x10
+[   45.592607][ T9821]  ? seqcount_lockdep_reader_access+0x122/0x1c0
+[   45.592614][ T9821]  ? lockdep_hardirqs_on+0x9c/0x150
+[   45.592631][ T9821]  ? __lock_acquire+0xaec/0xd80
+[   45.592641][ T9821]  hfs_rename+0x1dc/0x2d0
+[   45.592649][ T9821]  ? __pfx_hfs_rename+0x10/0x10
+[   45.592657][ T9821]  vfs_rename+0xac6/0xed0
+[   45.592664][ T9821]  ? __pfx_vfs_rename+0x10/0x10
+[   45.592670][ T9821]  ? d_alloc+0x144/0x190
+[   45.592677][ T9821]  ? bpf_lsm_path_rename+0x9/0x20
+[   45.592683][ T9821]  ? security_path_rename+0x17d/0x490
+[   45.592691][ T9821]  do_renameat2+0x890/0xc50
+[   45.592699][ T9821]  ? __pfx_do_renameat2+0x10/0x10
+[   45.592707][ T9821]  ? getname_flags+0x1e5/0x540
+[   45.592714][ T9821]  __x64_sys_rename+0x82/0x90
+[   45.592720][ T9821]  ? entry_SYSCALL_64_after_hwframe+0x77/0x7f
+[   45.592725][ T9821]  do_syscall_64+0xf3/0x3a0
+[   45.592741][ T9821]  ? exc_page_fault+0x9f/0xf0
+[   45.592748][ T9821]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
+[   45.592754][ T9821] RIP: 0033:0x7f7f73fe3fc9
+[   45.592760][ T9821] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 48
+[   45.592765][ T9821] RSP: 002b:00007ffc7e116cf8 EFLAGS: 00000283 ORIG_RAX: 0000000000000052
+[   45.592772][ T9821] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f7f73fe3fc9
+[   45.592776][ T9821] RDX: 0000200000000871 RSI: 0000200000000780 RDI: 00002000000003c0
+[   45.592781][ T9821] RBP: 00007ffc7e116d00 R08: 0000000000000000 R09: 00007ffc7e116d30
+[   45.592784][ T9821] R10: fffffffffffffff0 R11: 0000000000000283 R12: 00005557e81f8250
+[   45.592788][ T9821] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
+[   45.592795][ T9821]  </TASK>
+[   45.592797][ T9821]
+[   45.619721][ T9821] The buggy address belongs to the physical page:
+[   45.620300][ T9821] page: refcount:1 mapcount:1 mapping:0000000000000000 index:0x559a88174 pfn:0x35935
+[   45.621150][ T9821] memcg:ffff88810a1d5b00
+[   45.621531][ T9821] anon flags: 0xfff60000020838(uptodate|dirty|lru|owner_2|swapbacked|node=0|zone=1|lastcpupid=0x7ff)
+[   45.622496][ T9821] raw: 00fff60000020838 ffffea0000d64d88 ffff888021753e10 ffff888029da0771
+[   45.623260][ T9821] raw: 0000000559a88174 0000000000000000 0000000100000000 ffff88810a1d5b00
+[   45.624030][ T9821] page dumped because: kasan: bad access detected
+[   45.624602][ T9821] page_owner tracks the page as allocated
+[   45.625115][ T9821] page last allocated via order 0, migratetype Movable, gfp_mask 0x140dca(GFP_HIGHUSER_MOVABLE|__GFP_ZERO0
+[   45.626685][ T9821]  post_alloc_hook+0x240/0x2a0
+[   45.627127][ T9821]  get_page_from_freelist+0x2101/0x21e0
+[   45.627628][ T9821]  __alloc_frozen_pages_noprof+0x274/0x380
+[   45.628154][ T9821]  alloc_pages_mpol+0x241/0x4b0
+[   45.628593][ T9821]  vma_alloc_folio_noprof+0xe4/0x210
+[   45.629066][ T9821]  folio_prealloc+0x30/0x180
+[   45.629487][ T9821]  __handle_mm_fault+0x34bd/0x5640
+[   45.629957][ T9821]  handle_mm_fault+0x40e/0x8e0
+[   45.630392][ T9821]  do_user_addr_fault+0xa81/0x1390
+[   45.630862][ T9821]  exc_page_fault+0x76/0xf0
+[   45.631273][ T9821]  asm_exc_page_fault+0x26/0x30
+[   45.631712][ T9821] page last free pid 5269 tgid 5269 stack trace:
+[   45.632281][ T9821]  free_unref_folios+0xc73/0x14c0
+[   45.632740][ T9821]  folios_put_refs+0x55b/0x640
+[   45.633177][ T9821]  free_pages_and_swap_cache+0x26d/0x510
+[   45.633685][ T9821]  tlb_flush_mmu+0x3a0/0x680
+[   45.634105][ T9821]  tlb_finish_mmu+0xd4/0x200
+[   45.634525][ T9821]  exit_mmap+0x44c/0xb70
+[   45.634914][ T9821]  __mmput+0x118/0x420
+[   45.635286][ T9821]  exit_mm+0x1da/0x2c0
+[   45.635659][ T9821]  do_exit+0x652/0x2330
+[   45.636039][ T9821]  do_group_exit+0x21c/0x2d0
+[   45.636457][ T9821]  __x64_sys_exit_group+0x3f/0x40
+[   45.636915][ T9821]  x64_sys_call+0x21ba/0x21c0
+[   45.637342][ T9821]  do_syscall_64+0xf3/0x3a0
+[   45.637756][ T9821]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
+[   45.638290][ T9821] page has been migrated, last migrate reason: numa_misplaced
+[   45.638956][ T9821]
+[   45.639173][ T9821] Memory state around the buggy address:
+[   45.639677][ T9821]  ffff888035935300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[   45.640397][ T9821]  ffff888035935380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[   45.641117][ T9821] >ffff888035935400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[   45.641837][ T9821]                    ^
+[   45.642207][ T9821]  ffff888035935480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[   45.642929][ T9821]  ffff888035935500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[   45.643650][ T9821] ==================================================================
+
+This commit [1] fixes the issue if an offset inside of b-tree node
+or length of the request is bigger than b-tree node. However,
+this fix is still not ready for negative values
+of the offset or length. Moreover, negative values of
+the offset or length doesn't make sense for b-tree's
+operations. Because we could try to access the memory address
+outside of the beginning of memory page's addresses range.
+Also, using of negative values make logic very complicated,
+unpredictable, and we could access the wrong item(s)
+in the b-tree node.
+
+This patch changes b-tree interface by means of converting
+signed integer arguments of offset and length on u32 type.
+Such conversion has goal to prevent of using negative values
+unintentionally or by mistake in b-tree operations.
+
+[1] 'commit a431930c9bac ("hfs: fix slab-out-of-bounds in hfs_bnode_read()")'
+
+Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
+cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
+cc: Yangtao Li <frank.li@vivo.com>
+cc: linux-fsdevel@vger.kernel.org
+Link: https://lore.kernel.org/r/20251002200020.2578311-1-slava@dubeyko.com
+Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Stable-dep-of: 966cb76fb285 ("hfs/hfsplus: fix u32 overflow in check_and_correct_requested_length")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/hfs/bfind.c          |    2 -
+ fs/hfs/bnode.c          |   52 +++++++++++++++---------------
+ fs/hfs/brec.c           |    2 -
+ fs/hfs/btree.c          |    2 -
+ fs/hfs/btree.h          |   71 ++++++++++++++++++++---------------------
+ fs/hfs/hfs_fs.h         |   83 ++++++++++++++++++++++++++++--------------------
+ fs/hfs/inode.c          |    2 -
+ fs/hfsplus/bfind.c      |    2 -
+ fs/hfsplus/bnode.c      |   60 +++++++++++++++++-----------------
+ fs/hfsplus/brec.c       |    2 -
+ fs/hfsplus/btree.c      |    2 -
+ fs/hfsplus/hfsplus_fs.h |   38 ++++++++++-----------
+ 12 files changed, 167 insertions(+), 151 deletions(-)
+
+--- a/fs/hfs/bfind.c
++++ b/fs/hfs/bfind.c
+@@ -164,7 +164,7 @@ release:
+       return res;
+ }
+-int hfs_brec_read(struct hfs_find_data *fd, void *rec, int rec_len)
++int hfs_brec_read(struct hfs_find_data *fd, void *rec, u32 rec_len)
+ {
+       int res;
+--- a/fs/hfs/bnode.c
++++ b/fs/hfs/bnode.c
+@@ -16,14 +16,14 @@
+ #include "btree.h"
+ static inline
+-bool is_bnode_offset_valid(struct hfs_bnode *node, int off)
++bool is_bnode_offset_valid(struct hfs_bnode *node, u32 off)
+ {
+       bool is_valid = off < node->tree->node_size;
+       if (!is_valid) {
+               pr_err("requested invalid offset: "
+                      "NODE: id %u, type %#x, height %u, "
+-                     "node_size %u, offset %d\n",
++                     "node_size %u, offset %u\n",
+                      node->this, node->type, node->height,
+                      node->tree->node_size, off);
+       }
+@@ -32,7 +32,7 @@ bool is_bnode_offset_valid(struct hfs_bn
+ }
+ static inline
+-int check_and_correct_requested_length(struct hfs_bnode *node, int off, int len)
++u32 check_and_correct_requested_length(struct hfs_bnode *node, u32 off, u32 len)
+ {
+       unsigned int node_size;
+@@ -42,12 +42,12 @@ int check_and_correct_requested_length(s
+       node_size = node->tree->node_size;
+       if ((off + len) > node_size) {
+-              int new_len = (int)node_size - off;
++              u32 new_len = node_size - off;
+               pr_err("requested length has been corrected: "
+                      "NODE: id %u, type %#x, height %u, "
+-                     "node_size %u, offset %d, "
+-                     "requested_len %d, corrected_len %d\n",
++                     "node_size %u, offset %u, "
++                     "requested_len %u, corrected_len %u\n",
+                      node->this, node->type, node->height,
+                      node->tree->node_size, off, len, new_len);
+@@ -57,12 +57,12 @@ int check_and_correct_requested_length(s
+       return len;
+ }
+-void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len)
++void hfs_bnode_read(struct hfs_bnode *node, void *buf, u32 off, u32 len)
+ {
+       struct page *page;
+-      int pagenum;
+-      int bytes_read;
+-      int bytes_to_read;
++      u32 pagenum;
++      u32 bytes_read;
++      u32 bytes_to_read;
+       void *vaddr;
+       memset(buf, 0, len);
+@@ -73,7 +73,7 @@ void hfs_bnode_read(struct hfs_bnode *no
+       if (len == 0) {
+               pr_err("requested zero length: "
+                      "NODE: id %u, type %#x, height %u, "
+-                     "node_size %u, offset %d, len %d\n",
++                     "node_size %u, offset %u, len %u\n",
+                      node->this, node->type, node->height,
+                      node->tree->node_size, off, len);
+               return;
+@@ -89,7 +89,7 @@ void hfs_bnode_read(struct hfs_bnode *no
+               if (pagenum >= node->tree->pages_per_bnode)
+                       break;
+               page = node->page[pagenum];
+-              bytes_to_read = min_t(int, len - bytes_read, PAGE_SIZE - off);
++              bytes_to_read = min_t(u32, len - bytes_read, PAGE_SIZE - off);
+               vaddr = kmap_atomic(page);
+               memcpy(buf + bytes_read, vaddr + off, bytes_to_read);
+@@ -100,7 +100,7 @@ void hfs_bnode_read(struct hfs_bnode *no
+       }
+ }
+-u16 hfs_bnode_read_u16(struct hfs_bnode *node, int off)
++u16 hfs_bnode_read_u16(struct hfs_bnode *node, u32 off)
+ {
+       __be16 data;
+       // optimize later...
+@@ -108,7 +108,7 @@ u16 hfs_bnode_read_u16(struct hfs_bnode
+       return be16_to_cpu(data);
+ }
+-u8 hfs_bnode_read_u8(struct hfs_bnode *node, int off)
++u8 hfs_bnode_read_u8(struct hfs_bnode *node, u32 off)
+ {
+       u8 data;
+       // optimize later...
+@@ -116,10 +116,10 @@ u8 hfs_bnode_read_u8(struct hfs_bnode *n
+       return data;
+ }
+-void hfs_bnode_read_key(struct hfs_bnode *node, void *key, int off)
++void hfs_bnode_read_key(struct hfs_bnode *node, void *key, u32 off)
+ {
+       struct hfs_btree *tree;
+-      int key_len;
++      u32 key_len;
+       tree = node->tree;
+       if (node->type == HFS_NODE_LEAF ||
+@@ -130,14 +130,14 @@ void hfs_bnode_read_key(struct hfs_bnode
+       if (key_len > sizeof(hfs_btree_key) || key_len < 1) {
+               memset(key, 0, sizeof(hfs_btree_key));
+-              pr_err("hfs: Invalid key length: %d\n", key_len);
++              pr_err("hfs: Invalid key length: %u\n", key_len);
+               return;
+       }
+       hfs_bnode_read(node, key, off, key_len);
+ }
+-void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len)
++void hfs_bnode_write(struct hfs_bnode *node, void *buf, u32 off, u32 len)
+ {
+       struct page *page;
+@@ -147,7 +147,7 @@ void hfs_bnode_write(struct hfs_bnode *n
+       if (len == 0) {
+               pr_err("requested zero length: "
+                      "NODE: id %u, type %#x, height %u, "
+-                     "node_size %u, offset %d, len %d\n",
++                     "node_size %u, offset %u, len %u\n",
+                      node->this, node->type, node->height,
+                      node->tree->node_size, off, len);
+               return;
+@@ -163,20 +163,20 @@ void hfs_bnode_write(struct hfs_bnode *n
+       set_page_dirty(page);
+ }
+-void hfs_bnode_write_u16(struct hfs_bnode *node, int off, u16 data)
++void hfs_bnode_write_u16(struct hfs_bnode *node, u32 off, u16 data)
+ {
+       __be16 v = cpu_to_be16(data);
+       // optimize later...
+       hfs_bnode_write(node, &v, off, 2);
+ }
+-void hfs_bnode_write_u8(struct hfs_bnode *node, int off, u8 data)
++void hfs_bnode_write_u8(struct hfs_bnode *node, u32 off, u8 data)
+ {
+       // optimize later...
+       hfs_bnode_write(node, &data, off, 1);
+ }
+-void hfs_bnode_clear(struct hfs_bnode *node, int off, int len)
++void hfs_bnode_clear(struct hfs_bnode *node, u32 off, u32 len)
+ {
+       struct page *page;
+@@ -186,7 +186,7 @@ void hfs_bnode_clear(struct hfs_bnode *n
+       if (len == 0) {
+               pr_err("requested zero length: "
+                      "NODE: id %u, type %#x, height %u, "
+-                     "node_size %u, offset %d, len %d\n",
++                     "node_size %u, offset %u, len %u\n",
+                      node->this, node->type, node->height,
+                      node->tree->node_size, off, len);
+               return;
+@@ -202,8 +202,8 @@ void hfs_bnode_clear(struct hfs_bnode *n
+       set_page_dirty(page);
+ }
+-void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst,
+-              struct hfs_bnode *src_node, int src, int len)
++void hfs_bnode_copy(struct hfs_bnode *dst_node, u32 dst,
++                  struct hfs_bnode *src_node, u32 src, u32 len)
+ {
+       struct page *src_page, *dst_page;
+@@ -225,7 +225,7 @@ void hfs_bnode_copy(struct hfs_bnode *ds
+       set_page_dirty(dst_page);
+ }
+-void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len)
++void hfs_bnode_move(struct hfs_bnode *node, u32 dst, u32 src, u32 len)
+ {
+       struct page *page;
+       void *ptr;
+--- a/fs/hfs/brec.c
++++ b/fs/hfs/brec.c
+@@ -62,7 +62,7 @@ u16 hfs_brec_keylen(struct hfs_bnode *no
+       return retval;
+ }
+-int hfs_brec_insert(struct hfs_find_data *fd, void *entry, int entry_len)
++int hfs_brec_insert(struct hfs_find_data *fd, void *entry, u32 entry_len)
+ {
+       struct hfs_btree *tree;
+       struct hfs_bnode *node, *new_node;
+--- a/fs/hfs/btree.c
++++ b/fs/hfs/btree.c
+@@ -221,7 +221,7 @@ static struct hfs_bnode *hfs_bmap_new_bm
+ }
+ /* Make sure @tree has enough space for the @rsvd_nodes */
+-int hfs_bmap_reserve(struct hfs_btree *tree, int rsvd_nodes)
++int hfs_bmap_reserve(struct hfs_btree *tree, u32 rsvd_nodes)
+ {
+       struct inode *inode = tree->inode;
+       u32 count;
+--- a/fs/hfs/btree.h
++++ b/fs/hfs/btree.h
+@@ -86,48 +86,49 @@ struct hfs_find_data {
+ /* btree.c */
+-extern struct hfs_btree *hfs_btree_open(struct super_block *, u32, btree_keycmp);
+-extern void hfs_btree_close(struct hfs_btree *);
+-extern void hfs_btree_write(struct hfs_btree *);
+-extern int hfs_bmap_reserve(struct hfs_btree *, int);
+-extern struct hfs_bnode * hfs_bmap_alloc(struct hfs_btree *);
++extern struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id,
++                                      btree_keycmp keycmp);
++extern void hfs_btree_close(struct hfs_btree *tree);
++extern void hfs_btree_write(struct hfs_btree *tree);
++extern int hfs_bmap_reserve(struct hfs_btree *tree, u32 rsvd_nodes);
++extern struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree);
+ extern void hfs_bmap_free(struct hfs_bnode *node);
+ /* bnode.c */
+-extern void hfs_bnode_read(struct hfs_bnode *, void *, int, int);
+-extern u16 hfs_bnode_read_u16(struct hfs_bnode *, int);
+-extern u8 hfs_bnode_read_u8(struct hfs_bnode *, int);
+-extern void hfs_bnode_read_key(struct hfs_bnode *, void *, int);
+-extern void hfs_bnode_write(struct hfs_bnode *, void *, int, int);
+-extern void hfs_bnode_write_u16(struct hfs_bnode *, int, u16);
+-extern void hfs_bnode_write_u8(struct hfs_bnode *, int, u8);
+-extern void hfs_bnode_clear(struct hfs_bnode *, int, int);
+-extern void hfs_bnode_copy(struct hfs_bnode *, int,
+-                         struct hfs_bnode *, int, int);
+-extern void hfs_bnode_move(struct hfs_bnode *, int, int, int);
+-extern void hfs_bnode_dump(struct hfs_bnode *);
+-extern void hfs_bnode_unlink(struct hfs_bnode *);
+-extern struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *, u32);
+-extern struct hfs_bnode *hfs_bnode_find(struct hfs_btree *, u32);
+-extern void hfs_bnode_unhash(struct hfs_bnode *);
+-extern void hfs_bnode_free(struct hfs_bnode *);
+-extern struct hfs_bnode *hfs_bnode_create(struct hfs_btree *, u32);
+-extern void hfs_bnode_get(struct hfs_bnode *);
+-extern void hfs_bnode_put(struct hfs_bnode *);
++extern void hfs_bnode_read(struct hfs_bnode *node, void *buf, u32 off, u32 len);
++extern u16 hfs_bnode_read_u16(struct hfs_bnode *node, u32 off);
++extern u8 hfs_bnode_read_u8(struct hfs_bnode *node, u32 off);
++extern void hfs_bnode_read_key(struct hfs_bnode *node, void *key, u32 off);
++extern void hfs_bnode_write(struct hfs_bnode *node, void *buf, u32 off, u32 len);
++extern void hfs_bnode_write_u16(struct hfs_bnode *node, u32 off, u16 data);
++extern void hfs_bnode_write_u8(struct hfs_bnode *node, u32 off, u8 data);
++extern void hfs_bnode_clear(struct hfs_bnode *node, u32 off, u32 len);
++extern void hfs_bnode_copy(struct hfs_bnode *dst_node, u32 dst,
++                         struct hfs_bnode *src_node, u32 src, u32 len);
++extern void hfs_bnode_move(struct hfs_bnode *node, u32 dst, u32 src, u32 len);
++extern void hfs_bnode_dump(struct hfs_bnode *node);
++extern void hfs_bnode_unlink(struct hfs_bnode *node);
++extern struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *tree, u32 cnid);
++extern struct hfs_bnode *hfs_bnode_find(struct hfs_btree *tree, u32 num);
++extern void hfs_bnode_unhash(struct hfs_bnode *node);
++extern void hfs_bnode_free(struct hfs_bnode *node);
++extern struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num);
++extern void hfs_bnode_get(struct hfs_bnode *node);
++extern void hfs_bnode_put(struct hfs_bnode *node);
+ /* brec.c */
+-extern u16 hfs_brec_lenoff(struct hfs_bnode *, u16, u16 *);
+-extern u16 hfs_brec_keylen(struct hfs_bnode *, u16);
+-extern int hfs_brec_insert(struct hfs_find_data *, void *, int);
+-extern int hfs_brec_remove(struct hfs_find_data *);
++extern u16 hfs_brec_lenoff(struct hfs_bnode *node, u16 rec, u16 *off);
++extern u16 hfs_brec_keylen(struct hfs_bnode *node, u16 rec);
++extern int hfs_brec_insert(struct hfs_find_data *fd, void *entry, u32 entry_len);
++extern int hfs_brec_remove(struct hfs_find_data *fd);
+ /* bfind.c */
+-extern int hfs_find_init(struct hfs_btree *, struct hfs_find_data *);
+-extern void hfs_find_exit(struct hfs_find_data *);
+-extern int __hfs_brec_find(struct hfs_bnode *, struct hfs_find_data *);
+-extern int hfs_brec_find(struct hfs_find_data *);
+-extern int hfs_brec_read(struct hfs_find_data *, void *, int);
+-extern int hfs_brec_goto(struct hfs_find_data *, int);
++extern int hfs_find_init(struct hfs_btree *tree, struct hfs_find_data *fd);
++extern void hfs_find_exit(struct hfs_find_data *fd);
++extern int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd);
++extern int hfs_brec_find(struct hfs_find_data *fd);
++extern int hfs_brec_read(struct hfs_find_data *fd, void *rec, u32 rec_len);
++extern int hfs_brec_goto(struct hfs_find_data *fd, int cnt);
+ struct hfs_bnode_desc {
+--- a/fs/hfs/hfs_fs.h
++++ b/fs/hfs/hfs_fs.h
+@@ -171,70 +171,85 @@ struct hfs_sb_info {
+ #define HFS_FLG_ALT_MDB_DIRTY 2
+ /* bitmap.c */
+-extern u32 hfs_vbm_search_free(struct super_block *, u32, u32 *);
+-extern int hfs_clear_vbm_bits(struct super_block *, u16, u16);
++extern u32 hfs_vbm_search_free(struct super_block *sb, u32 goal, u32 *num_bits);
++extern int hfs_clear_vbm_bits(struct super_block *sb, u16 start, u16 count);
+ /* catalog.c */
+-extern int hfs_cat_keycmp(const btree_key *, const btree_key *);
++extern int hfs_cat_keycmp(const btree_key *key1, const btree_key *key2);
+ struct hfs_find_data;
+-extern int hfs_cat_find_brec(struct super_block *, u32, struct hfs_find_data *);
+-extern int hfs_cat_create(u32, struct inode *, const struct qstr *, struct inode *);
+-extern int hfs_cat_delete(u32, struct inode *, const struct qstr *);
+-extern int hfs_cat_move(u32, struct inode *, const struct qstr *,
+-                      struct inode *, const struct qstr *);
+-extern void hfs_cat_build_key(struct super_block *, btree_key *, u32, const struct qstr *);
++extern int hfs_cat_find_brec(struct super_block *sb, u32 cnid,
++                           struct hfs_find_data *fd);
++extern int hfs_cat_create(u32 cnid, struct inode *dir,
++                        const struct qstr *str, struct inode *inode);
++extern int hfs_cat_delete(u32 cnid, struct inode *dir, const struct qstr *str);
++extern int hfs_cat_move(u32 cnid, struct inode *src_dir,
++                      const struct qstr *src_name,
++                      struct inode *dst_dir,
++                      const struct qstr *dst_name);
++extern void hfs_cat_build_key(struct super_block *sb, btree_key *key,
++                            u32 parent, const struct qstr *name);
+ /* dir.c */
+ extern const struct file_operations hfs_dir_operations;
+ extern const struct inode_operations hfs_dir_inode_operations;
+ /* extent.c */
+-extern int hfs_ext_keycmp(const btree_key *, const btree_key *);
+-extern int hfs_free_fork(struct super_block *, struct hfs_cat_file *, int);
+-extern int hfs_ext_write_extent(struct inode *);
+-extern int hfs_extend_file(struct inode *);
+-extern void hfs_file_truncate(struct inode *);
++extern int hfs_ext_keycmp(const btree_key *key1, const btree_key *key2);
++extern int hfs_free_fork(struct super_block *sb,
++                       struct hfs_cat_file *file, int type);
++extern int hfs_ext_write_extent(struct inode *inode);
++extern int hfs_extend_file(struct inode *inode);
++extern void hfs_file_truncate(struct inode *inode);
+-extern int hfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
++extern int hfs_get_block(struct inode *inode, sector_t block,
++                       struct buffer_head *bh_result, int create);
+ /* inode.c */
+ extern const struct address_space_operations hfs_aops;
+ extern const struct address_space_operations hfs_btree_aops;
+-extern struct inode *hfs_new_inode(struct inode *, const struct qstr *, umode_t);
+-extern void hfs_inode_write_fork(struct inode *, struct hfs_extent *, __be32 *, __be32 *);
+-extern int hfs_write_inode(struct inode *, struct writeback_control *);
+-extern int hfs_inode_setattr(struct dentry *, struct iattr *);
++extern struct inode *hfs_new_inode(struct inode *dir, const struct qstr *name,
++                                 umode_t mode);
++extern void hfs_inode_write_fork(struct inode *inode, struct hfs_extent *ext,
++                               __be32 *log_size, __be32 *phys_size);
++extern int hfs_write_inode(struct inode *inode, struct writeback_control *wbc);
++extern int hfs_inode_setattr(struct dentry *dentry, struct iattr *attr);
+ extern void hfs_inode_read_fork(struct inode *inode, struct hfs_extent *ext,
+-                      __be32 log_size, __be32 phys_size, u32 clump_size);
+-extern struct inode *hfs_iget(struct super_block *, struct hfs_cat_key *, hfs_cat_rec *);
+-extern void hfs_evict_inode(struct inode *);
+-extern void hfs_delete_inode(struct inode *);
++                              __be32 __log_size, __be32 phys_size,
++                              u32 clump_size);
++extern struct inode *hfs_iget(struct super_block *sb, struct hfs_cat_key *key,
++                              hfs_cat_rec *rec);
++extern void hfs_evict_inode(struct inode *inode);
++extern void hfs_delete_inode(struct inode *inode);
+ /* attr.c */
+ extern const struct xattr_handler *hfs_xattr_handlers[];
+ /* mdb.c */
+-extern int hfs_mdb_get(struct super_block *);
+-extern void hfs_mdb_commit(struct super_block *);
+-extern void hfs_mdb_close(struct super_block *);
+-extern void hfs_mdb_put(struct super_block *);
++extern int hfs_mdb_get(struct super_block *sb);
++extern void hfs_mdb_commit(struct super_block *sb);
++extern void hfs_mdb_close(struct super_block *sb);
++extern void hfs_mdb_put(struct super_block *sb);
+ /* part_tbl.c */
+-extern int hfs_part_find(struct super_block *, sector_t *, sector_t *);
++extern int hfs_part_find(struct super_block *sb,
++                       sector_t *part_start, sector_t *part_size);
+ /* string.c */
+ extern const struct dentry_operations hfs_dentry_operations;
+-extern int hfs_hash_dentry(const struct dentry *, struct qstr *);
+-extern int hfs_strcmp(const unsigned char *, unsigned int,
+-                    const unsigned char *, unsigned int);
++extern int hfs_hash_dentry(const struct dentry *dentry, struct qstr *this);
++extern int hfs_strcmp(const unsigned char *s1, unsigned int len1,
++                    const unsigned char *s2, unsigned int len2);
+ extern int hfs_compare_dentry(const struct dentry *dentry,
+-              unsigned int len, const char *str, const struct qstr *name);
++                              unsigned int len, const char *str,
++                              const struct qstr *name);
+ /* trans.c */
+-extern void hfs_asc2mac(struct super_block *, struct hfs_name *, const struct qstr *);
+-extern int hfs_mac2asc(struct super_block *, char *, const struct hfs_name *);
++extern void hfs_asc2mac(struct super_block *sb,
++                      struct hfs_name *out, const struct qstr *in);
++extern int hfs_mac2asc(struct super_block *sb,
++                      char *out, const struct hfs_name *in);
+ /* super.c */
+ extern void hfs_mark_mdb_dirty(struct super_block *sb);
+--- a/fs/hfs/inode.c
++++ b/fs/hfs/inode.c
+@@ -50,7 +50,7 @@ static void hfs_write_failed(struct addr
+ }
+ static int hfs_write_begin(struct file *file, struct address_space *mapping,
+-                      loff_t pos, unsigned len, unsigned flags,
++                      loff_t pos, unsigned int len, unsigned flags,
+                       struct page **pagep, void **fsdata)
+ {
+       int ret;
+--- a/fs/hfsplus/bfind.c
++++ b/fs/hfsplus/bfind.c
+@@ -210,7 +210,7 @@ release:
+       return res;
+ }
+-int hfs_brec_read(struct hfs_find_data *fd, void *rec, int rec_len)
++int hfs_brec_read(struct hfs_find_data *fd, void *rec, u32 rec_len)
+ {
+       int res;
+--- a/fs/hfsplus/bnode.c
++++ b/fs/hfsplus/bnode.c
+@@ -20,10 +20,10 @@
+ /* Copy a specified range of bytes from the raw data of a node */
+-void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len)
++void hfs_bnode_read(struct hfs_bnode *node, void *buf, u32 off, u32 len)
+ {
+       struct page **pagep;
+-      int l;
++      u32 l;
+       memset(buf, 0, len);
+@@ -33,7 +33,7 @@ void hfs_bnode_read(struct hfs_bnode *no
+       if (len == 0) {
+               pr_err("requested zero length: "
+                      "NODE: id %u, type %#x, height %u, "
+-                     "node_size %u, offset %d, len %d\n",
++                     "node_size %u, offset %u, len %u\n",
+                      node->this, node->type, node->height,
+                      node->tree->node_size, off, len);
+               return;
+@@ -45,19 +45,19 @@ void hfs_bnode_read(struct hfs_bnode *no
+       pagep = node->page + (off >> PAGE_SHIFT);
+       off &= ~PAGE_MASK;
+-      l = min_t(int, len, PAGE_SIZE - off);
++      l = min_t(u32, len, PAGE_SIZE - off);
+       memcpy(buf, kmap(*pagep) + off, l);
+       kunmap(*pagep);
+       while ((len -= l) != 0) {
+               buf += l;
+-              l = min_t(int, len, PAGE_SIZE);
++              l = min_t(u32, len, PAGE_SIZE);
+               memcpy(buf, kmap(*++pagep), l);
+               kunmap(*pagep);
+       }
+ }
+-u16 hfs_bnode_read_u16(struct hfs_bnode *node, int off)
++u16 hfs_bnode_read_u16(struct hfs_bnode *node, u32 off)
+ {
+       __be16 data;
+       /* TODO: optimize later... */
+@@ -65,7 +65,7 @@ u16 hfs_bnode_read_u16(struct hfs_bnode
+       return be16_to_cpu(data);
+ }
+-u8 hfs_bnode_read_u8(struct hfs_bnode *node, int off)
++u8 hfs_bnode_read_u8(struct hfs_bnode *node, u32 off)
+ {
+       u8 data;
+       /* TODO: optimize later... */
+@@ -73,10 +73,10 @@ u8 hfs_bnode_read_u8(struct hfs_bnode *n
+       return data;
+ }
+-void hfs_bnode_read_key(struct hfs_bnode *node, void *key, int off)
++void hfs_bnode_read_key(struct hfs_bnode *node, void *key, u32 off)
+ {
+       struct hfs_btree *tree;
+-      int key_len;
++      u32 key_len;
+       tree = node->tree;
+       if (node->type == HFS_NODE_LEAF ||
+@@ -88,17 +88,17 @@ void hfs_bnode_read_key(struct hfs_bnode
+       if (key_len > sizeof(hfsplus_btree_key) || key_len < 1) {
+               memset(key, 0, sizeof(hfsplus_btree_key));
+-              pr_err("hfsplus: Invalid key length: %d\n", key_len);
++              pr_err("hfsplus: Invalid key length: %u\n", key_len);
+               return;
+       }
+       hfs_bnode_read(node, key, off, key_len);
+ }
+-void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len)
++void hfs_bnode_write(struct hfs_bnode *node, void *buf, u32 off, u32 len)
+ {
+       struct page **pagep;
+-      int l;
++      u32 l;
+       if (!is_bnode_offset_valid(node, off))
+               return;
+@@ -106,7 +106,7 @@ void hfs_bnode_write(struct hfs_bnode *n
+       if (len == 0) {
+               pr_err("requested zero length: "
+                      "NODE: id %u, type %#x, height %u, "
+-                     "node_size %u, offset %d, len %d\n",
++                     "node_size %u, offset %u, len %u\n",
+                      node->this, node->type, node->height,
+                      node->tree->node_size, off, len);
+               return;
+@@ -118,31 +118,31 @@ void hfs_bnode_write(struct hfs_bnode *n
+       pagep = node->page + (off >> PAGE_SHIFT);
+       off &= ~PAGE_MASK;
+-      l = min_t(int, len, PAGE_SIZE - off);
++      l = min_t(u32, len, PAGE_SIZE - off);
+       memcpy(kmap(*pagep) + off, buf, l);
+       set_page_dirty(*pagep);
+       kunmap(*pagep);
+       while ((len -= l) != 0) {
+               buf += l;
+-              l = min_t(int, len, PAGE_SIZE);
++              l = min_t(u32, len, PAGE_SIZE);
+               memcpy(kmap(*++pagep), buf, l);
+               set_page_dirty(*pagep);
+               kunmap(*pagep);
+       }
+ }
+-void hfs_bnode_write_u16(struct hfs_bnode *node, int off, u16 data)
++void hfs_bnode_write_u16(struct hfs_bnode *node, u32 off, u16 data)
+ {
+       __be16 v = cpu_to_be16(data);
+       /* TODO: optimize later... */
+       hfs_bnode_write(node, &v, off, 2);
+ }
+-void hfs_bnode_clear(struct hfs_bnode *node, int off, int len)
++void hfs_bnode_clear(struct hfs_bnode *node, u32 off, u32 len)
+ {
+       struct page **pagep;
+-      int l;
++      u32 l;
+       if (!is_bnode_offset_valid(node, off))
+               return;
+@@ -150,7 +150,7 @@ void hfs_bnode_clear(struct hfs_bnode *n
+       if (len == 0) {
+               pr_err("requested zero length: "
+                      "NODE: id %u, type %#x, height %u, "
+-                     "node_size %u, offset %d, len %d\n",
++                     "node_size %u, offset %u, len %u\n",
+                      node->this, node->type, node->height,
+                      node->tree->node_size, off, len);
+               return;
+@@ -162,24 +162,24 @@ void hfs_bnode_clear(struct hfs_bnode *n
+       pagep = node->page + (off >> PAGE_SHIFT);
+       off &= ~PAGE_MASK;
+-      l = min_t(int, len, PAGE_SIZE - off);
++      l = min_t(u32, len, PAGE_SIZE - off);
+       memset(kmap(*pagep) + off, 0, l);
+       set_page_dirty(*pagep);
+       kunmap(*pagep);
+       while ((len -= l) != 0) {
+-              l = min_t(int, len, PAGE_SIZE);
++              l = min_t(u32, len, PAGE_SIZE);
+               memset(kmap(*++pagep), 0, l);
+               set_page_dirty(*pagep);
+               kunmap(*pagep);
+       }
+ }
+-void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst,
+-                  struct hfs_bnode *src_node, int src, int len)
++void hfs_bnode_copy(struct hfs_bnode *dst_node, u32 dst,
++                  struct hfs_bnode *src_node, u32 src, u32 len)
+ {
+       struct page **src_page, **dst_page;
+-      int l;
++      u32 l;
+       hfs_dbg(BNODE_MOD, "copybytes: %u,%u,%u\n", dst, src, len);
+       if (!len)
+@@ -196,14 +196,14 @@ void hfs_bnode_copy(struct hfs_bnode *ds
+       dst &= ~PAGE_MASK;
+       if (src == dst) {
+-              l = min_t(int, len, PAGE_SIZE - src);
++              l = min_t(u32, len, PAGE_SIZE - src);
+               memcpy(kmap(*dst_page) + src, kmap(*src_page) + src, l);
+               kunmap(*src_page);
+               set_page_dirty(*dst_page);
+               kunmap(*dst_page);
+               while ((len -= l) != 0) {
+-                      l = min_t(int, len, PAGE_SIZE);
++                      l = min_t(u32, len, PAGE_SIZE);
+                       memcpy(kmap(*++dst_page), kmap(*++src_page), l);
+                       kunmap(*src_page);
+                       set_page_dirty(*dst_page);
+@@ -237,10 +237,10 @@ void hfs_bnode_copy(struct hfs_bnode *ds
+       }
+ }
+-void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len)
++void hfs_bnode_move(struct hfs_bnode *node, u32 dst, u32 src, u32 len)
+ {
+       struct page **src_page, **dst_page;
+-      int l;
++      u32 l;
+       hfs_dbg(BNODE_MOD, "movebytes: %u,%u,%u\n", dst, src, len);
+       if (!len)
+@@ -309,7 +309,7 @@ void hfs_bnode_move(struct hfs_bnode *no
+               dst &= ~PAGE_MASK;
+               if (src == dst) {
+-                      l = min_t(int, len, PAGE_SIZE - src);
++                      l = min_t(u32, len, PAGE_SIZE - src);
+                       memmove(kmap(*dst_page) + src,
+                               kmap(*src_page) + src, l);
+                       kunmap(*src_page);
+@@ -317,7 +317,7 @@ void hfs_bnode_move(struct hfs_bnode *no
+                       kunmap(*dst_page);
+                       while ((len -= l) != 0) {
+-                              l = min_t(int, len, PAGE_SIZE);
++                              l = min_t(u32, len, PAGE_SIZE);
+                               memmove(kmap(*++dst_page),
+                                       kmap(*++src_page), l);
+                               kunmap(*src_page);
+--- a/fs/hfsplus/brec.c
++++ b/fs/hfsplus/brec.c
+@@ -60,7 +60,7 @@ u16 hfs_brec_keylen(struct hfs_bnode *no
+       return retval;
+ }
+-int hfs_brec_insert(struct hfs_find_data *fd, void *entry, int entry_len)
++int hfs_brec_insert(struct hfs_find_data *fd, void *entry, u32 entry_len)
+ {
+       struct hfs_btree *tree;
+       struct hfs_bnode *node, *new_node;
+--- a/fs/hfsplus/btree.c
++++ b/fs/hfsplus/btree.c
+@@ -343,7 +343,7 @@ static struct hfs_bnode *hfs_bmap_new_bm
+ }
+ /* Make sure @tree has enough space for the @rsvd_nodes */
+-int hfs_bmap_reserve(struct hfs_btree *tree, int rsvd_nodes)
++int hfs_bmap_reserve(struct hfs_btree *tree, u32 rsvd_nodes)
+ {
+       struct inode *inode = tree->inode;
+       struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
+--- a/fs/hfsplus/hfsplus_fs.h
++++ b/fs/hfsplus/hfsplus_fs.h
+@@ -399,21 +399,21 @@ u32 hfsplus_calc_btree_clump_size(u32 bl
+ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id);
+ void hfs_btree_close(struct hfs_btree *tree);
+ int hfs_btree_write(struct hfs_btree *tree);
+-int hfs_bmap_reserve(struct hfs_btree *tree, int rsvd_nodes);
++int hfs_bmap_reserve(struct hfs_btree *tree, u32 rsvd_nodes);
+ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree);
+ void hfs_bmap_free(struct hfs_bnode *node);
+ /* bnode.c */
+-void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len);
+-u16 hfs_bnode_read_u16(struct hfs_bnode *node, int off);
+-u8 hfs_bnode_read_u8(struct hfs_bnode *node, int off);
+-void hfs_bnode_read_key(struct hfs_bnode *node, void *key, int off);
+-void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len);
+-void hfs_bnode_write_u16(struct hfs_bnode *node, int off, u16 data);
+-void hfs_bnode_clear(struct hfs_bnode *node, int off, int len);
+-void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst,
+-                  struct hfs_bnode *src_node, int src, int len);
+-void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len);
++void hfs_bnode_read(struct hfs_bnode *node, void *buf, u32 off, u32 len);
++u16 hfs_bnode_read_u16(struct hfs_bnode *node, u32 off);
++u8 hfs_bnode_read_u8(struct hfs_bnode *node, u32 off);
++void hfs_bnode_read_key(struct hfs_bnode *node, void *key, u32 off);
++void hfs_bnode_write(struct hfs_bnode *node, void *buf, u32 off, u32 len);
++void hfs_bnode_write_u16(struct hfs_bnode *node, u32 off, u16 data);
++void hfs_bnode_clear(struct hfs_bnode *node, u32 off, u32 len);
++void hfs_bnode_copy(struct hfs_bnode *dst_node, u32 dst,
++                  struct hfs_bnode *src_node, u32 src, u32 len);
++void hfs_bnode_move(struct hfs_bnode *node, u32 dst, u32 src, u32 len);
+ void hfs_bnode_dump(struct hfs_bnode *node);
+ void hfs_bnode_unlink(struct hfs_bnode *node);
+ struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *tree, u32 cnid);
+@@ -428,7 +428,7 @@ bool hfs_bnode_need_zeroout(struct hfs_b
+ /* brec.c */
+ u16 hfs_brec_lenoff(struct hfs_bnode *node, u16 rec, u16 *off);
+ u16 hfs_brec_keylen(struct hfs_bnode *node, u16 rec);
+-int hfs_brec_insert(struct hfs_find_data *fd, void *entry, int entry_len);
++int hfs_brec_insert(struct hfs_find_data *fd, void *entry, u32 entry_len);
+ int hfs_brec_remove(struct hfs_find_data *fd);
+ /* bfind.c */
+@@ -441,7 +441,7 @@ int hfs_find_rec_by_key(struct hfs_bnode
+ int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd,
+                   search_strategy_t rec_found);
+ int hfs_brec_find(struct hfs_find_data *fd, search_strategy_t do_key_compare);
+-int hfs_brec_read(struct hfs_find_data *fd, void *rec, int rec_len);
++int hfs_brec_read(struct hfs_find_data *fd, void *rec, u32 rec_len);
+ int hfs_brec_goto(struct hfs_find_data *fd, int cnt);
+ /* catalog.c */
+@@ -589,14 +589,14 @@ hfsplus_btree_lock_class(struct hfs_btre
+ }
+ static inline
+-bool is_bnode_offset_valid(struct hfs_bnode *node, int off)
++bool is_bnode_offset_valid(struct hfs_bnode *node, u32 off)
+ {
+       bool is_valid = off < node->tree->node_size;
+       if (!is_valid) {
+               pr_err("requested invalid offset: "
+                      "NODE: id %u, type %#x, height %u, "
+-                     "node_size %u, offset %d\n",
++                     "node_size %u, offset %u\n",
+                      node->this, node->type, node->height,
+                      node->tree->node_size, off);
+       }
+@@ -605,7 +605,7 @@ bool is_bnode_offset_valid(struct hfs_bn
+ }
+ static inline
+-int check_and_correct_requested_length(struct hfs_bnode *node, int off, int len)
++u32 check_and_correct_requested_length(struct hfs_bnode *node, u32 off, u32 len)
+ {
+       unsigned int node_size;
+@@ -615,12 +615,12 @@ int check_and_correct_requested_length(s
+       node_size = node->tree->node_size;
+       if ((off + len) > node_size) {
+-              int new_len = (int)node_size - off;
++              u32 new_len = node_size - off;
+               pr_err("requested length has been corrected: "
+                      "NODE: id %u, type %#x, height %u, "
+-                     "node_size %u, offset %d, "
+-                     "requested_len %d, corrected_len %d\n",
++                     "node_size %u, offset %u, "
++                     "requested_len %u, corrected_len %u\n",
+                      node->this, node->type, node->height,
+                      node->tree->node_size, off, len, new_len);
diff --git a/queue-5.10/hid-add-haptics-page-defines.patch b/queue-5.10/hid-add-haptics-page-defines.patch
new file mode 100644 (file)
index 0000000..eb51e32
--- /dev/null
@@ -0,0 +1,78 @@
+From stable+bounces-277172-greg=kroah.com@vger.kernel.org Fri Jul 17 20:11:41 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2026 14:11:32 -0400
+Subject: HID: add haptics page defines
+To: stable@vger.kernel.org
+Cc: Angela Czubak <aczubak@google.com>, Jonathan Denose <jdenose@google.com>, Benjamin Tissoires <bentiss@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260717181133.2086215-1-sashal@kernel.org>
+
+From: Angela Czubak <aczubak@google.com>
+
+[ Upstream commit 5e0ae59159e3a07391a35865bb79ff335473fa79 ]
+
+Introduce haptic usages as defined in HID Usage Tables specification.
+Add HID units for newton and gram.
+
+Signed-off-by: Angela Czubak <aczubak@google.com>
+Co-developed-by: Jonathan Denose <jdenose@google.com>
+Signed-off-by: Jonathan Denose <jdenose@google.com>
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Stable-dep-of: 8813b0612275 ("HID: multitouch: fix out-of-bounds bit access on mt_io_flags")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/hid.h |   29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+--- a/include/linux/hid.h
++++ b/include/linux/hid.h
+@@ -152,6 +152,7 @@ struct hid_item {
+ #define HID_UP_TELEPHONY      0x000b0000
+ #define HID_UP_CONSUMER               0x000c0000
+ #define HID_UP_DIGITIZER      0x000d0000
++#define HID_UP_HAPTIC         0x000e0000
+ #define HID_UP_PID            0x000f0000
+ #define HID_UP_HPVENDOR         0xff7f0000
+ #define HID_UP_HPVENDOR2        0xff010000
+@@ -299,6 +300,28 @@ struct hid_item {
+ #define HID_DG_TOOLSERIALNUMBER       0x000d005b
+ #define HID_DG_LATENCYMODE    0x000d0060
++#define HID_HP_SIMPLECONTROLLER       0x000e0001
++#define HID_HP_WAVEFORMLIST   0x000e0010
++#define HID_HP_DURATIONLIST   0x000e0011
++#define HID_HP_AUTOTRIGGER    0x000e0020
++#define HID_HP_MANUALTRIGGER  0x000e0021
++#define HID_HP_AUTOTRIGGERASSOCIATEDCONTROL 0x000e0022
++#define HID_HP_INTENSITY      0x000e0023
++#define HID_HP_REPEATCOUNT    0x000e0024
++#define HID_HP_RETRIGGERPERIOD        0x000e0025
++#define HID_HP_WAVEFORMVENDORPAGE     0x000e0026
++#define HID_HP_WAVEFORMVENDORID       0x000e0027
++#define HID_HP_WAVEFORMCUTOFFTIME     0x000e0028
++#define HID_HP_WAVEFORMNONE   0x000e1001
++#define HID_HP_WAVEFORMSTOP   0x000e1002
++#define HID_HP_WAVEFORMCLICK  0x000e1003
++#define HID_HP_WAVEFORMBUZZCONTINUOUS 0x000e1004
++#define HID_HP_WAVEFORMRUMBLECONTINUOUS       0x000e1005
++#define HID_HP_WAVEFORMPRESS  0x000e1006
++#define HID_HP_WAVEFORMRELEASE        0x000e1007
++#define HID_HP_VENDORWAVEFORMMIN      0x000e2001
++#define HID_HP_VENDORWAVEFORMMAX      0x000e2fff
++
+ #define HID_VD_ASUS_CUSTOM_MEDIA_KEYS 0xff310076
+ /*
+  * HID report types --- Ouch! HID spec says 1 2 3!
+@@ -385,6 +408,12 @@ struct hid_item {
+ #define HID_BOOT_PROTOCOL     0
+ /*
++ * HID units
++ */
++#define HID_UNIT_GRAM         0x0101
++#define HID_UNIT_NEWTON               0xe111
++
++/*
+  * This is the global environment of the parser. This information is
+  * persistent for main-items. The global environment can be saved and
+  * restored with PUSH/POP statements.
diff --git a/queue-5.10/hid-appleir-fix-uaf-on-pending-key_up_timer-in-remove.patch b/queue-5.10/hid-appleir-fix-uaf-on-pending-key_up_timer-in-remove.patch
new file mode 100644 (file)
index 0000000..5da5441
--- /dev/null
@@ -0,0 +1,150 @@
+From stable+bounces-277229-greg=kroah.com@vger.kernel.org Sat Jul 18 02:51:46 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2026 20:51:23 -0400
+Subject: HID: appleir: fix UAF on pending key_up_timer in remove()
+To: stable@vger.kernel.org
+Cc: Manish Khadka <maskmemanish@gmail.com>, Jiri Kosina <jkosina@suse.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260718005123.2484926-1-sashal@kernel.org>
+
+From: Manish Khadka <maskmemanish@gmail.com>
+
+[ Upstream commit 75fe87e19d8aff81eb2c64d15d244ab8da4de945 ]
+
+appleir_remove() runs hid_hw_stop() before timer_delete_sync().
+hid_hw_stop() synchronously unregisters the HID input device via
+hid_disconnect() -> hidinput_disconnect() -> input_unregister_device(),
+which drops the last reference and frees the underlying input_dev when
+no userspace handle holds it open.
+
+key_up_tick() reads appleir->input_dev and calls input_report_key() /
+input_sync() on it.  The timer is armed from appleir_raw_event() with
+a HZ/8 (~125 ms) timeout on every keydown and key-repeat report.  If a
+key was pressed shortly before the device is disconnected, the timer
+can fire after hid_hw_stop() has freed input_dev but before the
+teardown drains it.
+
+A simple reorder is not sufficient.  Putting the timer drain first
+still leaves a window where a USB URB completion (raw_event) running
+during hid_hw_stop() can call mod_timer() and re-arm the timer, which
+then fires after hidinput_disconnect() has freed input_dev.  The same
+URB-completion window also lets raw_event() reach key_up(), key_down()
+and battery_flat() directly, all of which dereference
+appleir->input_dev.
+
+Introduce a 'removing' flag on struct appleir, gated by the existing
+spinlock.  appleir_remove() sets the flag under the lock and then
+shuts down the timer with timer_shutdown_sync(), which both drains any
+in-flight callback and permanently disables further mod_timer() calls.
+appleir_raw_event() and key_up_tick() bail out early if the flag is
+set, so no path can arm or run the timer, or dereference
+appleir->input_dev, after remove() has started tearing down.
+
+The keyrepeat and flatbattery branches of appleir_raw_event()
+previously called into the input layer without holding the spinlock;
+take it now so the flag check is well-defined.  This incidentally
+closes a pre-existing read-side race on appleir->current_key in the
+keyrepeat branch.
+
+This bug is structurally a sibling of commit 4db2af929279 ("HID:
+appletb-kbd: fix UAF in inactivity-timer cleanup path") and has been
+present since the driver was introduced.
+
+Fixes: 9a4a5574ce42 ("HID: appleir: add support for Apple ir devices")
+Cc: stable@vger.kernel.org
+Signed-off-by: Manish Khadka <maskmemanish@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hid/hid-appleir.c |   45 +++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 35 insertions(+), 10 deletions(-)
+
+--- a/drivers/hid/hid-appleir.c
++++ b/drivers/hid/hid-appleir.c
+@@ -109,9 +109,10 @@ struct appleir {
+       struct hid_device *hid;
+       unsigned short keymap[ARRAY_SIZE(appleir_key_table)];
+       struct timer_list key_up_timer; /* timer for key up */
+-      spinlock_t lock;                /* protects .current_key */
++      spinlock_t lock;                /* protects .current_key, .removing */
+       int current_key;                /* the currently pressed key */
+       int prev_key_idx;               /* key index in a 2 packets message */
++      bool removing;                  /* set during teardown; gates input_dev access */
+ };
+ static int get_key(int data)
+@@ -172,7 +173,7 @@ static void key_up_tick(struct timer_lis
+       unsigned long flags;
+       spin_lock_irqsave(&appleir->lock, flags);
+-      if (appleir->current_key) {
++      if (!appleir->removing && appleir->current_key) {
+               key_up(hid, appleir, appleir->current_key);
+               appleir->current_key = 0;
+       }
+@@ -195,6 +196,10 @@ static int appleir_raw_event(struct hid_
+               int index;
+               spin_lock_irqsave(&appleir->lock, flags);
++              if (appleir->removing) {
++                      spin_unlock_irqrestore(&appleir->lock, flags);
++                      goto out;
++              }
+               /*
+                * If we already have a key down, take it up before marking
+                * this one down
+@@ -229,17 +234,25 @@ static int appleir_raw_event(struct hid_
+       appleir->prev_key_idx = 0;
+       if (!memcmp(data, keyrepeat, sizeof(keyrepeat))) {
+-              key_down(hid, appleir, appleir->current_key);
+-              /*
+-               * Remote doesn't do key up, either pull them up, in the test
+-               * above, or here set a timer which pulls them up after 1/8 s
+-               */
+-              mod_timer(&appleir->key_up_timer, jiffies + HZ / 8);
++              spin_lock_irqsave(&appleir->lock, flags);
++              if (!appleir->removing) {
++                      key_down(hid, appleir, appleir->current_key);
++                      /*
++                       * Remote doesn't do key up, either pull them up, in
++                       * the test above, or here set a timer which pulls them
++                       * up after 1/8 s
++                       */
++                      mod_timer(&appleir->key_up_timer, jiffies + HZ / 8);
++              }
++              spin_unlock_irqrestore(&appleir->lock, flags);
+               goto out;
+       }
+       if (!memcmp(data, flatbattery, sizeof(flatbattery))) {
+-              battery_flat(appleir);
++              spin_lock_irqsave(&appleir->lock, flags);
++              if (!appleir->removing)
++                      battery_flat(appleir);
++              spin_unlock_irqrestore(&appleir->lock, flags);
+               /* Fall through */
+       }
+@@ -318,8 +331,20 @@ fail:
+ static void appleir_remove(struct hid_device *hid)
+ {
+       struct appleir *appleir = hid_get_drvdata(hid);
++      unsigned long flags;
++
++      /*
++       * Mark the driver as tearing down so that any concurrent raw_event
++       * (e.g. from a USB URB completion that hid_hw_stop() has not yet
++       * killed) and the key_up_timer softirq stop touching input_dev
++       * before hid_hw_stop() frees it via hidinput_disconnect().
++       */
++      spin_lock_irqsave(&appleir->lock, flags);
++      appleir->removing = true;
++      spin_unlock_irqrestore(&appleir->lock, flags);
++
++      timer_delete_sync(&appleir->key_up_timer);
+       hid_hw_stop(hid);
+-      del_timer_sync(&appleir->key_up_timer);
+ }
+ static const struct hid_device_id appleir_devices[] = {
diff --git a/queue-5.10/hid-multitouch-fix-out-of-bounds-bit-access-on-mt_io_flags.patch b/queue-5.10/hid-multitouch-fix-out-of-bounds-bit-access-on-mt_io_flags.patch
new file mode 100644 (file)
index 0000000..a6b4e58
--- /dev/null
@@ -0,0 +1,158 @@
+From stable+bounces-277173-greg=kroah.com@vger.kernel.org Fri Jul 17 20:19:42 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2026 14:11:33 -0400
+Subject: HID: multitouch: fix out-of-bounds bit access on mt_io_flags
+To: stable@vger.kernel.org
+Cc: Trung Nguyen <trungnh@cystack.net>, Benjamin Tissoires <bentiss@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260717181133.2086215-2-sashal@kernel.org>
+
+From: Trung Nguyen <trungnh@cystack.net>
+
+[ Upstream commit 8813b0612275cc61fe9e6603d0ee019247ade6be ]
+
+mt_io_flags is a single unsigned long, but mt_process_slot(),
+mt_release_pending_palms() and mt_release_contacts() use it as a
+per-slot bitmap indexed by the slot number. That slot number is only
+bounded by td->maxcontacts, which is taken from the device's
+ContactCountMaximum feature report and can be up to 255, not by
+BITS_PER_LONG.
+
+As a result, a multitouch device that advertises a large contact count
+makes set_bit()/clear_bit() operate past the mt_io_flags word and
+corrupt the adjacent members of struct mt_device. The sticky-fingers
+release timer is the easiest way to reach this. mt_release_contacts()
+runs
+
+       for (i = 0; i < mt->num_slots; i++)
+               clear_bit(i, &td->mt_io_flags);
+
+with num_slots == maxcontacts. For maxcontacts around 250 the loop
+clears the bits that overlap td->applications.next, zeroing that list
+head, and the list_for_each_entry() that immediately follows then
+dereferences NULL. The kernel panics from timer (softirq) context. On a
+KASAN build this shows up as a general protection fault in
+mt_release_contacts() with a null-ptr-deref at offset 0x58, which is
+offsetof(struct mt_application, num_received).
+
+The state is reachable from an untrusted USB or Bluetooth HID
+multitouch device; no local privileges are required.
+
+Store the per-slot active state in a separately allocated bitmap sized
+for maxcontacts, the same pattern already used for pending_palm_slots,
+and keep only MT_IO_FLAGS_RUNNING in mt_io_flags. The two
+"mt_io_flags & MT_IO_SLOTS_MASK" arming checks become
+bitmap_empty(td->active_slots, td->maxcontacts).
+
+Move MT_IO_FLAGS_RUNNING back to bit 0. It was bumped to bit 32 by the
+same commit to leave the low byte for the slot bits; with the slot bits
+gone it fits in bit 0 again, which also keeps it within the unsigned
+long on 32-bit.
+
+Fixes: 46f781e0d151 ("HID: multitouch: fix sticky fingers")
+Cc: stable@vger.kernel.org
+Signed-off-by: Trung Nguyen <trungnh@cystack.net>
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hid/hid-multitouch.c |   32 ++++++++++++++++++++------------
+ 1 file changed, 20 insertions(+), 12 deletions(-)
+
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -31,6 +31,7 @@
+  * [1] https://gitlab.freedesktop.org/libevdev/hid-tools
+  */
++#include <linux/bitmap.h>
+ #include <linux/device.h>
+ #include <linux/hid.h>
+ #include <linux/module.h>
+@@ -81,8 +82,7 @@ enum latency_mode {
+       HID_LATENCY_HIGH = 1,
+ };
+-#define MT_IO_SLOTS_MASK              GENMASK(7, 0) /* reserve first 8 bits for slot tracking */
+-#define MT_IO_FLAGS_RUNNING           32
++#define MT_IO_FLAGS_RUNNING           0
+ static const bool mtrue = true;               /* default for true */
+ static const bool mfalse;             /* default for false */
+@@ -158,10 +158,9 @@ struct mt_device {
+       struct mt_class mtclass;        /* our mt device class */
+       struct timer_list release_timer;        /* to release sticky fingers */
+       struct hid_device *hdev;        /* hid_device we're attached to */
+-      unsigned long mt_io_flags;      /* mt flags (MT_IO_FLAGS_RUNNING)
+-                                       * first 8 bits are reserved for keeping the slot
+-                                       * states, this is fine because we only support up
+-                                       * to 250 slots (MT_MAX_MAXCONTACT)
++      unsigned long mt_io_flags;      /* mt flags (MT_IO_FLAGS_RUNNING) */
++      unsigned long *active_slots;    /* bitmap of slots with an active
++                                       * contact, sized for maxcontacts
+                                        */
+       __u8 inputmode_value;   /* InputMode HID feature value */
+       __u8 maxcontacts;
+@@ -915,7 +914,7 @@ static void mt_release_pending_palms(str
+       for_each_set_bit(slotnum, app->pending_palm_slots, td->maxcontacts) {
+               clear_bit(slotnum, app->pending_palm_slots);
+-              clear_bit(slotnum, &td->mt_io_flags);
++              clear_bit(slotnum, td->active_slots);
+               input_mt_slot(input, slotnum);
+               input_mt_report_slot_inactive(input);
+@@ -1100,9 +1099,9 @@ static int mt_process_slot(struct mt_dev
+               input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
+               input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
+-              set_bit(slotnum, &td->mt_io_flags);
++              set_bit(slotnum, td->active_slots);
+       } else {
+-              clear_bit(slotnum, &td->mt_io_flags);
++              clear_bit(slotnum, td->active_slots);
+       }
+       return 0;
+@@ -1237,7 +1236,7 @@ static void mt_touch_report(struct hid_d
+        * defect.
+        */
+       if (app->quirks & MT_QUIRK_STICKY_FINGERS) {
+-              if (td->mt_io_flags & MT_IO_SLOTS_MASK)
++              if (!bitmap_empty(td->active_slots, td->maxcontacts))
+                       mod_timer(&td->release_timer,
+                                 jiffies + msecs_to_jiffies(100));
+               else
+@@ -1277,6 +1276,15 @@ static int mt_touch_input_configured(str
+       if (td->is_buttonpad)
+               __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
++      if (!td->active_slots) {
++              td->active_slots = devm_kcalloc(&td->hdev->dev,
++                                              BITS_TO_LONGS(td->maxcontacts),
++                                              sizeof(long),
++                                              GFP_KERNEL);
++              if (!td->active_slots)
++                      return -ENOMEM;
++      }
++
+       app->pending_palm_slots = devm_kcalloc(&hi->input->dev,
+                                              BITS_TO_LONGS(td->maxcontacts),
+                                              sizeof(long),
+@@ -1655,7 +1663,7 @@ static void mt_release_contacts(struct h
+                       for (i = 0; i < mt->num_slots; i++) {
+                               input_mt_slot(input_dev, i);
+                               input_mt_report_slot_inactive(input_dev);
+-                              clear_bit(i, &td->mt_io_flags);
++                              clear_bit(i, td->active_slots);
+                       }
+                       input_mt_sync_frame(input_dev);
+                       input_sync(input_dev);
+@@ -1678,7 +1686,7 @@ static void mt_expired_timeout(struct ti
+        */
+       if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
+               return;
+-      if (td->mt_io_flags & MT_IO_SLOTS_MASK)
++      if (!bitmap_empty(td->active_slots, td->maxcontacts))
+               mt_release_contacts(hdev);
+       clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
+ }
diff --git a/queue-5.10/iio-common-st_sensors-honour-channel-endianness-in-read_axis_data.patch b/queue-5.10/iio-common-st_sensors-honour-channel-endianness-in-read_axis_data.patch
new file mode 100644 (file)
index 0000000..f53aa66
--- /dev/null
@@ -0,0 +1,109 @@
+From stable+bounces-274099-greg=kroah.com@vger.kernel.org Tue Jul 14 05:05:01 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:48 -0400
+Subject: iio: common: st_sensors: honour channel endianness in read_axis_data
+To: stable@vger.kernel.org
+Cc: Herman van Hazendonk <github.com@herrie.org>, Andy Shevchenko <andriy.shevchenko@intel.com>, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030448.2382602-2-sashal@kernel.org>
+
+From: Herman van Hazendonk <github.com@herrie.org>
+
+[ Upstream commit 55052184ac9011db2ea983e54d6c21f0b1079a12 ]
+
+st_sensors_read_axis_data() unconditionally decoded multi-byte
+results with get_unaligned_le16() / get_unaligned_le24() regardless
+of the channel's declared scan_type.endianness.
+
+For every ST sensor that has used this helper since it was introduced
+this happened to be fine because the ST IMU/accel/gyro/pressure
+families publish their data registers as little-endian and the
+channel specs in those drivers declare IIO_LE accordingly.
+
+The LSM303DLH magnetometer however publishes its X/Y/Z output as a
+pair of big-endian bytes (the H register sits at the lower address,
+0x03/0x05/0x07, and the L register immediately after), and its
+channel specs in st_magn_core.c correctly declare IIO_BE -- but
+read_axis_data() ignored that and decoded as little-endian, swapping
+the high and low bytes of every magnetometer sample. The LSM303DLHC
+and LSM303DLM share the same st_magn_16bit_channels (IIO_BE) and
+were therefore byte-swapped by the same bug; users of those parts
+will see different in_magn_*_raw values after this fix lands.
+
+The bug is most visible on a stationary chip: in earth's field the
+true X reading is small and the high byte sits at 0x00, so swapping
+the bytes pins sysfs X at exactly the low byte's pattern (e.g. 0x00F0
+= 240). Y and Z still appear "to vary" because their magnitudes are
+larger and the noise in the low byte produces big swings in the
+swapped high byte:
+
+  before (LSM303DLH flat, sysfs in_magn_*_raw):
+      X=240 (stuck), Y= 12032..23296, Z=-16128..-9728
+
+  after (direct i2c-dev big-endian decode, same chip same orientation):
+      X≈-4096, Y≈210, Z≈80     (sensible values reflecting earth's
+                                ambient field at low gauss range)
+
+Fix read_axis_data() to dispatch on ch->scan_type.endianness and
+call get_unaligned_be16() / get_unaligned_be24() when the channel
+declares IIO_BE. Existing IIO_LE consumers (st_accel, st_gyro,
+st_pressure, st_lsm6dsx and others) are unaffected because their
+channel specs already declare IIO_LE and the LE path is unchanged.
+
+While restructuring the branches, replace the previously implicit
+silent-success-with-uninitialised-*data fall-through for
+byte_for_channel outside 1..3 with an explicit return -EINVAL. No
+in-tree ST sensor publishes such a channel, but the new behaviour
+is strictly safer than handing userspace garbage.
+
+Fixes: 23491b513bcd ("iio:common: Add STMicroelectronics common library")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4-7 sparse smatch clang-analyzer coccinelle checkpatch
+Assisted-by: Sashiko:claude-opus-4-7
+Signed-off-by: Herman van Hazendonk <github.com@herrie.org>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/common/st_sensors/st_sensors_core.c |   23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+--- a/drivers/iio/common/st_sensors/st_sensors_core.c
++++ b/drivers/iio/common/st_sensors/st_sensors_core.c
+@@ -527,6 +527,7 @@ static int st_sensors_read_axis_data(str
+       u8 *outdata;
+       struct st_sensor_data *sdata = iio_priv(indio_dev);
+       unsigned int byte_for_channel;
++      u32 tmp;
+       byte_for_channel = DIV_ROUND_UP(ch->scan_type.realbits +
+                                       ch->scan_type.shift, 8);
+@@ -539,12 +540,22 @@ static int st_sensors_read_axis_data(str
+       if (err < 0)
+               goto st_sensors_free_memory;
+-      if (byte_for_channel == 1)
+-              *data = (s8)*outdata;
+-      else if (byte_for_channel == 2)
+-              *data = (s16)get_unaligned_le16(outdata);
+-      else if (byte_for_channel == 3)
+-              *data = (s32)sign_extend32(get_unaligned_le24(outdata), 23);
++      if (byte_for_channel == 1) {
++              tmp = *outdata;
++      } else if (byte_for_channel == 2) {
++              if (ch->scan_type.endianness == IIO_BE)
++                      tmp = get_unaligned_be16(outdata);
++              else
++                      tmp = get_unaligned_le16(outdata);
++      } else if (byte_for_channel == 3) {
++              if (ch->scan_type.endianness == IIO_BE)
++                      tmp = get_unaligned_be24(outdata);
++              else
++                      tmp = get_unaligned_le24(outdata);
++      } else {
++              return -EINVAL;
++      }
++      *data = sign_extend32(tmp, BYTES_TO_BITS(byte_for_channel) - 1);
+ st_sensors_free_memory:
+       kfree(outdata);
diff --git a/queue-5.10/iio-hid-sensor-rotation-fix-stale-or-zero-output-when-reading-raw-values.patch b/queue-5.10/iio-hid-sensor-rotation-fix-stale-or-zero-output-when-reading-raw-values.patch
new file mode 100644 (file)
index 0000000..faa401e
--- /dev/null
@@ -0,0 +1,89 @@
+From stable+bounces-273973-greg=kroah.com@vger.kernel.org Mon Jul 13 21:33:45 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 15:33:36 -0400
+Subject: iio: hid-sensor-rotation: Fix stale or zero output when reading raw values
+To: stable@vger.kernel.org
+Cc: Zhang Lixu <lixu.zhang@intel.com>, Andy Shevchenko <andriy.shevchenko@intel.com>, Stable@vger.kernel.org, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260713193336.2037451-2-sashal@kernel.org>
+
+From: Zhang Lixu <lixu.zhang@intel.com>
+
+[ Upstream commit 3ce8d099e0afc5a7da75a2007a67f67c4f5a4af1 ]
+
+When reading the raw quaternion attribute (in_rot_quaternion_raw), the
+driver currently returns either all zeros (if the sensor was never enabled)
+or stale data (if the sensor was previously enabled) because it reads from
+the internal buffer without explicitly requesting a new sample from the
+sensor.
+
+To fix this, power up the sensor, call sensor_hub_input_attr_read_values()
+to issue a synchronous GET_REPORT and receive the full quaternion data
+directly into a local buffer, then decode the four components.
+
+Fixes: fc18dddc0625 ("iio: hid-sensors: Added device rotation support")
+Signed-off-by: Zhang Lixu <lixu.zhang@intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/orientation/hid-sensor-rotation.c |   40 ++++++++++++++++++++++++--
+ 1 file changed, 38 insertions(+), 2 deletions(-)
+
+--- a/drivers/iio/orientation/hid-sensor-rotation.c
++++ b/drivers/iio/orientation/hid-sensor-rotation.c
+@@ -60,6 +60,13 @@ static int dev_rot_read_raw(struct iio_d
+                               long mask)
+ {
+       struct dev_rot_state *rot_state = iio_priv(indio_dev);
++      struct hid_sensor_hub_device *hsdev = rot_state->common_attributes.hsdev;
++      struct hid_sensor_hub_attribute_info *info = &rot_state->quaternion;
++      u32 usage_id = HID_USAGE_SENSOR_ORIENT_QUATERNION;
++      union {
++              s16 val16[4];
++              s32 val32[4];
++      } raw_buf;
+       int ret_type;
+       int i;
+@@ -69,8 +76,37 @@ static int dev_rot_read_raw(struct iio_d
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               if (size >= 4) {
+-                      for (i = 0; i < 4; ++i)
+-                              vals[i] = rot_state->sampled_vals[i];
++                      if (info->size <= 0 || info->size > sizeof(raw_buf))
++                              return -EINVAL;
++
++                      hid_sensor_power_state(&rot_state->common_attributes, true);
++
++                      ret_type = sensor_hub_input_attr_read_values(hsdev,
++                                                                   hsdev->usage,
++                                                                   usage_id,
++                                                                   info->report_id,
++                                                                   SENSOR_HUB_SYNC,
++                                                                   info->size,
++                                                                   (u8 *)&raw_buf);
++
++                      hid_sensor_power_state(&rot_state->common_attributes, false);
++
++                      if (ret_type < 0)
++                              return ret_type;
++
++                      switch (info->size) {
++                      case sizeof(raw_buf.val16):
++                              for (i = 0; i < ARRAY_SIZE(raw_buf.val16); i++)
++                                      vals[i] = raw_buf.val16[i];
++                              break;
++                      case sizeof(raw_buf.val32):
++                              for (i = 0; i < ARRAY_SIZE(raw_buf.val32); i++)
++                                      vals[i] = raw_buf.val32[i];
++                              break;
++                      default:
++                              return -EINVAL;
++                      }
++
+                       ret_type = IIO_VAL_INT_MULTIPLE;
+                       *val_len =  4;
+               } else
diff --git a/queue-5.10/iio-imu-adis-add-irqf_no_thread-to-non-fifo-trigger-irq.patch b/queue-5.10/iio-imu-adis-add-irqf_no_thread-to-non-fifo-trigger-irq.patch
new file mode 100644 (file)
index 0000000..ff71cc3
--- /dev/null
@@ -0,0 +1,49 @@
+From stable+bounces-273955-greg=kroah.com@vger.kernel.org Mon Jul 13 20:33:39 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 14:33:32 -0400
+Subject: iio: imu: adis: add IRQF_NO_THREAD to non-FIFO trigger IRQ
+To: stable@vger.kernel.org
+Cc: Runyu Xiao <runyu.xiao@seu.edu.cn>, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260713183332.1950471-1-sashal@kernel.org>
+
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+
+[ Upstream commit 6e1b9bff1202da55c464e36bd34a2b6863d7fe30 ]
+
+devm_adis_probe_trigger() registers iio_trigger_generic_data_rdy_poll()
+through devm_request_irq() on the non-FIFO path, but it does not add
+IRQF_NO_THREAD to the IRQ flags.
+
+When the kernel is booted with forced IRQ threading, the parent IRQ can
+otherwise be threaded by the IRQ core and the subsequent IIO trigger
+child IRQ is then dispatched from irq/... thread context instead of
+hardirq context. Because iio_trigger_generic_data_rdy_poll()
+immediately drives iio_trigger_poll(), this violates the hardirq-only
+IIO trigger helper contract and can push downstream trigger consumers
+through the wrong execution context.
+
+Add IRQF_NO_THREAD on top of the existing adis->irq_flag value for the
+non-FIFO request_irq() path, while preserving the current trigger
+polarity and IRQF_NO_AUTOEN behavior.
+
+Fixes: fec86c6b8369 ("iio: imu: adis: Add Managed device functions")
+Cc: stable@vger.kernel.org
+Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/imu/adis_trigger.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/imu/adis_trigger.c
++++ b/drivers/iio/imu/adis_trigger.c
+@@ -84,7 +84,7 @@ int devm_adis_probe_trigger(struct adis
+       ret = devm_request_irq(&adis->spi->dev, adis->spi->irq,
+                              &iio_trigger_generic_data_rdy_poll,
+-                             adis->irq_flag,
++                             adis->irq_flag | IRQF_NO_THREAD,
+                              indio_dev->name,
+                              adis->trig);
+       if (ret)
diff --git a/queue-5.10/iio-imu-inv_icm42600-fix-timestamping-by-limiting-fifo-reading.patch b/queue-5.10/iio-imu-inv_icm42600-fix-timestamping-by-limiting-fifo-reading.patch
new file mode 100644 (file)
index 0000000..2863c76
--- /dev/null
@@ -0,0 +1,72 @@
+From stable+bounces-274096-greg=kroah.com@vger.kernel.org Tue Jul 14 05:04:57 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:44 -0400
+Subject: iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading
+To: stable@vger.kernel.org
+Cc: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030444.2382550-8-sashal@kernel.org>
+
+From: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+
+[ Upstream commit affe3f077d7a4eeb25937f5323ff059a54b4712c ]
+
+Timestamps are made by measuring the chip clock using the watermark
+interrupts. If we read more than watermark samples as done today, we
+are reducing the period between interrupts and distort the time
+measurement. Fix that by reading only watermark samples in the
+interrupt case.
+
+Fixes: 7f85e42a6c54 ("iio: imu: inv_icm42600: add buffer support in iio devices")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c |    9 +++++----
+ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h |    1 +
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
+@@ -257,6 +257,7 @@ int inv_icm42600_buffer_update_watermark
+       /* compute watermark value in bytes */
+       wm_size = watermark * packet_size;
++      st->fifo.watermark.value = watermark;
+       /* changing FIFO watermark requires to turn off watermark interrupt */
+       ret = regmap_update_bits_check(st->map, INV_ICM42600_REG_INT_SOURCE0,
+@@ -476,11 +477,10 @@ int inv_icm42600_buffer_fifo_read(struct
+       st->fifo.nb.accel = 0;
+       st->fifo.nb.total = 0;
+-      /* compute maximum FIFO read size */
++      /* compute maximum FIFO read size (watermark for max = 0 interrupt case) */
+       if (max == 0)
+-              max_count = sizeof(st->fifo.data);
+-      else
+-              max_count = max * inv_icm42600_get_packet_size(st->fifo.en);
++              max = st->fifo.watermark.value;
++      max_count = max * inv_icm42600_get_packet_size(st->fifo.en);
+       /* read FIFO count value */
+       raw_fifo_count = (__be16 *)st->buffer;
+@@ -592,6 +592,7 @@ int inv_icm42600_buffer_init(struct inv_
+       st->fifo.watermark.eff_gyro = 1;
+       st->fifo.watermark.eff_accel = 1;
++      st->fifo.watermark.value = 1;
+       /*
+        * Default FIFO configuration (bits 7 to 5)
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h
+@@ -34,6 +34,7 @@ struct inv_icm42600_fifo {
+               unsigned int accel;
+               unsigned int eff_gyro;
+               unsigned int eff_accel;
++              unsigned int value;
+       } watermark;
+       size_t count;
+       struct {
diff --git a/queue-5.10/iio-imu-inv_icm42600-make-timestamp-module-chip-independent.patch b/queue-5.10/iio-imu-inv_icm42600-make-timestamp-module-chip-independent.patch
new file mode 100644 (file)
index 0000000..7cc09b8
--- /dev/null
@@ -0,0 +1,103 @@
+From stable+bounces-274090-greg=kroah.com@vger.kernel.org Tue Jul 14 05:06:17 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:37 -0400
+Subject: iio: imu: inv_icm42600: make timestamp module chip independent
+To: stable@vger.kernel.org
+Cc: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>, Andy Shevchenko <andy.shevchenko@gmail.com>, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030444.2382550-1-sashal@kernel.org>
+
+From: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+
+[ Upstream commit 6e9f2d8375cb24ba75e02e0272e9164d06a1522e ]
+
+Move icm42600 dependent function inside the core module.
+Do some headers cleanup at the same time.
+
+Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20230606162147.79667-2-inv.git-commit@tdk.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: affe3f077d7a ("iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/imu/inv_icm42600/inv_icm42600_core.c      |   11 +++++++++++
+ drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.c |   14 +-------------
+ drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.h |    6 ------
+ 3 files changed, 12 insertions(+), 19 deletions(-)
+
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
+@@ -522,6 +522,17 @@ static int inv_icm42600_irq_init(struct
+                                        "inv_icm42600", st);
+ }
++static int inv_icm42600_timestamp_setup(struct inv_icm42600_state *st)
++{
++      unsigned int val;
++
++      /* enable timestamp register */
++      val = INV_ICM42600_TMST_CONFIG_TMST_TO_REGS_EN |
++            INV_ICM42600_TMST_CONFIG_TMST_EN;
++      return regmap_update_bits(st->map, INV_ICM42600_REG_TMST_CONFIG,
++                                INV_ICM42600_TMST_CONFIG_MASK, val);
++}
++
+ static int inv_icm42600_enable_regulator_vddio(struct inv_icm42600_state *st)
+ {
+       int ret;
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.c
+@@ -3,11 +3,10 @@
+  * Copyright (C) 2020 Invensense, Inc.
+  */
++#include <linux/errno.h>
+ #include <linux/kernel.h>
+-#include <linux/regmap.h>
+ #include <linux/math64.h>
+-#include "inv_icm42600.h"
+ #include "inv_icm42600_timestamp.h"
+ /* internal chip period is 32kHz, 31250ns */
+@@ -56,17 +55,6 @@ void inv_icm42600_timestamp_init(struct
+       inv_update_acc(&ts->chip_period, INV_ICM42600_TIMESTAMP_PERIOD);
+ }
+-int inv_icm42600_timestamp_setup(struct inv_icm42600_state *st)
+-{
+-      unsigned int val;
+-
+-      /* enable timestamp register */
+-      val = INV_ICM42600_TMST_CONFIG_TMST_TO_REGS_EN |
+-            INV_ICM42600_TMST_CONFIG_TMST_EN;
+-      return regmap_update_bits(st->map, INV_ICM42600_REG_TMST_CONFIG,
+-                                INV_ICM42600_TMST_CONFIG_MASK, val);
+-}
+-
+ int inv_icm42600_timestamp_update_odr(struct inv_icm42600_timestamp *ts,
+                                     uint32_t period, bool fifo)
+ {
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.h
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.h
+@@ -6,10 +6,6 @@
+ #ifndef INV_ICM42600_TIMESTAMP_H_
+ #define INV_ICM42600_TIMESTAMP_H_
+-#include <linux/kernel.h>
+-
+-struct inv_icm42600_state;
+-
+ /**
+  * struct inv_icm42600_timestamp_interval - timestamps interval
+  * @lo:       interval lower bound
+@@ -53,8 +49,6 @@ struct inv_icm42600_timestamp {
+ void inv_icm42600_timestamp_init(struct inv_icm42600_timestamp *ts,
+                                uint32_t period);
+-int inv_icm42600_timestamp_setup(struct inv_icm42600_state *st);
+-
+ int inv_icm42600_timestamp_update_odr(struct inv_icm42600_timestamp *ts,
+                                     uint32_t period, bool fifo);
diff --git a/queue-5.10/iio-imu-inv_icm42600-stabilized-timestamp-in-interrupt.patch b/queue-5.10/iio-imu-inv_icm42600-stabilized-timestamp-in-interrupt.patch
new file mode 100644 (file)
index 0000000..30328b6
--- /dev/null
@@ -0,0 +1,116 @@
+From stable+bounces-274095-greg=kroah.com@vger.kernel.org Tue Jul 14 05:06:38 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:43 -0400
+Subject: iio: imu: inv_icm42600: stabilized timestamp in interrupt
+To: stable@vger.kernel.org
+Cc: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030444.2382550-7-sashal@kernel.org>
+
+From: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+
+[ Upstream commit d7bd473632d07f8a54655c270c0940cc3671c548 ]
+
+Use IRQF_ONESHOT flag to ensure the timestamp is not updated in the
+hard handler during the thread handler. And compute and use the
+effective watermark value that correspond to this first timestamp.
+
+This way we can ensure the timestamp is always corresponding to the
+value used by the timestamping mechanism. Otherwise, it is possible
+that between FIFO count read and FIFO processing the timestamp is
+overwritten in the hard handler.
+
+Fixes: ec74ae9fd37c ("iio: imu: inv_icm42600: add accurate timestamping")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Link: https://lore.kernel.org/r/20240529154717.651863-1-inv.git-commit@tdk.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: affe3f077d7a ("iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c |   19 +++++++++++++++++--
+ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h |    2 ++
+ drivers/iio/imu/inv_icm42600/inv_icm42600_core.c   |    1 +
+ 3 files changed, 20 insertions(+), 2 deletions(-)
+
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
+@@ -222,10 +222,15 @@ int inv_icm42600_buffer_update_watermark
+       latency_accel = period_accel * wm_accel;
+       /* 0 value for watermark means that the sensor is turned off */
++      if (wm_gyro == 0 && wm_accel == 0)
++              return 0;
++
+       if (latency_gyro == 0) {
+               watermark = wm_accel;
++              st->fifo.watermark.eff_accel = wm_accel;
+       } else if (latency_accel == 0) {
+               watermark = wm_gyro;
++              st->fifo.watermark.eff_gyro = wm_gyro;
+       } else {
+               /* compute the smallest latency that is a multiple of both */
+               if (latency_gyro <= latency_accel)
+@@ -241,6 +246,13 @@ int inv_icm42600_buffer_update_watermark
+               watermark = latency / period;
+               if (watermark < 1)
+                       watermark = 1;
++              /* update effective watermark */
++              st->fifo.watermark.eff_gyro = latency / period_gyro;
++              if (st->fifo.watermark.eff_gyro < 1)
++                      st->fifo.watermark.eff_gyro = 1;
++              st->fifo.watermark.eff_accel = latency / period_accel;
++              if (st->fifo.watermark.eff_accel < 1)
++                      st->fifo.watermark.eff_accel = 1;
+       }
+       /* compute watermark value in bytes */
+@@ -517,7 +529,7 @@ int inv_icm42600_buffer_fifo_parse(struc
+       /* handle gyroscope timestamp and FIFO data parsing */
+       if (st->fifo.nb.gyro > 0) {
+               ts = iio_priv(st->indio_gyro);
+-              inv_sensors_timestamp_interrupt(ts, st->fifo.nb.gyro,
++              inv_sensors_timestamp_interrupt(ts, st->fifo.watermark.eff_gyro,
+                                               st->timestamp.gyro);
+               ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro);
+               if (ret)
+@@ -527,7 +539,7 @@ int inv_icm42600_buffer_fifo_parse(struc
+       /* handle accelerometer timestamp and FIFO data parsing */
+       if (st->fifo.nb.accel > 0) {
+               ts = iio_priv(st->indio_accel);
+-              inv_sensors_timestamp_interrupt(ts, st->fifo.nb.accel,
++              inv_sensors_timestamp_interrupt(ts, st->fifo.watermark.eff_accel,
+                                               st->timestamp.accel);
+               ret = inv_icm42600_accel_parse_fifo(st->indio_accel);
+               if (ret)
+@@ -578,6 +590,9 @@ int inv_icm42600_buffer_init(struct inv_
+       unsigned int val;
+       int ret;
++      st->fifo.watermark.eff_gyro = 1;
++      st->fifo.watermark.eff_accel = 1;
++
+       /*
+        * Default FIFO configuration (bits 7 to 5)
+        * - use invalid value
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h
+@@ -32,6 +32,8 @@ struct inv_icm42600_fifo {
+       struct {
+               unsigned int gyro;
+               unsigned int accel;
++              unsigned int eff_gyro;
++              unsigned int eff_accel;
+       } watermark;
+       size_t count;
+       struct {
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
+@@ -518,6 +518,7 @@ static int inv_icm42600_irq_init(struct
+       if (ret)
+               return ret;
++      irq_type |= IRQF_ONESHOT;
+       return devm_request_threaded_irq(dev, irq, inv_icm42600_irq_timestamp,
+                                        inv_icm42600_irq_handler, irq_type,
+                                        "inv_icm42600", st);
diff --git a/queue-5.10/iio-imu-inv_mpu6050-use-the-common-inv_sensors-timestamp-module.patch b/queue-5.10/iio-imu-inv_mpu6050-use-the-common-inv_sensors-timestamp-module.patch
new file mode 100644 (file)
index 0000000..39a3646
--- /dev/null
@@ -0,0 +1,307 @@
+From stable+bounces-274098-greg=kroah.com@vger.kernel.org Tue Jul 14 05:05:00 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:40 -0400
+Subject: iio: imu: inv_mpu6050: use the common inv_sensors timestamp module
+To: stable@vger.kernel.org
+Cc: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>, Andy Shevchenko <andy.shevchenko@gmail.com>, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030444.2382550-4-sashal@kernel.org>
+
+From: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+
+[ Upstream commit 111e1abd00455971f6a568900f033cbddec9d4e5 ]
+
+Replace timestamping by the new common inv_sensors timestamp
+module. The principle behind is the same but the implementation in
+the new module is far better providing less jitter and a better
+estimation.
+
+Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20230606162147.79667-5-inv.git-commit@tdk.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: affe3f077d7a ("iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/imu/inv_mpu6050/Kconfig           |    1 
+ drivers/iio/imu/inv_mpu6050/inv_mpu_core.c    |   30 +++++++--
+ drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h     |   18 ++---
+ drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c    |   83 ++------------------------
+ drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c |    6 +
+ 5 files changed, 45 insertions(+), 93 deletions(-)
+
+--- a/drivers/iio/imu/inv_mpu6050/Kconfig
++++ b/drivers/iio/imu/inv_mpu6050/Kconfig
+@@ -7,6 +7,7 @@ config INV_MPU6050_IIO
+       tristate
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
++      select IIO_INV_SENSORS_TIMESTAMP
+ config INV_MPU6050_I2C
+       tristate "Invensense MPU6050 devices (I2C)"
+--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+@@ -12,12 +12,15 @@
+ #include <linux/jiffies.h>
+ #include <linux/irq.h>
+ #include <linux/interrupt.h>
+-#include <linux/iio/iio.h>
+ #include <linux/acpi.h>
+ #include <linux/platform_device.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/pm.h>
+ #include <linux/pm_runtime.h>
++
++#include <linux/iio/common/inv_sensors_timestamp.h>
++#include <linux/iio/iio.h>
++
+ #include "inv_mpu_iio.h"
+ #include "inv_mpu_magn.h"
+@@ -481,6 +484,7 @@ static int inv_mpu6050_init_config(struc
+       int result;
+       u8 d;
+       struct inv_mpu6050_state *st = iio_priv(indio_dev);
++      struct inv_sensors_timestamp_chip timestamp;
+       result = inv_mpu6050_set_gyro_fsr(st, st->chip_config.fsr);
+       if (result)
+@@ -504,12 +508,12 @@ static int inv_mpu6050_init_config(struc
+       if (result)
+               return result;
+-      /*
+-       * Internal chip period is 1ms (1kHz).
+-       * Let's use at the beginning the theorical value before measuring
+-       * with interrupt timestamps.
+-       */
+-      st->chip_period = NSEC_PER_MSEC;
++      /* clock jitter is +/- 2% */
++      timestamp.clock_period = NSEC_PER_SEC / INV_MPU6050_INTERNAL_FREQ_HZ;
++      timestamp.jitter = 20;
++      timestamp.init_period =
++                      NSEC_PER_SEC / INV_MPU6050_DIVIDER_TO_FIFO_RATE(st->chip_config.divider);
++      inv_sensors_timestamp_init(&st->timestamp, &timestamp);
+       /* magn chip init, noop if not present in the chip */
+       result = inv_mpu_magn_probe(st);
+@@ -900,6 +904,8 @@ inv_mpu6050_fifo_rate_store(struct devic
+                           const char *buf, size_t count)
+ {
+       int fifo_rate;
++      u32 fifo_period;
++      bool fifo_on;
+       u8 d;
+       int result;
+       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+@@ -916,12 +922,21 @@ inv_mpu6050_fifo_rate_store(struct devic
+       d = INV_MPU6050_FIFO_RATE_TO_DIVIDER(fifo_rate);
+       /* compute back the fifo rate to handle truncation cases */
+       fifo_rate = INV_MPU6050_DIVIDER_TO_FIFO_RATE(d);
++      fifo_period = NSEC_PER_SEC / fifo_rate;
+       mutex_lock(&st->lock);
+       if (d == st->chip_config.divider) {
+               result = 0;
+               goto fifo_rate_fail_unlock;
+       }
++
++      fifo_on = st->chip_config.accl_fifo_enable ||
++                st->chip_config.gyro_fifo_enable ||
++                st->chip_config.magn_fifo_enable;
++      result = inv_sensors_timestamp_update_odr(&st->timestamp, fifo_period, fifo_on);
++      if (result)
++              goto fifo_rate_fail_unlock;
++
+       result = pm_runtime_get_sync(pdev);
+       if (result < 0) {
+               pm_runtime_put_noidle(pdev);
+@@ -1741,3 +1756,4 @@ EXPORT_SYMBOL_GPL(inv_mpu_pmops);
+ MODULE_AUTHOR("Invensense Corporation");
+ MODULE_DESCRIPTION("Invensense device MPU6050 driver");
+ MODULE_LICENSE("GPL");
++MODULE_IMPORT_NS(IIO_INV_SENSORS_TIMESTAMP);
+--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
+@@ -9,15 +9,17 @@
+ #include <linux/i2c.h>
+ #include <linux/i2c-mux.h>
+ #include <linux/mutex.h>
+-#include <linux/iio/iio.h>
+-#include <linux/iio/buffer.h>
++#include <linux/platform_data/invensense_mpu6050.h>
+ #include <linux/regmap.h>
+-#include <linux/iio/sysfs.h>
++
++#include <linux/iio/buffer.h>
++#include <linux/iio/common/inv_sensors_timestamp.h>
++#include <linux/iio/iio.h>
+ #include <linux/iio/kfifo_buf.h>
+ #include <linux/iio/trigger.h>
+ #include <linux/iio/triggered_buffer.h>
+ #include <linux/iio/trigger_consumer.h>
+-#include <linux/platform_data/invensense_mpu6050.h>
++#include <linux/iio/sysfs.h>
+ /**
+  *  struct inv_mpu6050_reg_map - Notable registers.
+@@ -163,9 +165,7 @@ struct inv_mpu6050_hw {
+  *  @map              regmap pointer.
+  *  @irq              interrupt number.
+  *  @irq_mask         the int_pin_cfg mask to configure interrupt type.
+- *  @chip_period:     chip internal period estimation (~1kHz).
+- *  @it_timestamp:    timestamp from previous interrupt.
+- *  @data_timestamp:  timestamp for next data sample.
++ *  @timestamp:               timestamping module
+  *  @vdd_supply:      VDD voltage regulator for the chip.
+  *  @vddio_supply     I/O voltage regulator for the chip.
+  *  @magn_disabled:     magnetometer disabled for backward compatibility reason.
+@@ -189,9 +189,7 @@ struct inv_mpu6050_state {
+       int irq;
+       u8 irq_mask;
+       unsigned skip_samples;
+-      s64 chip_period;
+-      s64 it_timestamp;
+-      s64 data_timestamp;
++      struct inv_sensors_timestamp timestamp;
+       struct regulator *vdd_supply;
+       struct regulator *vddio_supply;
+       bool magn_disabled;
+--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
+@@ -13,81 +13,10 @@
+ #include <linux/interrupt.h>
+ #include <linux/poll.h>
+ #include <linux/math64.h>
+-#include "inv_mpu_iio.h"
+-
+-/**
+- *  inv_mpu6050_update_period() - Update chip internal period estimation
+- *
+- *  @st:              driver state
+- *  @timestamp:               the interrupt timestamp
+- *  @nb:              number of data set in the fifo
+- *
+- *  This function uses interrupt timestamps to estimate the chip period and
+- *  to choose the data timestamp to come.
+- */
+-static void inv_mpu6050_update_period(struct inv_mpu6050_state *st,
+-                                    s64 timestamp, size_t nb)
+-{
+-      /* Period boundaries for accepting timestamp */
+-      const s64 period_min =
+-              (NSEC_PER_MSEC * (100 - INV_MPU6050_TS_PERIOD_JITTER)) / 100;
+-      const s64 period_max =
+-              (NSEC_PER_MSEC * (100 + INV_MPU6050_TS_PERIOD_JITTER)) / 100;
+-      const s32 divider = INV_MPU6050_FREQ_DIVIDER(st);
+-      s64 delta, interval;
+-      bool use_it_timestamp = false;
+-
+-      if (st->it_timestamp == 0) {
+-              /* not initialized, forced to use it_timestamp */
+-              use_it_timestamp = true;
+-      } else if (nb == 1) {
+-              /*
+-               * Validate the use of it timestamp by checking if interrupt
+-               * has been delayed.
+-               * nb > 1 means interrupt was delayed for more than 1 sample,
+-               * so it's obviously not good.
+-               * Compute the chip period between 2 interrupts for validating.
+-               */
+-              delta = div_s64(timestamp - st->it_timestamp, divider);
+-              if (delta > period_min && delta < period_max) {
+-                      /* update chip period and use it timestamp */
+-                      st->chip_period = (st->chip_period + delta) / 2;
+-                      use_it_timestamp = true;
+-              }
+-      }
+-      if (use_it_timestamp) {
+-              /*
+-               * Manage case of multiple samples in the fifo (nb > 1):
+-               * compute timestamp corresponding to the first sample using
+-               * estimated chip period.
+-               */
+-              interval = (nb - 1) * st->chip_period * divider;
+-              st->data_timestamp = timestamp - interval;
+-      }
++#include <linux/iio/common/inv_sensors_timestamp.h>
+-      /* save it timestamp */
+-      st->it_timestamp = timestamp;
+-}
+-
+-/**
+- *  inv_mpu6050_get_timestamp() - Return the current data timestamp
+- *
+- *  @st:              driver state
+- *  @return:          current data timestamp
+- *
+- *  This function returns the current data timestamp and prepares for next one.
+- */
+-static s64 inv_mpu6050_get_timestamp(struct inv_mpu6050_state *st)
+-{
+-      s64 ts;
+-
+-      /* return current data timestamp and increment */
+-      ts = st->data_timestamp;
+-      st->data_timestamp += st->chip_period * INV_MPU6050_FREQ_DIVIDER(st);
+-
+-      return ts;
+-}
++#include "inv_mpu_iio.h"
+ static int inv_reset_fifo(struct iio_dev *indio_dev)
+ {
+@@ -121,6 +50,7 @@ irqreturn_t inv_mpu6050_read_fifo(int ir
+       size_t bytes_per_datum;
+       int result;
+       u16 fifo_count;
++      u32 fifo_period;
+       s64 timestamp;
+       int int_status;
+       size_t i, nb;
+@@ -177,7 +107,10 @@ irqreturn_t inv_mpu6050_read_fifo(int ir
+       /* compute and process all complete datum */
+       nb = fifo_count / bytes_per_datum;
+-      inv_mpu6050_update_period(st, pf->timestamp, nb);
++      /* Each FIFO data contains all sensors, so same number for FIFO and sensor data */
++      fifo_period = NSEC_PER_SEC / INV_MPU6050_DIVIDER_TO_FIFO_RATE(st->chip_config.divider);
++      inv_sensors_timestamp_interrupt(&st->timestamp, fifo_period, nb, nb, pf->timestamp);
++      inv_sensors_timestamp_apply_odr(&st->timestamp, fifo_period, nb, 0);
+       for (i = 0; i < nb; ++i) {
+               result = regmap_noinc_read(st->map, st->reg->fifo_r_w,
+                                          st->data, bytes_per_datum);
+@@ -188,7 +121,7 @@ irqreturn_t inv_mpu6050_read_fifo(int ir
+                       st->skip_samples--;
+                       continue;
+               }
+-              timestamp = inv_mpu6050_get_timestamp(st);
++              timestamp = inv_sensors_timestamp_pop(&st->timestamp);
+               iio_push_to_buffers_with_timestamp(indio_dev, st->data, timestamp);
+       }
+--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
+@@ -4,6 +4,9 @@
+ */
+ #include <linux/pm_runtime.h>
++
++#include <linux/iio/common/inv_sensors_timestamp.h>
++
+ #include "inv_mpu_iio.h"
+ static unsigned int inv_scan_query_mpu6050(struct iio_dev *indio_dev)
+@@ -107,7 +110,8 @@ int inv_mpu6050_prepare_fifo(struct inv_
+       int ret;
+       if (enable) {
+-              st->it_timestamp = 0;
++              /* reset timestamping */
++              inv_sensors_timestamp_reset(&st->timestamp);
+               /* reset FIFO */
+               d = st->chip_config.user_ctrl | INV_MPU6050_BIT_FIFO_RST;
+               ret = regmap_write(st->map, st->reg->user_ctrl, d);
diff --git a/queue-5.10/iio-invensense-fix-timestamp-glitches-when-switching-frequency.patch b/queue-5.10/iio-invensense-fix-timestamp-glitches-when-switching-frequency.patch
new file mode 100644 (file)
index 0000000..025e828
--- /dev/null
@@ -0,0 +1,202 @@
+From stable+bounces-274094-greg=kroah.com@vger.kernel.org Tue Jul 14 05:06:33 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:42 -0400
+Subject: iio: invensense: fix timestamp glitches when switching frequency
+To: stable@vger.kernel.org
+Cc: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>, Stable@vger.kernel.org, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030444.2382550-6-sashal@kernel.org>
+
+From: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+
+[ Upstream commit bf8367b00c33c64a9391c262bb2e11d274c9f2a4 ]
+
+When a sensor is running and there is a FIFO frequency change due to
+another sensor turned on/off, there are glitches on timestamp. Fix that
+by using only interrupt timestamp when there is the corresponding sensor
+data in the FIFO.
+
+Delete FIFO period handling and simplify internal functions.
+
+Update integration inside inv_mpu6050 and inv_icm42600 drivers.
+
+Fixes: 0ecc363ccea7 ("iio: make invensense timestamp module generic")
+Cc: Stable@vger.kernel.org
+Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Link: https://lore.kernel.org/r/20240426094835.138389-1-inv.git-commit@tdk.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: affe3f077d7a ("iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/common/inv_sensors/inv_sensors_timestamp.c |   30 +++++++----------
+ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c     |   20 ++++-------
+ drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c             |    2 -
+ include/linux/iio/common/inv_sensors_timestamp.h       |    3 -
+ 4 files changed, 23 insertions(+), 32 deletions(-)
+
+--- a/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
++++ b/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
+@@ -70,13 +70,13 @@ int inv_sensors_timestamp_update_odr(str
+ }
+ EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_update_odr, IIO_INV_SENSORS_TIMESTAMP);
+-static bool inv_validate_period(struct inv_sensors_timestamp *ts, uint32_t period, uint32_t mult)
++static bool inv_validate_period(struct inv_sensors_timestamp *ts, uint32_t period)
+ {
+       uint32_t period_min, period_max;
+       /* check that period is acceptable */
+-      period_min = ts->min_period * mult;
+-      period_max = ts->max_period * mult;
++      period_min = ts->min_period * ts->mult;
++      period_max = ts->max_period * ts->mult;
+       if (period > period_min && period < period_max)
+               return true;
+       else
+@@ -84,32 +84,30 @@ static bool inv_validate_period(struct i
+ }
+ static bool inv_compute_chip_period(struct inv_sensors_timestamp *ts,
+-                                  uint32_t mult, uint32_t period)
++                                  uint32_t period)
+ {
+       uint32_t new_chip_period;
+-      if (!inv_validate_period(ts, period, mult))
++      if (!inv_validate_period(ts, period))
+               return false;
+       /* update chip internal period estimation */
+-      new_chip_period = period / mult;
++      new_chip_period = period / ts->mult;
+       inv_update_acc(&ts->chip_period, new_chip_period);
+       return true;
+ }
+ void inv_sensors_timestamp_interrupt(struct inv_sensors_timestamp *ts,
+-                                    uint32_t fifo_period, size_t fifo_nb,
+-                                    size_t sensor_nb, int64_t timestamp)
++                                   size_t sample_nb, int64_t timestamp)
+ {
+       struct inv_sensors_timestamp_interval *it;
+       int64_t delta, interval;
+-      const uint32_t fifo_mult = fifo_period / ts->chip.clock_period;
+       uint32_t period;
+       int32_t m;
+       bool valid = false;
+-      if (fifo_nb == 0)
++      if (sample_nb == 0)
+               return;
+       /* update interrupt timestamp and compute chip and sensor periods */
+@@ -119,8 +117,8 @@ void inv_sensors_timestamp_interrupt(str
+       delta = it->up - it->lo;
+       if (it->lo != 0) {
+               /* compute period: delta time divided by number of samples */
+-              period = div_s64(delta, fifo_nb);
+-              valid = inv_compute_chip_period(ts, fifo_mult, period);
++              period = div_s64(delta, sample_nb);
++              valid = inv_compute_chip_period(ts, period);
+               /* update sensor period if chip internal period is updated */
+               if (valid)
+                       ts->period = ts->mult * ts->chip_period.val;
+@@ -129,20 +127,18 @@ void inv_sensors_timestamp_interrupt(str
+       /* no previous data, compute theoritical value from interrupt */
+       if (ts->timestamp == 0) {
+               /* elapsed time: sensor period * sensor samples number */
+-              interval = (int64_t)ts->period * (int64_t)sensor_nb;
++              interval = (int64_t)ts->period * (int64_t)sample_nb;
+               ts->timestamp = it->up - interval;
+               return;
+       }
+       /* if interrupt interval is valid, sync with interrupt timestamp */
+       if (valid) {
+-              /* compute measured fifo_period */
+-              fifo_period = fifo_mult * ts->chip_period.val;
+               /* delta time between last sample and last interrupt */
+               delta = it->lo - ts->timestamp;
+               /* if there are multiple samples, go back to first one */
+-              while (delta >= (fifo_period * 3 / 2))
+-                      delta -= fifo_period;
++              while (delta >= (ts->period * 3 / 2))
++                      delta -= ts->period;
+               /* compute maximal adjustment value */
+               m = INV_SENSORS_TIMESTAMP_JITTER((int64_t)ts->period, ts->chip.jitter);
+               if (delta > m)
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
+@@ -515,20 +515,20 @@ int inv_icm42600_buffer_fifo_parse(struc
+               return 0;
+       /* handle gyroscope timestamp and FIFO data parsing */
+-      ts = iio_priv(st->indio_gyro);
+-      inv_sensors_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total,
+-                                      st->fifo.nb.gyro, st->timestamp.gyro);
+       if (st->fifo.nb.gyro > 0) {
++              ts = iio_priv(st->indio_gyro);
++              inv_sensors_timestamp_interrupt(ts, st->fifo.nb.gyro,
++                                              st->timestamp.gyro);
+               ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro);
+               if (ret)
+                       return ret;
+       }
+       /* handle accelerometer timestamp and FIFO data parsing */
+-      ts = iio_priv(st->indio_accel);
+-      inv_sensors_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total,
+-                                      st->fifo.nb.accel, st->timestamp.accel);
+       if (st->fifo.nb.accel > 0) {
++              ts = iio_priv(st->indio_accel);
++              inv_sensors_timestamp_interrupt(ts, st->fifo.nb.accel,
++                                              st->timestamp.accel);
+               ret = inv_icm42600_accel_parse_fifo(st->indio_accel);
+               if (ret)
+                       return ret;
+@@ -556,9 +556,7 @@ int inv_icm42600_buffer_hwfifo_flush(str
+       if (st->fifo.nb.gyro > 0) {
+               ts = iio_priv(st->indio_gyro);
+-              inv_sensors_timestamp_interrupt(ts, st->fifo.period,
+-                                              st->fifo.nb.total, st->fifo.nb.gyro,
+-                                              gyro_ts);
++              inv_sensors_timestamp_interrupt(ts, st->fifo.nb.gyro, gyro_ts);
+               ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro);
+               if (ret)
+                       return ret;
+@@ -566,9 +564,7 @@ int inv_icm42600_buffer_hwfifo_flush(str
+       if (st->fifo.nb.accel > 0) {
+               ts = iio_priv(st->indio_accel);
+-              inv_sensors_timestamp_interrupt(ts, st->fifo.period,
+-                                              st->fifo.nb.total, st->fifo.nb.accel,
+-                                              accel_ts);
++              inv_sensors_timestamp_interrupt(ts, st->fifo.nb.accel, accel_ts);
+               ret = inv_icm42600_accel_parse_fifo(st->indio_accel);
+               if (ret)
+                       return ret;
+--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
+@@ -109,7 +109,7 @@ irqreturn_t inv_mpu6050_read_fifo(int ir
+       nb = fifo_count / bytes_per_datum;
+       /* Each FIFO data contains all sensors, so same number for FIFO and sensor data */
+       fifo_period = NSEC_PER_SEC / INV_MPU6050_DIVIDER_TO_FIFO_RATE(st->chip_config.divider);
+-      inv_sensors_timestamp_interrupt(&st->timestamp, fifo_period, nb, nb, pf->timestamp);
++      inv_sensors_timestamp_interrupt(&st->timestamp, nb, pf->timestamp);
+       inv_sensors_timestamp_apply_odr(&st->timestamp, fifo_period, nb, 0);
+       for (i = 0; i < nb; ++i) {
+               result = regmap_noinc_read(st->map, st->reg->fifo_r_w,
+--- a/include/linux/iio/common/inv_sensors_timestamp.h
++++ b/include/linux/iio/common/inv_sensors_timestamp.h
+@@ -71,8 +71,7 @@ int inv_sensors_timestamp_update_odr(str
+                                    uint32_t period, bool fifo);
+ void inv_sensors_timestamp_interrupt(struct inv_sensors_timestamp *ts,
+-                                   uint32_t fifo_period, size_t fifo_nb,
+-                                   size_t sensor_nb, int64_t timestamp);
++                                   size_t sample_nb, int64_t timestamp);
+ static inline int64_t inv_sensors_timestamp_pop(struct inv_sensors_timestamp *ts)
+ {
diff --git a/queue-5.10/iio-invensense-remove-redundant-initialization-of-variable-period.patch b/queue-5.10/iio-invensense-remove-redundant-initialization-of-variable-period.patch
new file mode 100644 (file)
index 0000000..0bfe882
--- /dev/null
@@ -0,0 +1,42 @@
+From stable+bounces-274093-greg=kroah.com@vger.kernel.org Tue Jul 14 05:06:29 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:41 -0400
+Subject: iio: invensense: remove redundant initialization of variable period
+To: stable@vger.kernel.org
+Cc: Colin Ian King <colin.i.king@gmail.com>, Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030444.2382550-5-sashal@kernel.org>
+
+From: Colin Ian King <colin.i.king@gmail.com>
+
+[ Upstream commit b58b13f156c00c2457035b7071eaaac105fe6836 ]
+
+The variable period is being initialized with a value that is never
+read, it is being re-assigned a new value later on before it is read.
+The initialization is redundant and can be removed.
+
+Cleans up clang scan build warning:
+Value stored to 'period' during its initialization is never
+read [deadcode.DeadStores]
+
+Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
+Acked-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Link: https://lore.kernel.org/r/20240106153202.54861-1-colin.i.king@gmail.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: affe3f077d7a ("iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/common/inv_sensors/inv_sensors_timestamp.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
++++ b/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
+@@ -105,7 +105,7 @@ void inv_sensors_timestamp_interrupt(str
+       struct inv_sensors_timestamp_interval *it;
+       int64_t delta, interval;
+       const uint32_t fifo_mult = fifo_period / ts->chip.clock_period;
+-      uint32_t period = ts->period;
++      uint32_t period;
+       int32_t m;
+       bool valid = false;
diff --git a/queue-5.10/iio-make-invensense-timestamp-module-generic.patch b/queue-5.10/iio-make-invensense-timestamp-module-generic.patch
new file mode 100644 (file)
index 0000000..74a87d3
--- /dev/null
@@ -0,0 +1,962 @@
+From stable+bounces-274092-greg=kroah.com@vger.kernel.org Tue Jul 14 05:06:25 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:39 -0400
+Subject: iio: make invensense timestamp module generic
+To: stable@vger.kernel.org
+Cc: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>, Andy Shevchenko <andy.shevchenko@gmail.com>, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030444.2382550-3-sashal@kernel.org>
+
+From: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+
+[ Upstream commit 0ecc363ccea71eda6a2cceade120489259bcdb33 ]
+
+Rename common module to inv_sensors_timestamp, add configuration
+at init (chip internal clock, acceptable jitter, ...) and update
+inv_icm42600 driver integration.
+
+Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20230606162147.79667-4-inv.git-commit@tdk.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: affe3f077d7a ("iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/common/inv_sensors/Makefile                 |    2 
+ drivers/iio/common/inv_sensors/inv_icm42600_timestamp.c |  192 ----------------
+ drivers/iio/common/inv_sensors/inv_sensors_timestamp.c  |  191 +++++++++++++++
+ drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c       |   32 +-
+ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c      |   34 +-
+ drivers/iio/imu/inv_icm42600/inv_icm42600_core.c        |   10 
+ drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c        |   32 +-
+ include/linux/iio/common/inv_icm42600_timestamp.h       |   79 ------
+ include/linux/iio/common/inv_sensors_timestamp.h        |   95 +++++++
+ 9 files changed, 349 insertions(+), 318 deletions(-)
+ rename drivers/iio/common/inv_sensors/{inv_icm42600_timestamp.c => inv_sensors_timestamp.c} (61%)
+ delete mode 100644 include/linux/iio/common/inv_icm42600_timestamp.h
+ create mode 100644 include/linux/iio/common/inv_sensors_timestamp.h
+
+--- a/drivers/iio/common/inv_sensors/Makefile
++++ b/drivers/iio/common/inv_sensors/Makefile
+@@ -3,4 +3,4 @@
+ # Makefile for TDK-InvenSense sensors module.
+ #
+-obj-$(CONFIG_IIO_INV_SENSORS_TIMESTAMP) += inv_icm42600_timestamp.o
++obj-$(CONFIG_IIO_INV_SENSORS_TIMESTAMP) += inv_sensors_timestamp.o
+--- a/drivers/iio/common/inv_sensors/inv_icm42600_timestamp.c
++++ /dev/null
+@@ -1,192 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0-or-later
+-/*
+- * Copyright (C) 2020 Invensense, Inc.
+- */
+-
+-#include <linux/errno.h>
+-#include <linux/kernel.h>
+-#include <linux/math64.h>
+-#include <linux/module.h>
+-
+-#include <linux/iio/common/inv_icm42600_timestamp.h>
+-
+-/* internal chip period is 32kHz, 31250ns */
+-#define INV_ICM42600_TIMESTAMP_PERIOD         31250
+-/* allow a jitter of +/- 2% */
+-#define INV_ICM42600_TIMESTAMP_JITTER         2
+-/* compute min and max periods accepted */
+-#define INV_ICM42600_TIMESTAMP_MIN_PERIOD(_p)         \
+-      (((_p) * (100 - INV_ICM42600_TIMESTAMP_JITTER)) / 100)
+-#define INV_ICM42600_TIMESTAMP_MAX_PERIOD(_p)         \
+-      (((_p) * (100 + INV_ICM42600_TIMESTAMP_JITTER)) / 100)
+-
+-/* Add a new value inside an accumulator and update the estimate value */
+-static void inv_update_acc(struct inv_icm42600_timestamp_acc *acc, uint32_t val)
+-{
+-      uint64_t sum = 0;
+-      size_t i;
+-
+-      acc->values[acc->idx++] = val;
+-      if (acc->idx >= ARRAY_SIZE(acc->values))
+-              acc->idx = 0;
+-
+-      /* compute the mean of all stored values, use 0 as empty slot */
+-      for (i = 0; i < ARRAY_SIZE(acc->values); ++i) {
+-              if (acc->values[i] == 0)
+-                      break;
+-              sum += acc->values[i];
+-      }
+-
+-      acc->val = div_u64(sum, i);
+-}
+-
+-void inv_icm42600_timestamp_init(struct inv_icm42600_timestamp *ts,
+-                               uint32_t period)
+-{
+-      /* initial odr for sensor after reset is 1kHz */
+-      const uint32_t default_period = 1000000;
+-
+-      /* current multiplier and period values after reset */
+-      ts->mult = default_period / INV_ICM42600_TIMESTAMP_PERIOD;
+-      ts->period = default_period;
+-      /* new set multiplier is the one from chip initialization */
+-      ts->new_mult = period / INV_ICM42600_TIMESTAMP_PERIOD;
+-
+-      /* use theoretical value for chip period */
+-      inv_update_acc(&ts->chip_period, INV_ICM42600_TIMESTAMP_PERIOD);
+-}
+-EXPORT_SYMBOL_NS_GPL(inv_icm42600_timestamp_init, IIO_INV_SENSORS_TIMESTAMP);
+-
+-int inv_icm42600_timestamp_update_odr(struct inv_icm42600_timestamp *ts,
+-                                    uint32_t period, bool fifo)
+-{
+-      /* when FIFO is on, prevent odr change if one is already pending */
+-      if (fifo && ts->new_mult != 0)
+-              return -EAGAIN;
+-
+-      ts->new_mult = period / INV_ICM42600_TIMESTAMP_PERIOD;
+-
+-      return 0;
+-}
+-EXPORT_SYMBOL_NS_GPL(inv_icm42600_timestamp_update_odr, IIO_INV_SENSORS_TIMESTAMP);
+-
+-static bool inv_validate_period(uint32_t period, uint32_t mult)
+-{
+-      const uint32_t chip_period = INV_ICM42600_TIMESTAMP_PERIOD;
+-      uint32_t period_min, period_max;
+-
+-      /* check that period is acceptable */
+-      period_min = INV_ICM42600_TIMESTAMP_MIN_PERIOD(chip_period) * mult;
+-      period_max = INV_ICM42600_TIMESTAMP_MAX_PERIOD(chip_period) * mult;
+-      if (period > period_min && period < period_max)
+-              return true;
+-      else
+-              return false;
+-}
+-
+-static bool inv_compute_chip_period(struct inv_icm42600_timestamp *ts,
+-                                  uint32_t mult, uint32_t period)
+-{
+-      uint32_t new_chip_period;
+-
+-      if (!inv_validate_period(period, mult))
+-              return false;
+-
+-      /* update chip internal period estimation */
+-      new_chip_period = period / mult;
+-      inv_update_acc(&ts->chip_period, new_chip_period);
+-
+-      return true;
+-}
+-
+-void inv_icm42600_timestamp_interrupt(struct inv_icm42600_timestamp *ts,
+-                                    uint32_t fifo_period, size_t fifo_nb,
+-                                    size_t sensor_nb, int64_t timestamp)
+-{
+-      struct inv_icm42600_timestamp_interval *it;
+-      int64_t delta, interval;
+-      const uint32_t fifo_mult = fifo_period / INV_ICM42600_TIMESTAMP_PERIOD;
+-      uint32_t period = ts->period;
+-      int32_t m;
+-      bool valid = false;
+-
+-      if (fifo_nb == 0)
+-              return;
+-
+-      /* update interrupt timestamp and compute chip and sensor periods */
+-      it = &ts->it;
+-      it->lo = it->up;
+-      it->up = timestamp;
+-      delta = it->up - it->lo;
+-      if (it->lo != 0) {
+-              /* compute period: delta time divided by number of samples */
+-              period = div_s64(delta, fifo_nb);
+-              valid = inv_compute_chip_period(ts, fifo_mult, period);
+-              /* update sensor period if chip internal period is updated */
+-              if (valid)
+-                      ts->period = ts->mult * ts->chip_period.val;
+-      }
+-
+-      /* no previous data, compute theoritical value from interrupt */
+-      if (ts->timestamp == 0) {
+-              /* elapsed time: sensor period * sensor samples number */
+-              interval = (int64_t)ts->period * (int64_t)sensor_nb;
+-              ts->timestamp = it->up - interval;
+-              return;
+-      }
+-
+-      /* if interrupt interval is valid, sync with interrupt timestamp */
+-      if (valid) {
+-              /* compute measured fifo_period */
+-              fifo_period = fifo_mult * ts->chip_period.val;
+-              /* delta time between last sample and last interrupt */
+-              delta = it->lo - ts->timestamp;
+-              /* if there are multiple samples, go back to first one */
+-              while (delta >= (fifo_period * 3 / 2))
+-                      delta -= fifo_period;
+-              /* compute maximal adjustment value */
+-              m = INV_ICM42600_TIMESTAMP_MAX_PERIOD(ts->period) - ts->period;
+-              if (delta > m)
+-                      delta = m;
+-              else if (delta < -m)
+-                      delta = -m;
+-              ts->timestamp += delta;
+-      }
+-}
+-EXPORT_SYMBOL_NS_GPL(inv_icm42600_timestamp_interrupt, IIO_INV_SENSORS_TIMESTAMP);
+-
+-void inv_icm42600_timestamp_apply_odr(struct inv_icm42600_timestamp *ts,
+-                                    uint32_t fifo_period, size_t fifo_nb,
+-                                    unsigned int fifo_no)
+-{
+-      int64_t interval;
+-      uint32_t fifo_mult;
+-
+-      if (ts->new_mult == 0)
+-              return;
+-
+-      /* update to new multiplier and update period */
+-      ts->mult = ts->new_mult;
+-      ts->new_mult = 0;
+-      ts->period = ts->mult * ts->chip_period.val;
+-
+-      /*
+-       * After ODR change the time interval with the previous sample is
+-       * undertermined (depends when the change occures). So we compute the
+-       * timestamp from the current interrupt using the new FIFO period, the
+-       * total number of samples and the current sample numero.
+-       */
+-      if (ts->timestamp != 0) {
+-              /* compute measured fifo period */
+-              fifo_mult = fifo_period / INV_ICM42600_TIMESTAMP_PERIOD;
+-              fifo_period = fifo_mult * ts->chip_period.val;
+-              /* computes time interval between interrupt and this sample */
+-              interval = (int64_t)(fifo_nb - fifo_no) * (int64_t)fifo_period;
+-              ts->timestamp = ts->it.up - interval;
+-      }
+-}
+-EXPORT_SYMBOL_NS_GPL(inv_icm42600_timestamp_apply_odr, IIO_INV_SENSORS_TIMESTAMP);
+-
+-MODULE_AUTHOR("InvenSense, Inc.");
+-MODULE_DESCRIPTION("InvenSense sensors timestamp module");
+-MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
+@@ -0,0 +1,191 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Copyright (C) 2020 Invensense, Inc.
++ */
++
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/math64.h>
++#include <linux/module.h>
++
++#include <linux/iio/common/inv_sensors_timestamp.h>
++
++/* compute jitter, min and max following jitter in per mille */
++#define INV_SENSORS_TIMESTAMP_JITTER(_val, _jitter)           \
++      (div_s64((_val) * (_jitter), 1000))
++#define INV_SENSORS_TIMESTAMP_MIN(_val, _jitter)              \
++      (((_val) * (1000 - (_jitter))) / 1000)
++#define INV_SENSORS_TIMESTAMP_MAX(_val, _jitter)              \
++      (((_val) * (1000 + (_jitter))) / 1000)
++
++/* Add a new value inside an accumulator and update the estimate value */
++static void inv_update_acc(struct inv_sensors_timestamp_acc *acc, uint32_t val)
++{
++      uint64_t sum = 0;
++      size_t i;
++
++      acc->values[acc->idx++] = val;
++      if (acc->idx >= ARRAY_SIZE(acc->values))
++              acc->idx = 0;
++
++      /* compute the mean of all stored values, use 0 as empty slot */
++      for (i = 0; i < ARRAY_SIZE(acc->values); ++i) {
++              if (acc->values[i] == 0)
++                      break;
++              sum += acc->values[i];
++      }
++
++      acc->val = div_u64(sum, i);
++}
++
++void inv_sensors_timestamp_init(struct inv_sensors_timestamp *ts,
++                              const struct inv_sensors_timestamp_chip *chip)
++{
++      memset(ts, 0, sizeof(*ts));
++
++      /* save chip parameters and compute min and max clock period */
++      ts->chip = *chip;
++      ts->min_period = INV_SENSORS_TIMESTAMP_MIN(chip->clock_period, chip->jitter);
++      ts->max_period = INV_SENSORS_TIMESTAMP_MAX(chip->clock_period, chip->jitter);
++
++      /* current multiplier and period values after reset */
++      ts->mult = chip->init_period / chip->clock_period;
++      ts->period = chip->init_period;
++
++      /* use theoretical value for chip period */
++      inv_update_acc(&ts->chip_period, chip->clock_period);
++}
++EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_init, IIO_INV_SENSORS_TIMESTAMP);
++
++int inv_sensors_timestamp_update_odr(struct inv_sensors_timestamp *ts,
++                                   uint32_t period, bool fifo)
++{
++      /* when FIFO is on, prevent odr change if one is already pending */
++      if (fifo && ts->new_mult != 0)
++              return -EAGAIN;
++
++      ts->new_mult = period / ts->chip.clock_period;
++
++      return 0;
++}
++EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_update_odr, IIO_INV_SENSORS_TIMESTAMP);
++
++static bool inv_validate_period(struct inv_sensors_timestamp *ts, uint32_t period, uint32_t mult)
++{
++      uint32_t period_min, period_max;
++
++      /* check that period is acceptable */
++      period_min = ts->min_period * mult;
++      period_max = ts->max_period * mult;
++      if (period > period_min && period < period_max)
++              return true;
++      else
++              return false;
++}
++
++static bool inv_compute_chip_period(struct inv_sensors_timestamp *ts,
++                                  uint32_t mult, uint32_t period)
++{
++      uint32_t new_chip_period;
++
++      if (!inv_validate_period(ts, period, mult))
++              return false;
++
++      /* update chip internal period estimation */
++      new_chip_period = period / mult;
++      inv_update_acc(&ts->chip_period, new_chip_period);
++
++      return true;
++}
++
++void inv_sensors_timestamp_interrupt(struct inv_sensors_timestamp *ts,
++                                    uint32_t fifo_period, size_t fifo_nb,
++                                    size_t sensor_nb, int64_t timestamp)
++{
++      struct inv_sensors_timestamp_interval *it;
++      int64_t delta, interval;
++      const uint32_t fifo_mult = fifo_period / ts->chip.clock_period;
++      uint32_t period = ts->period;
++      int32_t m;
++      bool valid = false;
++
++      if (fifo_nb == 0)
++              return;
++
++      /* update interrupt timestamp and compute chip and sensor periods */
++      it = &ts->it;
++      it->lo = it->up;
++      it->up = timestamp;
++      delta = it->up - it->lo;
++      if (it->lo != 0) {
++              /* compute period: delta time divided by number of samples */
++              period = div_s64(delta, fifo_nb);
++              valid = inv_compute_chip_period(ts, fifo_mult, period);
++              /* update sensor period if chip internal period is updated */
++              if (valid)
++                      ts->period = ts->mult * ts->chip_period.val;
++      }
++
++      /* no previous data, compute theoritical value from interrupt */
++      if (ts->timestamp == 0) {
++              /* elapsed time: sensor period * sensor samples number */
++              interval = (int64_t)ts->period * (int64_t)sensor_nb;
++              ts->timestamp = it->up - interval;
++              return;
++      }
++
++      /* if interrupt interval is valid, sync with interrupt timestamp */
++      if (valid) {
++              /* compute measured fifo_period */
++              fifo_period = fifo_mult * ts->chip_period.val;
++              /* delta time between last sample and last interrupt */
++              delta = it->lo - ts->timestamp;
++              /* if there are multiple samples, go back to first one */
++              while (delta >= (fifo_period * 3 / 2))
++                      delta -= fifo_period;
++              /* compute maximal adjustment value */
++              m = INV_SENSORS_TIMESTAMP_JITTER((int64_t)ts->period, ts->chip.jitter);
++              if (delta > m)
++                      delta = m;
++              else if (delta < -m)
++                      delta = -m;
++              ts->timestamp += delta;
++      }
++}
++EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_interrupt, IIO_INV_SENSORS_TIMESTAMP);
++
++void inv_sensors_timestamp_apply_odr(struct inv_sensors_timestamp *ts,
++                                   uint32_t fifo_period, size_t fifo_nb,
++                                   unsigned int fifo_no)
++{
++      int64_t interval;
++      uint32_t fifo_mult;
++
++      if (ts->new_mult == 0)
++              return;
++
++      /* update to new multiplier and update period */
++      ts->mult = ts->new_mult;
++      ts->new_mult = 0;
++      ts->period = ts->mult * ts->chip_period.val;
++
++      /*
++       * After ODR change the time interval with the previous sample is
++       * undertermined (depends when the change occures). So we compute the
++       * timestamp from the current interrupt using the new FIFO period, the
++       * total number of samples and the current sample numero.
++       */
++      if (ts->timestamp != 0) {
++              /* compute measured fifo period */
++              fifo_mult = fifo_period / ts->chip.clock_period;
++              fifo_period = fifo_mult * ts->chip_period.val;
++              /* computes time interval between interrupt and this sample */
++              interval = (int64_t)(fifo_nb - fifo_no) * (int64_t)fifo_period;
++              ts->timestamp = ts->it.up - interval;
++      }
++}
++EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_apply_odr, IIO_INV_SENSORS_TIMESTAMP);
++
++MODULE_AUTHOR("InvenSense, Inc.");
++MODULE_DESCRIPTION("InvenSense sensors timestamp module");
++MODULE_LICENSE("GPL");
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
+@@ -12,7 +12,7 @@
+ #include <linux/math64.h>
+ #include <linux/iio/buffer.h>
+-#include <linux/iio/common/inv_icm42600_timestamp.h>
++#include <linux/iio/common/inv_sensors_timestamp.h>
+ #include <linux/iio/iio.h>
+ #include <linux/iio/kfifo_buf.h>
+@@ -99,7 +99,7 @@ static int inv_icm42600_accel_update_sca
+                                              const unsigned long *scan_mask)
+ {
+       struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+-      struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
++      struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
+       struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
+       unsigned int fifo_en = 0;
+       unsigned int sleep_temp = 0;
+@@ -127,7 +127,7 @@ static int inv_icm42600_accel_update_sca
+       }
+       /* update data FIFO write */
+-      inv_icm42600_timestamp_apply_odr(ts, 0, 0, 0);
++      inv_sensors_timestamp_apply_odr(ts, 0, 0, 0);
+       ret = inv_icm42600_buffer_set_fifo_en(st, fifo_en | st->fifo.en);
+ out_unlock:
+@@ -308,7 +308,7 @@ static int inv_icm42600_accel_write_odr(
+                                       int val, int val2)
+ {
+       struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+-      struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
++      struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
+       struct device *dev = regmap_get_device(st->map);
+       unsigned int idx;
+       struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
+@@ -329,8 +329,8 @@ static int inv_icm42600_accel_write_odr(
+       pm_runtime_get_sync(dev);
+       mutex_lock(&st->lock);
+-      ret = inv_icm42600_timestamp_update_odr(ts, inv_icm42600_odr_to_period(conf.odr),
+-                                              iio_buffer_enabled(indio_dev));
++      ret = inv_sensors_timestamp_update_odr(ts, inv_icm42600_odr_to_period(conf.odr),
++                                             iio_buffer_enabled(indio_dev));
+       if (ret)
+               goto out_unlock;
+@@ -706,7 +706,8 @@ struct iio_dev *inv_icm42600_accel_init(
+ {
+       struct device *dev = regmap_get_device(st->map);
+       const char *name;
+-      struct inv_icm42600_timestamp *ts;
++      struct inv_sensors_timestamp_chip ts_chip;
++      struct inv_sensors_timestamp *ts;
+       struct iio_dev *indio_dev;
+       struct iio_buffer *buffer;
+       int ret;
+@@ -723,8 +724,15 @@ struct iio_dev *inv_icm42600_accel_init(
+       if (!buffer)
+               return ERR_PTR(-ENOMEM);
++      /*
++       * clock period is 32kHz (31250ns)
++       * jitter is +/- 2% (20 per mille)
++       */
++      ts_chip.clock_period = 31250;
++      ts_chip.jitter = 20;
++      ts_chip.init_period = inv_icm42600_odr_to_period(st->conf.accel.odr);
+       ts = iio_priv(indio_dev);
+-      inv_icm42600_timestamp_init(ts, inv_icm42600_odr_to_period(st->conf.accel.odr));
++      inv_sensors_timestamp_init(ts, &ts_chip);
+       iio_device_set_drvdata(indio_dev, st);
+       indio_dev->name = name;
+@@ -747,7 +755,7 @@ struct iio_dev *inv_icm42600_accel_init(
+ int inv_icm42600_accel_parse_fifo(struct iio_dev *indio_dev)
+ {
+       struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+-      struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
++      struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
+       ssize_t i, size;
+       unsigned int no;
+       const void *accel, *gyro, *timestamp;
+@@ -771,13 +779,13 @@ int inv_icm42600_accel_parse_fifo(struct
+               /* update odr */
+               if (odr & INV_ICM42600_SENSOR_ACCEL)
+-                      inv_icm42600_timestamp_apply_odr(ts, st->fifo.period,
+-                                                       st->fifo.nb.total, no);
++                      inv_sensors_timestamp_apply_odr(ts, st->fifo.period,
++                                                      st->fifo.nb.total, no);
+               memcpy(&buffer.accel, accel, sizeof(buffer.accel));
+               /* convert 8 bits FIFO temperature in high resolution format */
+               buffer.temp = temp ? (*temp * 64) : 0;
+-              ts_val = inv_icm42600_timestamp_pop(ts);
++              ts_val = inv_sensors_timestamp_pop(ts);
+               iio_push_to_buffers_with_timestamp(indio_dev, &buffer, ts_val);
+       }
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
+@@ -11,7 +11,7 @@
+ #include <linux/delay.h>
+ #include <linux/iio/buffer.h>
+-#include <linux/iio/common/inv_icm42600_timestamp.h>
++#include <linux/iio/common/inv_sensors_timestamp.h>
+ #include <linux/iio/iio.h>
+ #include "inv_icm42600.h"
+@@ -276,12 +276,12 @@ static int inv_icm42600_buffer_preenable
+ {
+       struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+       struct device *dev = regmap_get_device(st->map);
+-      struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
++      struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
+       pm_runtime_get_sync(dev);
+       mutex_lock(&st->lock);
+-      inv_icm42600_timestamp_reset(ts);
++      inv_sensors_timestamp_reset(ts);
+       mutex_unlock(&st->lock);
+       return 0;
+@@ -378,7 +378,7 @@ out_unlock:
+ static int inv_icm42600_buffer_postdisable(struct iio_dev *indio_dev)
+ {
+       struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+-      struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
++      struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
+       struct device *dev = regmap_get_device(st->map);
+       unsigned int sensor;
+       unsigned int *watermark;
+@@ -400,7 +400,7 @@ static int inv_icm42600_buffer_postdisab
+       mutex_lock(&st->lock);
+-      inv_icm42600_timestamp_apply_odr(ts, 0, 0, 0);
++      inv_sensors_timestamp_apply_odr(ts, 0, 0, 0);
+       ret = inv_icm42600_buffer_set_fifo_en(st, st->fifo.en & ~sensor);
+       if (ret)
+@@ -508,7 +508,7 @@ int inv_icm42600_buffer_fifo_read(struct
+ int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st)
+ {
+-      struct inv_icm42600_timestamp *ts;
++      struct inv_sensors_timestamp *ts;
+       int ret;
+       if (st->fifo.nb.total == 0)
+@@ -516,8 +516,8 @@ int inv_icm42600_buffer_fifo_parse(struc
+       /* handle gyroscope timestamp and FIFO data parsing */
+       ts = iio_priv(st->indio_gyro);
+-      inv_icm42600_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total,
+-                                       st->fifo.nb.gyro, st->timestamp.gyro);
++      inv_sensors_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total,
++                                      st->fifo.nb.gyro, st->timestamp.gyro);
+       if (st->fifo.nb.gyro > 0) {
+               ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro);
+               if (ret)
+@@ -526,8 +526,8 @@ int inv_icm42600_buffer_fifo_parse(struc
+       /* handle accelerometer timestamp and FIFO data parsing */
+       ts = iio_priv(st->indio_accel);
+-      inv_icm42600_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total,
+-                                       st->fifo.nb.accel, st->timestamp.accel);
++      inv_sensors_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total,
++                                      st->fifo.nb.accel, st->timestamp.accel);
+       if (st->fifo.nb.accel > 0) {
+               ret = inv_icm42600_accel_parse_fifo(st->indio_accel);
+               if (ret)
+@@ -540,7 +540,7 @@ int inv_icm42600_buffer_fifo_parse(struc
+ int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st,
+                                    unsigned int count)
+ {
+-      struct inv_icm42600_timestamp *ts;
++      struct inv_sensors_timestamp *ts;
+       int64_t gyro_ts, accel_ts;
+       int ret;
+@@ -556,9 +556,9 @@ int inv_icm42600_buffer_hwfifo_flush(str
+       if (st->fifo.nb.gyro > 0) {
+               ts = iio_priv(st->indio_gyro);
+-              inv_icm42600_timestamp_interrupt(ts, st->fifo.period,
+-                                               st->fifo.nb.total, st->fifo.nb.gyro,
+-                                               gyro_ts);
++              inv_sensors_timestamp_interrupt(ts, st->fifo.period,
++                                              st->fifo.nb.total, st->fifo.nb.gyro,
++                                              gyro_ts);
+               ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro);
+               if (ret)
+                       return ret;
+@@ -566,9 +566,9 @@ int inv_icm42600_buffer_hwfifo_flush(str
+       if (st->fifo.nb.accel > 0) {
+               ts = iio_priv(st->indio_accel);
+-              inv_icm42600_timestamp_interrupt(ts, st->fifo.period,
+-                                               st->fifo.nb.total, st->fifo.nb.accel,
+-                                               accel_ts);
++              inv_sensors_timestamp_interrupt(ts, st->fifo.period,
++                                              st->fifo.nb.total, st->fifo.nb.accel,
++                                              accel_ts);
+               ret = inv_icm42600_accel_parse_fifo(st->indio_accel);
+               if (ret)
+                       return ret;
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
+@@ -16,7 +16,7 @@
+ #include <linux/property.h>
+ #include <linux/regmap.h>
+-#include <linux/iio/common/inv_icm42600_timestamp.h>
++#include <linux/iio/common/inv_sensors_timestamp.h>
+ #include <linux/iio/iio.h>
+ #include "inv_icm42600.h"
+@@ -720,8 +720,8 @@ out_unlock:
+ static int __maybe_unused inv_icm42600_resume(struct device *dev)
+ {
+       struct inv_icm42600_state *st = dev_get_drvdata(dev);
+-      struct inv_icm42600_timestamp *gyro_ts = iio_priv(st->indio_gyro);
+-      struct inv_icm42600_timestamp *accel_ts = iio_priv(st->indio_accel);
++      struct inv_sensors_timestamp *gyro_ts = iio_priv(st->indio_gyro);
++      struct inv_sensors_timestamp *accel_ts = iio_priv(st->indio_accel);
+       int ret = 0;
+       mutex_lock(&st->lock);
+@@ -742,8 +742,8 @@ static int __maybe_unused inv_icm42600_r
+       /* restore FIFO data streaming */
+       if (st->fifo.on) {
+-              inv_icm42600_timestamp_reset(gyro_ts);
+-              inv_icm42600_timestamp_reset(accel_ts);
++              inv_sensors_timestamp_reset(gyro_ts);
++              inv_sensors_timestamp_reset(accel_ts);
+               ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG,
+                                  INV_ICM42600_FIFO_CONFIG_STREAM);
+       }
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
+@@ -12,7 +12,7 @@
+ #include <linux/math64.h>
+ #include <linux/iio/buffer.h>
+-#include <linux/iio/common/inv_icm42600_timestamp.h>
++#include <linux/iio/common/inv_sensors_timestamp.h>
+ #include <linux/iio/iio.h>
+ #include <linux/iio/kfifo_buf.h>
+@@ -99,7 +99,7 @@ static int inv_icm42600_gyro_update_scan
+                                             const unsigned long *scan_mask)
+ {
+       struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+-      struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
++      struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
+       struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
+       unsigned int fifo_en = 0;
+       unsigned int sleep_gyro = 0;
+@@ -127,7 +127,7 @@ static int inv_icm42600_gyro_update_scan
+       }
+       /* update data FIFO write */
+-      inv_icm42600_timestamp_apply_odr(ts, 0, 0, 0);
++      inv_sensors_timestamp_apply_odr(ts, 0, 0, 0);
+       ret = inv_icm42600_buffer_set_fifo_en(st, fifo_en | st->fifo.en);
+ out_unlock:
+@@ -320,7 +320,7 @@ static int inv_icm42600_gyro_write_odr(s
+                                      int val, int val2)
+ {
+       struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+-      struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
++      struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
+       struct device *dev = regmap_get_device(st->map);
+       unsigned int idx;
+       struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
+@@ -341,8 +341,8 @@ static int inv_icm42600_gyro_write_odr(s
+       pm_runtime_get_sync(dev);
+       mutex_lock(&st->lock);
+-      ret = inv_icm42600_timestamp_update_odr(ts, inv_icm42600_odr_to_period(conf.odr),
+-                                              iio_buffer_enabled(indio_dev));
++      ret = inv_sensors_timestamp_update_odr(ts, inv_icm42600_odr_to_period(conf.odr),
++                                             iio_buffer_enabled(indio_dev));
+       if (ret)
+               goto out_unlock;
+@@ -717,7 +717,8 @@ struct iio_dev *inv_icm42600_gyro_init(s
+ {
+       struct device *dev = regmap_get_device(st->map);
+       const char *name;
+-      struct inv_icm42600_timestamp *ts;
++      struct inv_sensors_timestamp_chip ts_chip;
++      struct inv_sensors_timestamp *ts;
+       struct iio_dev *indio_dev;
+       struct iio_buffer *buffer;
+       int ret;
+@@ -734,8 +735,15 @@ struct iio_dev *inv_icm42600_gyro_init(s
+       if (!buffer)
+               return ERR_PTR(-ENOMEM);
++      /*
++       * clock period is 32kHz (31250ns)
++       * jitter is +/- 2% (20 per mille)
++       */
++      ts_chip.clock_period = 31250;
++      ts_chip.jitter = 20;
++      ts_chip.init_period = inv_icm42600_odr_to_period(st->conf.accel.odr);
+       ts = iio_priv(indio_dev);
+-      inv_icm42600_timestamp_init(ts, inv_icm42600_odr_to_period(st->conf.gyro.odr));
++      inv_sensors_timestamp_init(ts, &ts_chip);
+       iio_device_set_drvdata(indio_dev, st);
+       indio_dev->name = name;
+@@ -758,7 +766,7 @@ struct iio_dev *inv_icm42600_gyro_init(s
+ int inv_icm42600_gyro_parse_fifo(struct iio_dev *indio_dev)
+ {
+       struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+-      struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
++      struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
+       ssize_t i, size;
+       unsigned int no;
+       const void *accel, *gyro, *timestamp;
+@@ -782,13 +790,13 @@ int inv_icm42600_gyro_parse_fifo(struct
+               /* update odr */
+               if (odr & INV_ICM42600_SENSOR_GYRO)
+-                      inv_icm42600_timestamp_apply_odr(ts, st->fifo.period,
+-                                                       st->fifo.nb.total, no);
++                      inv_sensors_timestamp_apply_odr(ts, st->fifo.period,
++                                                      st->fifo.nb.total, no);
+               memcpy(&buffer.gyro, gyro, sizeof(buffer.gyro));
+               /* convert 8 bits FIFO temperature in high resolution format */
+               buffer.temp = temp ? (*temp * 64) : 0;
+-              ts_val = inv_icm42600_timestamp_pop(ts);
++              ts_val = inv_sensors_timestamp_pop(ts);
+               iio_push_to_buffers_with_timestamp(indio_dev, &buffer, ts_val);
+       }
+--- a/include/linux/iio/common/inv_icm42600_timestamp.h
++++ /dev/null
+@@ -1,79 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0-or-later */
+-/*
+- * Copyright (C) 2020 Invensense, Inc.
+- */
+-
+-#ifndef INV_ICM42600_TIMESTAMP_H_
+-#define INV_ICM42600_TIMESTAMP_H_
+-
+-/**
+- * struct inv_icm42600_timestamp_interval - timestamps interval
+- * @lo:       interval lower bound
+- * @up:       interval upper bound
+- */
+-struct inv_icm42600_timestamp_interval {
+-      int64_t lo;
+-      int64_t up;
+-};
+-
+-/**
+- * struct inv_icm42600_timestamp_acc - accumulator for computing an estimation
+- * @val:      current estimation of the value, the mean of all values
+- * @idx:      current index of the next free place in values table
+- * @values:   table of all measured values, use for computing the mean
+- */
+-struct inv_icm42600_timestamp_acc {
+-      uint32_t val;
+-      size_t idx;
+-      uint32_t values[32];
+-};
+-
+-/**
+- * struct inv_icm42600_timestamp - timestamp management states
+- * @it:                       interrupts interval timestamps
+- * @timestamp:                store last timestamp for computing next data timestamp
+- * @mult:             current internal period multiplier
+- * @new_mult:         new set internal period multiplier (not yet effective)
+- * @period:           measured current period of the sensor
+- * @chip_period:      accumulator for computing internal chip period
+- */
+-struct inv_icm42600_timestamp {
+-      struct inv_icm42600_timestamp_interval it;
+-      int64_t timestamp;
+-      uint32_t mult;
+-      uint32_t new_mult;
+-      uint32_t period;
+-      struct inv_icm42600_timestamp_acc chip_period;
+-};
+-
+-void inv_icm42600_timestamp_init(struct inv_icm42600_timestamp *ts,
+-                               uint32_t period);
+-
+-int inv_icm42600_timestamp_update_odr(struct inv_icm42600_timestamp *ts,
+-                                    uint32_t period, bool fifo);
+-
+-void inv_icm42600_timestamp_interrupt(struct inv_icm42600_timestamp *ts,
+-                                    uint32_t fifo_period, size_t fifo_nb,
+-                                    size_t sensor_nb, int64_t timestamp);
+-
+-static inline int64_t
+-inv_icm42600_timestamp_pop(struct inv_icm42600_timestamp *ts)
+-{
+-      ts->timestamp += ts->period;
+-      return ts->timestamp;
+-}
+-
+-void inv_icm42600_timestamp_apply_odr(struct inv_icm42600_timestamp *ts,
+-                                    uint32_t fifo_period, size_t fifo_nb,
+-                                    unsigned int fifo_no);
+-
+-static inline void
+-inv_icm42600_timestamp_reset(struct inv_icm42600_timestamp *ts)
+-{
+-      const struct inv_icm42600_timestamp_interval interval_init = {0LL, 0LL};
+-
+-      ts->it = interval_init;
+-      ts->timestamp = 0;
+-}
+-
+-#endif
+--- /dev/null
++++ b/include/linux/iio/common/inv_sensors_timestamp.h
+@@ -0,0 +1,95 @@
++/* SPDX-License-Identifier: GPL-2.0-or-later */
++/*
++ * Copyright (C) 2020 Invensense, Inc.
++ */
++
++#ifndef INV_SENSORS_TIMESTAMP_H_
++#define INV_SENSORS_TIMESTAMP_H_
++
++/**
++ * struct inv_sensors_timestamp_chip - chip internal properties
++ * @clock_period:     internal clock period in ns
++ * @jitter:           acceptable jitter in per-mille
++ * @init_period:      chip initial period at reset in ns
++ */
++struct inv_sensors_timestamp_chip {
++      uint32_t clock_period;
++      uint32_t jitter;
++      uint32_t init_period;
++};
++
++/**
++ * struct inv_sensors_timestamp_interval - timestamps interval
++ * @lo:       interval lower bound
++ * @up:       interval upper bound
++ */
++struct inv_sensors_timestamp_interval {
++      int64_t lo;
++      int64_t up;
++};
++
++/**
++ * struct inv_sensors_timestamp_acc - accumulator for computing an estimation
++ * @val:      current estimation of the value, the mean of all values
++ * @idx:      current index of the next free place in values table
++ * @values:   table of all measured values, use for computing the mean
++ */
++struct inv_sensors_timestamp_acc {
++      uint32_t val;
++      size_t idx;
++      uint32_t values[32];
++};
++
++/**
++ * struct inv_sensors_timestamp - timestamp management states
++ * @chip:             chip internal characteristics
++ * @min_period:               minimal acceptable clock period
++ * @max_period:               maximal acceptable clock period
++ * @it:                       interrupts interval timestamps
++ * @timestamp:                store last timestamp for computing next data timestamp
++ * @mult:             current internal period multiplier
++ * @new_mult:         new set internal period multiplier (not yet effective)
++ * @period:           measured current period of the sensor
++ * @chip_period:      accumulator for computing internal chip period
++ */
++struct inv_sensors_timestamp {
++      struct inv_sensors_timestamp_chip chip;
++      uint32_t min_period;
++      uint32_t max_period;
++      struct inv_sensors_timestamp_interval it;
++      int64_t timestamp;
++      uint32_t mult;
++      uint32_t new_mult;
++      uint32_t period;
++      struct inv_sensors_timestamp_acc chip_period;
++};
++
++void inv_sensors_timestamp_init(struct inv_sensors_timestamp *ts,
++                              const struct inv_sensors_timestamp_chip *chip);
++
++int inv_sensors_timestamp_update_odr(struct inv_sensors_timestamp *ts,
++                                   uint32_t period, bool fifo);
++
++void inv_sensors_timestamp_interrupt(struct inv_sensors_timestamp *ts,
++                                   uint32_t fifo_period, size_t fifo_nb,
++                                   size_t sensor_nb, int64_t timestamp);
++
++static inline int64_t inv_sensors_timestamp_pop(struct inv_sensors_timestamp *ts)
++{
++      ts->timestamp += ts->period;
++      return ts->timestamp;
++}
++
++void inv_sensors_timestamp_apply_odr(struct inv_sensors_timestamp *ts,
++                                   uint32_t fifo_period, size_t fifo_nb,
++                                   unsigned int fifo_no);
++
++static inline void inv_sensors_timestamp_reset(struct inv_sensors_timestamp *ts)
++{
++      const struct inv_sensors_timestamp_interval interval_init = {0LL, 0LL};
++
++      ts->it = interval_init;
++      ts->timestamp = 0;
++}
++
++#endif
diff --git a/queue-5.10/iio-move-inv_icm42600-timestamp-module-in-common.patch b/queue-5.10/iio-move-inv_icm42600-timestamp-module-in-common.patch
new file mode 100644 (file)
index 0000000..e43e03c
--- /dev/null
@@ -0,0 +1,741 @@
+From stable+bounces-274091-greg=kroah.com@vger.kernel.org Tue Jul 14 05:04:51 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:04:38 -0400
+Subject: iio: move inv_icm42600 timestamp module in common
+To: stable@vger.kernel.org
+Cc: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>, Andy Shevchenko <andy.shevchenko@gmail.com>, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714030444.2382550-2-sashal@kernel.org>
+
+From: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+
+[ Upstream commit d99ff463ecf651437e9e4abe68f331dfb6b5bd9d ]
+
+Create new inv_sensors common modules and move inv_icm42600
+timestamp module inside. This module will be used by IMUs and
+also in the future by other chips.
+
+Modify inv_icm42600 driver to use timestamp module and do some
+headers cleanup.
+
+Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20230606162147.79667-3-inv.git-commit@tdk.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: affe3f077d7a ("iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/common/Kconfig                            |  1 +
+ drivers/iio/common/Makefile                           |  1 +
+ drivers/iio/common/inv_sensors/Kconfig                |  7 +++++++
+ drivers/iio/common/inv_sensors/Makefile               |  6 ++++++
+ .../inv_sensors}/inv_icm42600_timestamp.c             | 11 ++++++++++-
+ drivers/iio/imu/inv_icm42600/Kconfig                  |  1 +
+ drivers/iio/imu/inv_icm42600/Makefile                 |  1 -
+ drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c     |  5 +++--
+ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c    |  5 +++--
+ drivers/iio/imu/inv_icm42600/inv_icm42600_core.c      |  4 +++-
+ drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c      |  5 +++--
+ .../linux/iio/common}/inv_icm42600_timestamp.h        |  0
+ drivers/iio/common/Kconfig                              |    1 
+ drivers/iio/common/Makefile                             |    1 
+ drivers/iio/common/inv_sensors/Kconfig                  |    7 
+ drivers/iio/common/inv_sensors/Makefile                 |    6 
+ drivers/iio/common/inv_sensors/inv_icm42600_timestamp.c |  192 ++++++++++++++++
+ drivers/iio/imu/inv_icm42600/Kconfig                    |    1 
+ drivers/iio/imu/inv_icm42600/Makefile                   |    1 
+ drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c       |    5 
+ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c      |    5 
+ drivers/iio/imu/inv_icm42600/inv_icm42600_core.c        |    4 
+ drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c        |    5 
+ drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.c   |  183 ---------------
+ drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.h   |   79 ------
+ include/linux/iio/common/inv_icm42600_timestamp.h       |   79 ++++++
+ 14 files changed, 299 insertions(+), 270 deletions(-)
+ create mode 100644 drivers/iio/common/inv_sensors/Kconfig
+ create mode 100644 drivers/iio/common/inv_sensors/Makefile
+ rename drivers/iio/{imu/inv_icm42600 => common/inv_sensors}/inv_icm42600_timestamp.c (91%)
+ rename {drivers/iio/imu/inv_icm42600 => include/linux/iio/common}/inv_icm42600_timestamp.h (100%)
+
+--- a/drivers/iio/common/Kconfig
++++ b/drivers/iio/common/Kconfig
+@@ -5,6 +5,7 @@
+ source "drivers/iio/common/cros_ec_sensors/Kconfig"
+ source "drivers/iio/common/hid-sensors/Kconfig"
++source "drivers/iio/common/inv_sensors/Kconfig"
+ source "drivers/iio/common/ms_sensors/Kconfig"
+ source "drivers/iio/common/ssp_sensors/Kconfig"
+ source "drivers/iio/common/st_sensors/Kconfig"
+--- a/drivers/iio/common/Makefile
++++ b/drivers/iio/common/Makefile
+@@ -10,6 +10,7 @@
+ # When adding new entries keep the list in alphabetical order
+ obj-y += cros_ec_sensors/
+ obj-y += hid-sensors/
++obj-y += inv_sensors/
+ obj-y += ms_sensors/
+ obj-y += ssp_sensors/
+ obj-y += st_sensors/
+--- /dev/null
++++ b/drivers/iio/common/inv_sensors/Kconfig
+@@ -0,0 +1,7 @@
++# SPDX-License-Identifier: GPL-2.0-only
++#
++# TDK-InvenSense sensors common library
++#
++
++config IIO_INV_SENSORS_TIMESTAMP
++      tristate
+--- /dev/null
++++ b/drivers/iio/common/inv_sensors/Makefile
+@@ -0,0 +1,6 @@
++# SPDX-License-Identifier: GPL-2.0
++#
++# Makefile for TDK-InvenSense sensors module.
++#
++
++obj-$(CONFIG_IIO_INV_SENSORS_TIMESTAMP) += inv_icm42600_timestamp.o
+--- /dev/null
++++ b/drivers/iio/common/inv_sensors/inv_icm42600_timestamp.c
+@@ -0,0 +1,192 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Copyright (C) 2020 Invensense, Inc.
++ */
++
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/math64.h>
++#include <linux/module.h>
++
++#include <linux/iio/common/inv_icm42600_timestamp.h>
++
++/* internal chip period is 32kHz, 31250ns */
++#define INV_ICM42600_TIMESTAMP_PERIOD         31250
++/* allow a jitter of +/- 2% */
++#define INV_ICM42600_TIMESTAMP_JITTER         2
++/* compute min and max periods accepted */
++#define INV_ICM42600_TIMESTAMP_MIN_PERIOD(_p)         \
++      (((_p) * (100 - INV_ICM42600_TIMESTAMP_JITTER)) / 100)
++#define INV_ICM42600_TIMESTAMP_MAX_PERIOD(_p)         \
++      (((_p) * (100 + INV_ICM42600_TIMESTAMP_JITTER)) / 100)
++
++/* Add a new value inside an accumulator and update the estimate value */
++static void inv_update_acc(struct inv_icm42600_timestamp_acc *acc, uint32_t val)
++{
++      uint64_t sum = 0;
++      size_t i;
++
++      acc->values[acc->idx++] = val;
++      if (acc->idx >= ARRAY_SIZE(acc->values))
++              acc->idx = 0;
++
++      /* compute the mean of all stored values, use 0 as empty slot */
++      for (i = 0; i < ARRAY_SIZE(acc->values); ++i) {
++              if (acc->values[i] == 0)
++                      break;
++              sum += acc->values[i];
++      }
++
++      acc->val = div_u64(sum, i);
++}
++
++void inv_icm42600_timestamp_init(struct inv_icm42600_timestamp *ts,
++                               uint32_t period)
++{
++      /* initial odr for sensor after reset is 1kHz */
++      const uint32_t default_period = 1000000;
++
++      /* current multiplier and period values after reset */
++      ts->mult = default_period / INV_ICM42600_TIMESTAMP_PERIOD;
++      ts->period = default_period;
++      /* new set multiplier is the one from chip initialization */
++      ts->new_mult = period / INV_ICM42600_TIMESTAMP_PERIOD;
++
++      /* use theoretical value for chip period */
++      inv_update_acc(&ts->chip_period, INV_ICM42600_TIMESTAMP_PERIOD);
++}
++EXPORT_SYMBOL_NS_GPL(inv_icm42600_timestamp_init, IIO_INV_SENSORS_TIMESTAMP);
++
++int inv_icm42600_timestamp_update_odr(struct inv_icm42600_timestamp *ts,
++                                    uint32_t period, bool fifo)
++{
++      /* when FIFO is on, prevent odr change if one is already pending */
++      if (fifo && ts->new_mult != 0)
++              return -EAGAIN;
++
++      ts->new_mult = period / INV_ICM42600_TIMESTAMP_PERIOD;
++
++      return 0;
++}
++EXPORT_SYMBOL_NS_GPL(inv_icm42600_timestamp_update_odr, IIO_INV_SENSORS_TIMESTAMP);
++
++static bool inv_validate_period(uint32_t period, uint32_t mult)
++{
++      const uint32_t chip_period = INV_ICM42600_TIMESTAMP_PERIOD;
++      uint32_t period_min, period_max;
++
++      /* check that period is acceptable */
++      period_min = INV_ICM42600_TIMESTAMP_MIN_PERIOD(chip_period) * mult;
++      period_max = INV_ICM42600_TIMESTAMP_MAX_PERIOD(chip_period) * mult;
++      if (period > period_min && period < period_max)
++              return true;
++      else
++              return false;
++}
++
++static bool inv_compute_chip_period(struct inv_icm42600_timestamp *ts,
++                                  uint32_t mult, uint32_t period)
++{
++      uint32_t new_chip_period;
++
++      if (!inv_validate_period(period, mult))
++              return false;
++
++      /* update chip internal period estimation */
++      new_chip_period = period / mult;
++      inv_update_acc(&ts->chip_period, new_chip_period);
++
++      return true;
++}
++
++void inv_icm42600_timestamp_interrupt(struct inv_icm42600_timestamp *ts,
++                                    uint32_t fifo_period, size_t fifo_nb,
++                                    size_t sensor_nb, int64_t timestamp)
++{
++      struct inv_icm42600_timestamp_interval *it;
++      int64_t delta, interval;
++      const uint32_t fifo_mult = fifo_period / INV_ICM42600_TIMESTAMP_PERIOD;
++      uint32_t period = ts->period;
++      int32_t m;
++      bool valid = false;
++
++      if (fifo_nb == 0)
++              return;
++
++      /* update interrupt timestamp and compute chip and sensor periods */
++      it = &ts->it;
++      it->lo = it->up;
++      it->up = timestamp;
++      delta = it->up - it->lo;
++      if (it->lo != 0) {
++              /* compute period: delta time divided by number of samples */
++              period = div_s64(delta, fifo_nb);
++              valid = inv_compute_chip_period(ts, fifo_mult, period);
++              /* update sensor period if chip internal period is updated */
++              if (valid)
++                      ts->period = ts->mult * ts->chip_period.val;
++      }
++
++      /* no previous data, compute theoritical value from interrupt */
++      if (ts->timestamp == 0) {
++              /* elapsed time: sensor period * sensor samples number */
++              interval = (int64_t)ts->period * (int64_t)sensor_nb;
++              ts->timestamp = it->up - interval;
++              return;
++      }
++
++      /* if interrupt interval is valid, sync with interrupt timestamp */
++      if (valid) {
++              /* compute measured fifo_period */
++              fifo_period = fifo_mult * ts->chip_period.val;
++              /* delta time between last sample and last interrupt */
++              delta = it->lo - ts->timestamp;
++              /* if there are multiple samples, go back to first one */
++              while (delta >= (fifo_period * 3 / 2))
++                      delta -= fifo_period;
++              /* compute maximal adjustment value */
++              m = INV_ICM42600_TIMESTAMP_MAX_PERIOD(ts->period) - ts->period;
++              if (delta > m)
++                      delta = m;
++              else if (delta < -m)
++                      delta = -m;
++              ts->timestamp += delta;
++      }
++}
++EXPORT_SYMBOL_NS_GPL(inv_icm42600_timestamp_interrupt, IIO_INV_SENSORS_TIMESTAMP);
++
++void inv_icm42600_timestamp_apply_odr(struct inv_icm42600_timestamp *ts,
++                                    uint32_t fifo_period, size_t fifo_nb,
++                                    unsigned int fifo_no)
++{
++      int64_t interval;
++      uint32_t fifo_mult;
++
++      if (ts->new_mult == 0)
++              return;
++
++      /* update to new multiplier and update period */
++      ts->mult = ts->new_mult;
++      ts->new_mult = 0;
++      ts->period = ts->mult * ts->chip_period.val;
++
++      /*
++       * After ODR change the time interval with the previous sample is
++       * undertermined (depends when the change occures). So we compute the
++       * timestamp from the current interrupt using the new FIFO period, the
++       * total number of samples and the current sample numero.
++       */
++      if (ts->timestamp != 0) {
++              /* compute measured fifo period */
++              fifo_mult = fifo_period / INV_ICM42600_TIMESTAMP_PERIOD;
++              fifo_period = fifo_mult * ts->chip_period.val;
++              /* computes time interval between interrupt and this sample */
++              interval = (int64_t)(fifo_nb - fifo_no) * (int64_t)fifo_period;
++              ts->timestamp = ts->it.up - interval;
++      }
++}
++EXPORT_SYMBOL_NS_GPL(inv_icm42600_timestamp_apply_odr, IIO_INV_SENSORS_TIMESTAMP);
++
++MODULE_AUTHOR("InvenSense, Inc.");
++MODULE_DESCRIPTION("InvenSense sensors timestamp module");
++MODULE_LICENSE("GPL");
+--- a/drivers/iio/imu/inv_icm42600/Kconfig
++++ b/drivers/iio/imu/inv_icm42600/Kconfig
+@@ -3,6 +3,7 @@
+ config INV_ICM42600
+       tristate
+       select IIO_BUFFER
++      select IIO_INV_SENSORS_TIMESTAMP
+ config INV_ICM42600_I2C
+       tristate "InvenSense ICM-426xx I2C driver"
+--- a/drivers/iio/imu/inv_icm42600/Makefile
++++ b/drivers/iio/imu/inv_icm42600/Makefile
+@@ -6,7 +6,6 @@ inv-icm42600-y += inv_icm42600_gyro.o
+ inv-icm42600-y += inv_icm42600_accel.o
+ inv-icm42600-y += inv_icm42600_temp.o
+ inv-icm42600-y += inv_icm42600_buffer.o
+-inv-icm42600-y += inv_icm42600_timestamp.o
+ obj-$(CONFIG_INV_ICM42600_I2C) += inv-icm42600-i2c.o
+ inv-icm42600-i2c-y += inv_icm42600_i2c.o
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
+@@ -10,14 +10,15 @@
+ #include <linux/regmap.h>
+ #include <linux/delay.h>
+ #include <linux/math64.h>
+-#include <linux/iio/iio.h>
++
+ #include <linux/iio/buffer.h>
++#include <linux/iio/common/inv_icm42600_timestamp.h>
++#include <linux/iio/iio.h>
+ #include <linux/iio/kfifo_buf.h>
+ #include "inv_icm42600.h"
+ #include "inv_icm42600_temp.h"
+ #include "inv_icm42600_buffer.h"
+-#include "inv_icm42600_timestamp.h"
+ #define INV_ICM42600_ACCEL_CHAN(_modifier, _index, _ext_info)         \
+       {                                                               \
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
+@@ -9,11 +9,12 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/regmap.h>
+ #include <linux/delay.h>
+-#include <linux/iio/iio.h>
++
+ #include <linux/iio/buffer.h>
++#include <linux/iio/common/inv_icm42600_timestamp.h>
++#include <linux/iio/iio.h>
+ #include "inv_icm42600.h"
+-#include "inv_icm42600_timestamp.h"
+ #include "inv_icm42600_buffer.h"
+ /* FIFO header: 1 byte */
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
+@@ -15,11 +15,12 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/property.h>
+ #include <linux/regmap.h>
++
++#include <linux/iio/common/inv_icm42600_timestamp.h>
+ #include <linux/iio/iio.h>
+ #include "inv_icm42600.h"
+ #include "inv_icm42600_buffer.h"
+-#include "inv_icm42600_timestamp.h"
+ static const struct regmap_range_cfg inv_icm42600_regmap_ranges[] = {
+       {
+@@ -798,3 +799,4 @@ EXPORT_SYMBOL_GPL(inv_icm42600_pm_ops);
+ MODULE_AUTHOR("InvenSense, Inc.");
+ MODULE_DESCRIPTION("InvenSense ICM-426xx device driver");
+ MODULE_LICENSE("GPL");
++MODULE_IMPORT_NS(IIO_INV_SENSORS_TIMESTAMP);
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
+@@ -10,14 +10,15 @@
+ #include <linux/regmap.h>
+ #include <linux/delay.h>
+ #include <linux/math64.h>
+-#include <linux/iio/iio.h>
++
+ #include <linux/iio/buffer.h>
++#include <linux/iio/common/inv_icm42600_timestamp.h>
++#include <linux/iio/iio.h>
+ #include <linux/iio/kfifo_buf.h>
+ #include "inv_icm42600.h"
+ #include "inv_icm42600_temp.h"
+ #include "inv_icm42600_buffer.h"
+-#include "inv_icm42600_timestamp.h"
+ #define INV_ICM42600_GYRO_CHAN(_modifier, _index, _ext_info)          \
+       {                                                               \
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.c
++++ /dev/null
+@@ -1,183 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0-or-later
+-/*
+- * Copyright (C) 2020 Invensense, Inc.
+- */
+-
+-#include <linux/errno.h>
+-#include <linux/kernel.h>
+-#include <linux/math64.h>
+-
+-#include "inv_icm42600_timestamp.h"
+-
+-/* internal chip period is 32kHz, 31250ns */
+-#define INV_ICM42600_TIMESTAMP_PERIOD         31250
+-/* allow a jitter of +/- 2% */
+-#define INV_ICM42600_TIMESTAMP_JITTER         2
+-/* compute min and max periods accepted */
+-#define INV_ICM42600_TIMESTAMP_MIN_PERIOD(_p)         \
+-      (((_p) * (100 - INV_ICM42600_TIMESTAMP_JITTER)) / 100)
+-#define INV_ICM42600_TIMESTAMP_MAX_PERIOD(_p)         \
+-      (((_p) * (100 + INV_ICM42600_TIMESTAMP_JITTER)) / 100)
+-
+-/* Add a new value inside an accumulator and update the estimate value */
+-static void inv_update_acc(struct inv_icm42600_timestamp_acc *acc, uint32_t val)
+-{
+-      uint64_t sum = 0;
+-      size_t i;
+-
+-      acc->values[acc->idx++] = val;
+-      if (acc->idx >= ARRAY_SIZE(acc->values))
+-              acc->idx = 0;
+-
+-      /* compute the mean of all stored values, use 0 as empty slot */
+-      for (i = 0; i < ARRAY_SIZE(acc->values); ++i) {
+-              if (acc->values[i] == 0)
+-                      break;
+-              sum += acc->values[i];
+-      }
+-
+-      acc->val = div_u64(sum, i);
+-}
+-
+-void inv_icm42600_timestamp_init(struct inv_icm42600_timestamp *ts,
+-                               uint32_t period)
+-{
+-      /* initial odr for sensor after reset is 1kHz */
+-      const uint32_t default_period = 1000000;
+-
+-      /* current multiplier and period values after reset */
+-      ts->mult = default_period / INV_ICM42600_TIMESTAMP_PERIOD;
+-      ts->period = default_period;
+-      /* new set multiplier is the one from chip initialization */
+-      ts->new_mult = period / INV_ICM42600_TIMESTAMP_PERIOD;
+-
+-      /* use theoretical value for chip period */
+-      inv_update_acc(&ts->chip_period, INV_ICM42600_TIMESTAMP_PERIOD);
+-}
+-
+-int inv_icm42600_timestamp_update_odr(struct inv_icm42600_timestamp *ts,
+-                                    uint32_t period, bool fifo)
+-{
+-      /* when FIFO is on, prevent odr change if one is already pending */
+-      if (fifo && ts->new_mult != 0)
+-              return -EAGAIN;
+-
+-      ts->new_mult = period / INV_ICM42600_TIMESTAMP_PERIOD;
+-
+-      return 0;
+-}
+-
+-static bool inv_validate_period(uint32_t period, uint32_t mult)
+-{
+-      const uint32_t chip_period = INV_ICM42600_TIMESTAMP_PERIOD;
+-      uint32_t period_min, period_max;
+-
+-      /* check that period is acceptable */
+-      period_min = INV_ICM42600_TIMESTAMP_MIN_PERIOD(chip_period) * mult;
+-      period_max = INV_ICM42600_TIMESTAMP_MAX_PERIOD(chip_period) * mult;
+-      if (period > period_min && period < period_max)
+-              return true;
+-      else
+-              return false;
+-}
+-
+-static bool inv_compute_chip_period(struct inv_icm42600_timestamp *ts,
+-                                  uint32_t mult, uint32_t period)
+-{
+-      uint32_t new_chip_period;
+-
+-      if (!inv_validate_period(period, mult))
+-              return false;
+-
+-      /* update chip internal period estimation */
+-      new_chip_period = period / mult;
+-      inv_update_acc(&ts->chip_period, new_chip_period);
+-
+-      return true;
+-}
+-
+-void inv_icm42600_timestamp_interrupt(struct inv_icm42600_timestamp *ts,
+-                                    uint32_t fifo_period, size_t fifo_nb,
+-                                    size_t sensor_nb, int64_t timestamp)
+-{
+-      struct inv_icm42600_timestamp_interval *it;
+-      int64_t delta, interval;
+-      const uint32_t fifo_mult = fifo_period / INV_ICM42600_TIMESTAMP_PERIOD;
+-      uint32_t period = ts->period;
+-      int32_t m;
+-      bool valid = false;
+-
+-      if (fifo_nb == 0)
+-              return;
+-
+-      /* update interrupt timestamp and compute chip and sensor periods */
+-      it = &ts->it;
+-      it->lo = it->up;
+-      it->up = timestamp;
+-      delta = it->up - it->lo;
+-      if (it->lo != 0) {
+-              /* compute period: delta time divided by number of samples */
+-              period = div_s64(delta, fifo_nb);
+-              valid = inv_compute_chip_period(ts, fifo_mult, period);
+-              /* update sensor period if chip internal period is updated */
+-              if (valid)
+-                      ts->period = ts->mult * ts->chip_period.val;
+-      }
+-
+-      /* no previous data, compute theoritical value from interrupt */
+-      if (ts->timestamp == 0) {
+-              /* elapsed time: sensor period * sensor samples number */
+-              interval = (int64_t)ts->period * (int64_t)sensor_nb;
+-              ts->timestamp = it->up - interval;
+-              return;
+-      }
+-
+-      /* if interrupt interval is valid, sync with interrupt timestamp */
+-      if (valid) {
+-              /* compute measured fifo_period */
+-              fifo_period = fifo_mult * ts->chip_period.val;
+-              /* delta time between last sample and last interrupt */
+-              delta = it->lo - ts->timestamp;
+-              /* if there are multiple samples, go back to first one */
+-              while (delta >= (fifo_period * 3 / 2))
+-                      delta -= fifo_period;
+-              /* compute maximal adjustment value */
+-              m = INV_ICM42600_TIMESTAMP_MAX_PERIOD(ts->period) - ts->period;
+-              if (delta > m)
+-                      delta = m;
+-              else if (delta < -m)
+-                      delta = -m;
+-              ts->timestamp += delta;
+-      }
+-}
+-
+-void inv_icm42600_timestamp_apply_odr(struct inv_icm42600_timestamp *ts,
+-                                    uint32_t fifo_period, size_t fifo_nb,
+-                                    unsigned int fifo_no)
+-{
+-      int64_t interval;
+-      uint32_t fifo_mult;
+-
+-      if (ts->new_mult == 0)
+-              return;
+-
+-      /* update to new multiplier and update period */
+-      ts->mult = ts->new_mult;
+-      ts->new_mult = 0;
+-      ts->period = ts->mult * ts->chip_period.val;
+-
+-      /*
+-       * After ODR change the time interval with the previous sample is
+-       * undertermined (depends when the change occures). So we compute the
+-       * timestamp from the current interrupt using the new FIFO period, the
+-       * total number of samples and the current sample numero.
+-       */
+-      if (ts->timestamp != 0) {
+-              /* compute measured fifo period */
+-              fifo_mult = fifo_period / INV_ICM42600_TIMESTAMP_PERIOD;
+-              fifo_period = fifo_mult * ts->chip_period.val;
+-              /* computes time interval between interrupt and this sample */
+-              interval = (int64_t)(fifo_nb - fifo_no) * (int64_t)fifo_period;
+-              ts->timestamp = ts->it.up - interval;
+-      }
+-}
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.h
++++ /dev/null
+@@ -1,79 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0-or-later */
+-/*
+- * Copyright (C) 2020 Invensense, Inc.
+- */
+-
+-#ifndef INV_ICM42600_TIMESTAMP_H_
+-#define INV_ICM42600_TIMESTAMP_H_
+-
+-/**
+- * struct inv_icm42600_timestamp_interval - timestamps interval
+- * @lo:       interval lower bound
+- * @up:       interval upper bound
+- */
+-struct inv_icm42600_timestamp_interval {
+-      int64_t lo;
+-      int64_t up;
+-};
+-
+-/**
+- * struct inv_icm42600_timestamp_acc - accumulator for computing an estimation
+- * @val:      current estimation of the value, the mean of all values
+- * @idx:      current index of the next free place in values table
+- * @values:   table of all measured values, use for computing the mean
+- */
+-struct inv_icm42600_timestamp_acc {
+-      uint32_t val;
+-      size_t idx;
+-      uint32_t values[32];
+-};
+-
+-/**
+- * struct inv_icm42600_timestamp - timestamp management states
+- * @it:                       interrupts interval timestamps
+- * @timestamp:                store last timestamp for computing next data timestamp
+- * @mult:             current internal period multiplier
+- * @new_mult:         new set internal period multiplier (not yet effective)
+- * @period:           measured current period of the sensor
+- * @chip_period:      accumulator for computing internal chip period
+- */
+-struct inv_icm42600_timestamp {
+-      struct inv_icm42600_timestamp_interval it;
+-      int64_t timestamp;
+-      uint32_t mult;
+-      uint32_t new_mult;
+-      uint32_t period;
+-      struct inv_icm42600_timestamp_acc chip_period;
+-};
+-
+-void inv_icm42600_timestamp_init(struct inv_icm42600_timestamp *ts,
+-                               uint32_t period);
+-
+-int inv_icm42600_timestamp_update_odr(struct inv_icm42600_timestamp *ts,
+-                                    uint32_t period, bool fifo);
+-
+-void inv_icm42600_timestamp_interrupt(struct inv_icm42600_timestamp *ts,
+-                                    uint32_t fifo_period, size_t fifo_nb,
+-                                    size_t sensor_nb, int64_t timestamp);
+-
+-static inline int64_t
+-inv_icm42600_timestamp_pop(struct inv_icm42600_timestamp *ts)
+-{
+-      ts->timestamp += ts->period;
+-      return ts->timestamp;
+-}
+-
+-void inv_icm42600_timestamp_apply_odr(struct inv_icm42600_timestamp *ts,
+-                                    uint32_t fifo_period, size_t fifo_nb,
+-                                    unsigned int fifo_no);
+-
+-static inline void
+-inv_icm42600_timestamp_reset(struct inv_icm42600_timestamp *ts)
+-{
+-      const struct inv_icm42600_timestamp_interval interval_init = {0LL, 0LL};
+-
+-      ts->it = interval_init;
+-      ts->timestamp = 0;
+-}
+-
+-#endif
+--- /dev/null
++++ b/include/linux/iio/common/inv_icm42600_timestamp.h
+@@ -0,0 +1,79 @@
++/* SPDX-License-Identifier: GPL-2.0-or-later */
++/*
++ * Copyright (C) 2020 Invensense, Inc.
++ */
++
++#ifndef INV_ICM42600_TIMESTAMP_H_
++#define INV_ICM42600_TIMESTAMP_H_
++
++/**
++ * struct inv_icm42600_timestamp_interval - timestamps interval
++ * @lo:       interval lower bound
++ * @up:       interval upper bound
++ */
++struct inv_icm42600_timestamp_interval {
++      int64_t lo;
++      int64_t up;
++};
++
++/**
++ * struct inv_icm42600_timestamp_acc - accumulator for computing an estimation
++ * @val:      current estimation of the value, the mean of all values
++ * @idx:      current index of the next free place in values table
++ * @values:   table of all measured values, use for computing the mean
++ */
++struct inv_icm42600_timestamp_acc {
++      uint32_t val;
++      size_t idx;
++      uint32_t values[32];
++};
++
++/**
++ * struct inv_icm42600_timestamp - timestamp management states
++ * @it:                       interrupts interval timestamps
++ * @timestamp:                store last timestamp for computing next data timestamp
++ * @mult:             current internal period multiplier
++ * @new_mult:         new set internal period multiplier (not yet effective)
++ * @period:           measured current period of the sensor
++ * @chip_period:      accumulator for computing internal chip period
++ */
++struct inv_icm42600_timestamp {
++      struct inv_icm42600_timestamp_interval it;
++      int64_t timestamp;
++      uint32_t mult;
++      uint32_t new_mult;
++      uint32_t period;
++      struct inv_icm42600_timestamp_acc chip_period;
++};
++
++void inv_icm42600_timestamp_init(struct inv_icm42600_timestamp *ts,
++                               uint32_t period);
++
++int inv_icm42600_timestamp_update_odr(struct inv_icm42600_timestamp *ts,
++                                    uint32_t period, bool fifo);
++
++void inv_icm42600_timestamp_interrupt(struct inv_icm42600_timestamp *ts,
++                                    uint32_t fifo_period, size_t fifo_nb,
++                                    size_t sensor_nb, int64_t timestamp);
++
++static inline int64_t
++inv_icm42600_timestamp_pop(struct inv_icm42600_timestamp *ts)
++{
++      ts->timestamp += ts->period;
++      return ts->timestamp;
++}
++
++void inv_icm42600_timestamp_apply_odr(struct inv_icm42600_timestamp *ts,
++                                    uint32_t fifo_period, size_t fifo_nb,
++                                    unsigned int fifo_no);
++
++static inline void
++inv_icm42600_timestamp_reset(struct inv_icm42600_timestamp *ts)
++{
++      const struct inv_icm42600_timestamp_interval interval_init = {0LL, 0LL};
++
++      ts->it = interval_init;
++      ts->timestamp = 0;
++}
++
++#endif
diff --git a/queue-5.10/leds-lm3601x-improve-error-reporting-for-problems-during-.remove.patch b/queue-5.10/leds-lm3601x-improve-error-reporting-for-problems-during-.remove.patch
new file mode 100644 (file)
index 0000000..d5e0a79
--- /dev/null
@@ -0,0 +1,54 @@
+From stable+bounces-277537-greg=kroah.com@vger.kernel.org Mon Jul 20 04:35:49 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 22:35:37 -0400
+Subject: leds: lm3601x: Improve error reporting for problems during .remove()
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>, "Pavel Machek" <pavel@ucw.cz>, "Wolfram Sang" <wsa@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260720023539.2968115-3-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 22a23436891886a66d21af3619f4a4e8809f0e0a ]
+
+Returning an error value in an i2c remove callback results in a generic
+error message being emitted by the i2c core, but otherwise it doesn't
+make a difference. The device goes away anyhow and the devm cleanups are
+called.
+
+So instead of triggering the generic i2c error message, emit a more
+helpful message if a problem occurs and return 0 to suppress the generic
+message.
+
+This patch is a preparation for making i2c remove callbacks return void.
+
+Acked-by: Pavel Machek <pavel@ucw.cz>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Stable-dep-of: 1f0bdc2884b6 ("usb: typec: ucsi: ccg: Fix use-after-free of ucsi on remove")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/leds/leds-lm3601x.c |   11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/leds/leds-lm3601x.c
++++ b/drivers/leds/leds-lm3601x.c
+@@ -443,10 +443,15 @@ static int lm3601x_probe(struct i2c_clie
+ static int lm3601x_remove(struct i2c_client *client)
+ {
+       struct lm3601x_led *led = i2c_get_clientdata(client);
++      int ret;
+-      return regmap_update_bits(led->regmap, LM3601X_ENABLE_REG,
+-                         LM3601X_ENABLE_MASK,
+-                         LM3601X_MODE_STANDBY);
++      ret = regmap_update_bits(led->regmap, LM3601X_ENABLE_REG,
++                               LM3601X_ENABLE_MASK, LM3601X_MODE_STANDBY);
++      if (ret)
++              dev_warn(&client->dev,
++                       "Failed to put into standby (%pe)\n", ERR_PTR(ret));
++
++      return 0;
+ }
+ static const struct i2c_device_id lm3601x_id[] = {
diff --git a/queue-5.10/leds-lm3697-remove-duplicated-error-reporting-in-.remove.patch b/queue-5.10/leds-lm3697-remove-duplicated-error-reporting-in-.remove.patch
new file mode 100644 (file)
index 0000000..362383c
--- /dev/null
@@ -0,0 +1,48 @@
+From stable+bounces-277536-greg=kroah.com@vger.kernel.org Mon Jul 20 04:35:48 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 22:35:36 -0400
+Subject: leds: lm3697: Remove duplicated error reporting in .remove()
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>, "Pavel Machek" <pavel@ucw.cz>, "Wolfram Sang" <wsa@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260720023539.2968115-2-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit af89fa11fae1cee4e07453f780e6e5573ef0f477 ]
+
+Returning an error value from an i2c remove callback results in an error
+message being emitted by the i2c core, but otherwise it doesn't make a
+difference. The device goes away anyhow and the devm cleanups are
+called.
+
+As lm3697_remove() already emits an error message on failure and the
+additional error message by the i2c core doesn't add any useful
+information, don't pass the error value up the stack. Instead continue
+to clean up and return 0.
+
+This patch is a preparation for making i2c remove callbacks return void.
+
+Acked-by: Pavel Machek <pavel@ucw.cz>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Stable-dep-of: 1f0bdc2884b6 ("usb: typec: ucsi: ccg: Fix use-after-free of ucsi on remove")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/leds/leds-lm3697.c |    4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/drivers/leds/leds-lm3697.c
++++ b/drivers/leds/leds-lm3697.c
+@@ -337,10 +337,8 @@ static int lm3697_remove(struct i2c_clie
+       ret = regmap_update_bits(led->regmap, LM3697_CTRL_ENABLE,
+                                LM3697_CTRL_A_B_EN, 0);
+-      if (ret) {
++      if (ret)
+               dev_err(dev, "Failed to disable the device\n");
+-              return ret;
+-      }
+       if (led->enable_gpio)
+               gpiod_direction_output(led->enable_gpio, 0);
diff --git a/queue-5.10/media-atomisp-replace-boolean-comparison-of-values-with-bool-variables.patch b/queue-5.10/media-atomisp-replace-boolean-comparison-of-values-with-bool-variables.patch
new file mode 100644 (file)
index 0000000..35035ac
--- /dev/null
@@ -0,0 +1,153 @@
+From stable+bounces-274527-greg=kroah.com@vger.kernel.org Tue Jul 14 22:02:12 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 16:01:53 -0400
+Subject: media: atomisp: replace boolean comparison of values with bool variables
+To: stable@vger.kernel.org
+Cc: Aditya Srivastava <yashsri421@gmail.com>, Mauro Carvalho Chehab <mchehab+huawei@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714200158.3152137-1-sashal@kernel.org>
+
+From: Aditya Srivastava <yashsri421@gmail.com>
+
+[ Upstream commit c606970d4250dfb95869a563975c08bab148137a ]
+
+There are certain expressions in a condition in atomisp, where a boolean
+variable is compared with true/false in forms such as (foo == true)
+or (false != bar), which does not comply with the coding style rule by
+checkpatch.pl (CHK: BOOL_COMPARISON), according to which the boolean
+variables should be themselves used in the condition, rather than
+comparing with true or false.
+
+E.g. In drivers/staging/media/atomisp/pci/atomisp_compat_css20.c:
+
+if (asd->stream_prepared == false) {
+
+Can be replaced with:
+if (!asd->stream_prepared) {
+
+Replace such expressions with boolean variables appropriately.
+
+Link: https://lore.kernel.org/linux-media/20201214132716.28157-1-yashsri421@gmail.com
+Signed-off-by: Aditya Srivastava <yashsri421@gmail.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: f4d51e55dd47 ("staging: media: atomisp: reduce load_primary_binaries() stack usage")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/media/atomisp/pci/atomisp_compat_css20.c          |    2 -
+ drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c |   12 +++++-----
+ drivers/staging/media/atomisp/pci/sh_css.c                        |   12 +++++-----
+ 3 files changed, 13 insertions(+), 13 deletions(-)
+
+--- a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c
++++ b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c
+@@ -1142,7 +1142,7 @@ int atomisp_css_start(struct atomisp_sub
+        * Thus the stream created in set_fmt get destroyed and need to be
+        * recreated in the next stream on.
+        */
+-      if (asd->stream_prepared == false) {
++      if (!asd->stream_prepared) {
+               if (__create_pipes(asd)) {
+                       dev_err(isp->dev, "create pipe error.\n");
+                       return -EINVAL;
+--- a/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c
++++ b/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c
+@@ -179,12 +179,12 @@ ia_css_isys_error_t ia_css_isys_stream_c
+       isys_stream->linked_isys_stream_id = isys_stream_descr->linked_isys_stream_id;
+       rc = create_input_system_input_port(isys_stream_descr,
+                                           &isys_stream->input_port);
+-      if (rc == false)
++      if (!rc)
+               return false;
+       rc = create_input_system_channel(isys_stream_descr, false,
+                                        &isys_stream->channel);
+-      if (rc == false) {
++      if (!rc) {
+               destroy_input_system_input_port(&isys_stream->input_port);
+               return false;
+       }
+@@ -204,7 +204,7 @@ ia_css_isys_error_t ia_css_isys_stream_c
+       if (isys_stream_descr->metadata.enable) {
+               rc = create_input_system_channel(isys_stream_descr, true,
+                                                &isys_stream->md_channel);
+-              if (rc == false) {
++              if (!rc) {
+                       destroy_input_system_input_port(&isys_stream->input_port);
+                       destroy_input_system_channel(&isys_stream->channel);
+                       return false;
+@@ -248,7 +248,7 @@ ia_css_isys_error_t ia_css_isys_stream_c
+                 isys_stream_descr,
+                 &isys_stream_cfg->channel_cfg,
+                 false);
+-      if (rc == false)
++      if (!rc)
+               return false;
+       /* configure metadata channel */
+@@ -260,7 +260,7 @@ ia_css_isys_error_t ia_css_isys_stream_c
+                         isys_stream_descr,
+                         &isys_stream_cfg->md_channel_cfg,
+                         true);
+-              if (rc == false)
++              if (!rc)
+                       return false;
+       }
+@@ -269,7 +269,7 @@ ia_css_isys_error_t ia_css_isys_stream_c
+                &isys_stream->input_port,
+                isys_stream_descr,
+                &isys_stream_cfg->input_port_cfg);
+-      if (rc == false)
++      if (!rc)
+               return false;
+       isys_stream->valid = 1;
+--- a/drivers/staging/media/atomisp/pci/sh_css.c
++++ b/drivers/staging/media/atomisp/pci/sh_css.c
+@@ -1058,7 +1058,7 @@ sh_css_config_input_network(struct ia_cs
+       ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
+                           "sh_css_config_input_network() enter 0x%p:\n", stream);
+-      if (stream->config.continuous == true)
++      if (stream->config.continuous)
+       {
+               if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE) {
+                       pipe = stream->last_pipe;
+@@ -5622,7 +5622,7 @@ static int load_video_binaries(struct ia
+               } else {
+                       /* output from main binary is not yuv line. currently this is
+                        * possible only when bci is enabled on vfpp output */
+-                      assert(pipe->config.enable_vfpp_bci == true);
++                      assert(pipe->config.enable_vfpp_bci);
+                       ia_css_pipe_get_yuvscaler_binarydesc(pipe, &vf_pp_descr,
+                                                            &mycs->video_binary.vf_frame_info,
+                                                            pipe_vf_out_info, NULL, NULL);
+@@ -8068,7 +8068,7 @@ create_host_regular_capture_pipeline(str
+               struct ia_css_frame *tmp_out_frame = NULL;
+               for (i = 0; i < num_yuv_scaler; i++) {
+-                      if (is_output_stage[i] == true)
++                      if (is_output_stage[i])
+                               tmp_out_frame = out_frame;
+                       else
+                               tmp_out_frame = NULL;
+@@ -8460,7 +8460,7 @@ sh_css_pipeline_add_acc_stage(struct ia_
+       /* In QoS case, load_extension already called, so skipping */
+       int     err = 0;
+-      if (fw->loaded == false)
++      if (!fw->loaded)
+               err = acc_load_extension(fw);
+       ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
+@@ -9697,8 +9697,8 @@ ia_css_stream_destroy(struct ia_css_stre
+                       assert(entry);
+                       if (entry) {
+                               /* get the SP thread id */
+-                              if (ia_css_pipeline_get_sp_thread_id(
+-                                      ia_css_pipe_get_pipe_num(entry), &sp_thread_id) != true)
++                              if (!ia_css_pipeline_get_sp_thread_id(
++                                      ia_css_pipe_get_pipe_num(entry), &sp_thread_id))
+                                       return -EINVAL;
+                               /* get the target input terminal */
+                               sp_pipeline_input_terminal =
diff --git a/queue-5.10/media-staging-media-atomisp-fix-alignment-and-line-length-issues.patch b/queue-5.10/media-staging-media-atomisp-fix-alignment-and-line-length-issues.patch
new file mode 100644 (file)
index 0000000..a242b43
--- /dev/null
@@ -0,0 +1,1519 @@
+From stable+bounces-274531-greg=kroah.com@vger.kernel.org Tue Jul 14 22:02:33 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 16:01:57 -0400
+Subject: media: staging: media: atomisp: Fix alignment and line length issues
+To: stable@vger.kernel.org
+Cc: Martiros Shakhzadyan <vrzh@vrzh.net>, Hans Verkuil <hverkuil-cisco@xs4all.nl>, Mauro Carvalho Chehab <mchehab+huawei@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714200158.3152137-5-sashal@kernel.org>
+
+From: Martiros Shakhzadyan <vrzh@vrzh.net>
+
+[ Upstream commit 7796e455170efa1823457b17a292b1c65bb8c1e0 ]
+
+Fix alignment style issues and adjacent line length issues in sh_css.c
+
+Signed-off-by: Martiros Shakhzadyan <vrzh@vrzh.net>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: f4d51e55dd47 ("staging: media: atomisp: reduce load_primary_binaries() stack usage")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/media/atomisp/pci/sh_css.c |  619 +++++++++++++++--------------
+ 1 file changed, 333 insertions(+), 286 deletions(-)
+
+--- a/drivers/staging/media/atomisp/pci/sh_css.c
++++ b/drivers/staging/media/atomisp/pci/sh_css.c
+@@ -242,8 +242,8 @@ ia_css_reset_defaults(struct sh_css *css
+ static void
+ sh_css_init_host_sp_control_vars(void);
+-static int set_num_primary_stages(unsigned int *num,
+-      enum ia_css_pipe_version version);
++static int
++set_num_primary_stages(unsigned int *num, enum ia_css_pipe_version version);
+ static bool
+ need_capture_pp(const struct ia_css_pipe *pipe);
+@@ -3002,9 +3002,8 @@ static int add_firmwares(
+               ia_css_pipe_get_firmwares_stage_desc(&stage_desc, binary,
+                                                    out, in, vf, fw, binary_mode);
+-              err = ia_css_pipeline_create_and_add_stage(me,
+-                      &stage_desc,
+-                      &extra_stage);
++              err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++                                                         &extra_stage);
+               if (err)
+                       return err;
+               if (fw->info.isp.sp.enable.output != 0)
+@@ -3112,9 +3111,8 @@ static int add_yuv_scaler_stage(
+               ia_css_pipe_get_generic_stage_desc(&stage_desc,
+                                                  yuv_scaler_binary, out_frames, in_frame, vf_frame);
+       }
+-      err = ia_css_pipeline_create_and_add_stage(me,
+-              &stage_desc,
+-              pre_vf_pp_stage);
++      err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++                                                 pre_vf_pp_stage);
+       if (err)
+               return err;
+       in_frame = (*pre_vf_pp_stage)->args.out_frame[0];
+@@ -3172,9 +3170,8 @@ static int add_capture_pp_stage(
+               ia_css_pipe_get_generic_stage_desc(&stage_desc,
+                                                  capture_pp_binary, out_frames, NULL, vf_frame);
+       }
+-      err = ia_css_pipeline_create_and_add_stage(me,
+-              &stage_desc,
+-              capture_pp_stage);
++      err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++                                                 capture_pp_stage);
+       if (err)
+               return err;
+       err = add_firmwares(me, capture_pp_binary, pipe->output_stage, last_fw,
+@@ -3529,9 +3526,8 @@ static int create_host_video_pipeline(st
+               ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
+               ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
+                                                  out_frames, NULL, NULL);
+-              err = ia_css_pipeline_create_and_add_stage(me,
+-                      &stage_desc,
+-                      &copy_stage);
++              err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++                                                         &copy_stage);
+               if (err)
+                       goto ERR;
+               in_frame = me->stages->args.out_frame[0];
+@@ -3558,9 +3554,8 @@ static int create_host_video_pipeline(st
+               ia_css_pipe_get_generic_stage_desc(&stage_desc, video_binary,
+                                                  out_frames, in_frame, vf_frame);
+       }
+-      err = ia_css_pipeline_create_and_add_stage(me,
+-              &stage_desc,
+-              &video_stage);
++      err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++                                                 &video_stage);
+       if (err)
+               goto ERR;
+@@ -3625,8 +3620,8 @@ static int create_host_video_pipeline(st
+               for (i = 0; i < num_yuv_scaler; i++) {
+                       tmp_out_frame = is_output_stage[i] ? out_frame : NULL;
+-                      err = add_yuv_scaler_stage(pipe, me, tmp_in_frame, tmp_out_frame,
+-                                                 NULL,
++                      err = add_yuv_scaler_stage(pipe, me, tmp_in_frame,
++                                                 tmp_out_frame, NULL,
+                                                  &yuv_scaler_binary[i],
+                                                  &yuv_scaler_stage);
+@@ -3765,9 +3760,8 @@ create_host_preview_pipeline(struct ia_c
+               ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
+               ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
+                                                  out_frames, NULL, NULL);
+-              err = ia_css_pipeline_create_and_add_stage(me,
+-                      &stage_desc,
+-                      &copy_stage);
++              err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++                                                         &copy_stage);
+               if (err)
+                       goto ERR;
+               in_frame = me->stages->args.out_frame[0];
+@@ -3793,9 +3787,8 @@ create_host_preview_pipeline(struct ia_c
+               ia_css_pipe_get_generic_stage_desc(&stage_desc, preview_binary,
+                                                  out_frames, in_frame, NULL);
+       }
+-      err = ia_css_pipeline_create_and_add_stage(me,
+-              &stage_desc,
+-              &preview_stage);
++      err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++                                                 &preview_stage);
+       if (err)
+               goto ERR;
+       /* If we use copy iso preview, the input must be yuv iso raw */
+@@ -4131,8 +4124,8 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+       }
+       hmm_store(h_vbuf->vptr,
+-                 (void *)(&ddr_buffer),
+-                 sizeof(struct sh_css_hmm_buffer));
++                (void *)(&ddr_buffer),
++                sizeof(struct sh_css_hmm_buffer));
+       if ((buf_type == IA_CSS_BUFFER_TYPE_3A_STATISTICS)
+           || (buf_type == IA_CSS_BUFFER_TYPE_DIS_STATISTICS)
+           || (buf_type == IA_CSS_BUFFER_TYPE_LACE_STATISTICS)) {
+@@ -4293,8 +4286,8 @@ ia_css_pipe_dequeue_buffer(struct ia_css
+               }
+               hmm_load(ddr_buffer_addr,
+-                        &ddr_buffer,
+-                        sizeof(struct sh_css_hmm_buffer));
++                       &ddr_buffer,
++                       sizeof(struct sh_css_hmm_buffer));
+               /* if the kernel_ptr is 0 or an invalid, return an error.
+                * do not access the buffer via the kernal_ptr.
+@@ -4949,7 +4942,7 @@ sh_css_pipes_stop(struct ia_css_stream *
+       for (i = 0; i < stream->num_pipes; i++) {
+               /* send the "stop" request to the "ia_css_pipe" instance */
+               IA_CSS_LOG("Send the stop-request to the pipe: pipe_id=%d",
+-                      stream->pipes[i]->pipeline.pipe_id);
++                         stream->pipes[i]->pipeline.pipe_id);
+               err = ia_css_pipeline_request_stop(&stream->pipes[i]->pipeline);
+               /*
+@@ -4999,7 +4992,7 @@ sh_css_pipes_stop(struct ia_css_stream *
+               /* send the "stop" request to "Copy Pipe" */
+               IA_CSS_LOG("Send the stop-request to the pipe: pipe_id=%d",
+-                      copy_pipe->pipeline.pipe_id);
++                         copy_pipe->pipeline.pipe_id);
+               err = ia_css_pipeline_request_stop(&copy_pipe->pipeline);
+       }
+@@ -5832,7 +5825,7 @@ static bool need_capt_ldc(
+ }
+ static int set_num_primary_stages(unsigned int *num,
+-      enum ia_css_pipe_version version)
++                                enum ia_css_pipe_version version)
+ {
+       int err = 0;
+@@ -6032,10 +6025,13 @@ static int load_primary_binaries(
+                       capt_pp_in_info = &prim_out_info;
+               ia_css_pipe_get_capturepp_binarydesc(pipe,
+-                                                      &capture_pp_descr, capt_pp_in_info,
+-                                                      &capt_pp_out_info, &vf_info);
++                                                   &capture_pp_descr,
++                                                   capt_pp_in_info,
++                                                   &capt_pp_out_info,
++                                                   &vf_info);
++
+               err = ia_css_binary_find(&capture_pp_descr,
+-                                          &mycs->capture_pp_binary);
++                                       &mycs->capture_pp_binary);
+               if (err) {
+                       IA_CSS_LEAVE_ERR_PRIVATE(err);
+                       return err;
+@@ -6045,11 +6041,12 @@ static int load_primary_binaries(
+                       struct ia_css_binary_descr capt_ldc_descr;
+                       ia_css_pipe_get_ldc_binarydesc(pipe,
+-                                                      &capt_ldc_descr, &prim_out_info,
+-                                                      &capt_ldc_out_info);
++                                                     &capt_ldc_descr,
++                                                     &prim_out_info,
++                                                     &capt_ldc_out_info);
+                       err = ia_css_binary_find(&capt_ldc_descr,
+-                                                  &mycs->capture_ldc_binary);
++                                               &mycs->capture_ldc_binary);
+                       if (err) {
+                               IA_CSS_LEAVE_ERR_PRIVATE(err);
+                               return err;
+@@ -6066,8 +6063,9 @@ static int load_primary_binaries(
+               if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0] &&
+                   (i == mycs->num_primary_stage - 1))
+                       local_vf_info = &vf_info;
+-              ia_css_pipe_get_primary_binarydesc(pipe, &prim_descr[i], &prim_in_info,
+-                                                  &prim_out_info, local_vf_info, i);
++              ia_css_pipe_get_primary_binarydesc(pipe, &prim_descr[i],
++                                                 &prim_in_info, &prim_out_info,
++                                                 local_vf_info, i);
+               err = ia_css_binary_find(&prim_descr[i], &mycs->primary_binary[i]);
+               if (err) {
+                       IA_CSS_LEAVE_ERR_PRIVATE(err);
+@@ -6119,8 +6117,8 @@ static int load_primary_binaries(
+       /* ISP Copy */
+       if (need_isp_copy_binary) {
+               err = load_copy_binary(pipe,
+-                                      &mycs->copy_binary,
+-                                      &mycs->primary_binary[0]);
++                                     &mycs->copy_binary,
++                                     &mycs->primary_binary[0]);
+               if (err) {
+                       IA_CSS_LEAVE_ERR_PRIVATE(err);
+                       return err;
+@@ -6229,7 +6227,7 @@ static int load_advanced_binaries(
+       assert(pipe);
+       assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE ||
+-              pipe->mode == IA_CSS_PIPE_ID_COPY);
++             pipe->mode == IA_CSS_PIPE_ID_COPY);
+       if (pipe->pipe_settings.capture.pre_isp_binary.info)
+               return 0;
+       pipe_out_info = &pipe->output_info[0];
+@@ -6242,17 +6240,18 @@ static int load_advanced_binaries(
+       need_pp = need_capture_pp(pipe);
+       ia_css_frame_info_set_format(&vf_info,
+-                                      IA_CSS_FRAME_FORMAT_YUV_LINE);
++                                   IA_CSS_FRAME_FORMAT_YUV_LINE);
+       /* we build up the pipeline starting at the end */
+       /* Capture post-processing */
+       if (need_pp) {
+               struct ia_css_binary_descr capture_pp_descr;
+-              ia_css_pipe_get_capturepp_binarydesc(pipe,
+-                                                      &capture_pp_descr, &post_out_info, pipe_out_info, &vf_info);
++              ia_css_pipe_get_capturepp_binarydesc(pipe, &capture_pp_descr,
++                                                   &post_out_info,
++                                                   pipe_out_info, &vf_info);
+               err = ia_css_binary_find(&capture_pp_descr,
+-                                          &pipe->pipe_settings.capture.capture_pp_binary);
++                                       &pipe->pipe_settings.capture.capture_pp_binary);
+               if (err)
+                       return err;
+       } else {
+@@ -6263,10 +6262,11 @@ static int load_advanced_binaries(
+       {
+               struct ia_css_binary_descr post_gdc_descr;
+-              ia_css_pipe_get_post_gdc_binarydesc(pipe,
+-                                                  &post_gdc_descr, &post_in_info, &post_out_info, &vf_info);
++              ia_css_pipe_get_post_gdc_binarydesc(pipe, &post_gdc_descr,
++                                                  &post_in_info,
++                                                  &post_out_info, &vf_info);
+               err = ia_css_binary_find(&post_gdc_descr,
+-                                          &pipe->pipe_settings.capture.post_isp_binary);
++                                       &pipe->pipe_settings.capture.post_isp_binary);
+               if (err)
+                       return err;
+       }
+@@ -6276,9 +6276,9 @@ static int load_advanced_binaries(
+               struct ia_css_binary_descr gdc_descr;
+               ia_css_pipe_get_gdc_binarydesc(pipe, &gdc_descr, &gdc_in_info,
+-                                              &pipe->pipe_settings.capture.post_isp_binary.in_frame_info);
++                                             &pipe->pipe_settings.capture.post_isp_binary.in_frame_info);
+               err = ia_css_binary_find(&gdc_descr,
+-                                          &pipe->pipe_settings.capture.anr_gdc_binary);
++                                       &pipe->pipe_settings.capture.anr_gdc_binary);
+               if (err)
+                       return err;
+       }
+@@ -6290,9 +6290,9 @@ static int load_advanced_binaries(
+               struct ia_css_binary_descr pre_gdc_descr;
+               ia_css_pipe_get_pre_gdc_binarydesc(pipe, &pre_gdc_descr, &pre_in_info,
+-                                                  &pipe->pipe_settings.capture.anr_gdc_binary.in_frame_info);
++                                                 &pipe->pipe_settings.capture.anr_gdc_binary.in_frame_info);
+               err = ia_css_binary_find(&pre_gdc_descr,
+-                                          &pipe->pipe_settings.capture.pre_isp_binary);
++                                       &pipe->pipe_settings.capture.pre_isp_binary);
+               if (err)
+                       return err;
+       }
+@@ -6314,7 +6314,7 @@ static int load_advanced_binaries(
+               ia_css_pipe_get_vfpp_binarydesc(pipe,
+                                               &vf_pp_descr, vf_pp_in_info, pipe_vf_out_info);
+               err = ia_css_binary_find(&vf_pp_descr,
+-                                          &pipe->pipe_settings.capture.vf_pp_binary);
++                                       &pipe->pipe_settings.capture.vf_pp_binary);
+               if (err)
+                       return err;
+       }
+@@ -6326,8 +6326,8 @@ static int load_advanced_binaries(
+ #endif
+       if (need_isp_copy)
+               load_copy_binary(pipe,
+-                                  &pipe->pipe_settings.capture.copy_binary,
+-                                  &pipe->pipe_settings.capture.pre_isp_binary);
++                               &pipe->pipe_settings.capture.copy_binary,
++                               &pipe->pipe_settings.capture.pre_isp_binary);
+       return err;
+ }
+@@ -6342,7 +6342,7 @@ static int load_bayer_isp_binaries(
+       IA_CSS_ENTER_PRIVATE("");
+       assert(pipe);
+       assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE ||
+-              pipe->mode == IA_CSS_PIPE_ID_COPY);
++             pipe->mode == IA_CSS_PIPE_ID_COPY);
+       pipe_out_info = &pipe->output_info[0];
+       if (pipe->pipe_settings.capture.pre_isp_binary.info)
+@@ -6353,11 +6353,11 @@ static int load_bayer_isp_binaries(
+               return err;
+       ia_css_pipe_get_pre_de_binarydesc(pipe, &pre_de_descr,
+-                                          &pre_isp_in_info,
+-                                          pipe_out_info);
++                                        &pre_isp_in_info,
++                                        pipe_out_info);
+       err = ia_css_binary_find(&pre_de_descr,
+-                                  &pipe->pipe_settings.capture.pre_isp_binary);
++                               &pipe->pipe_settings.capture.pre_isp_binary);
+       return err;
+ }
+@@ -6376,7 +6376,7 @@ static int load_low_light_binaries(
+       IA_CSS_ENTER_PRIVATE("");
+       assert(pipe);
+       assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE ||
+-              pipe->mode == IA_CSS_PIPE_ID_COPY);
++             pipe->mode == IA_CSS_PIPE_ID_COPY);
+       if (pipe->pipe_settings.capture.pre_isp_binary.info)
+               return 0;
+@@ -6391,17 +6391,18 @@ static int load_low_light_binaries(
+       need_pp = need_capture_pp(pipe);
+       ia_css_frame_info_set_format(&vf_info,
+-                                      IA_CSS_FRAME_FORMAT_YUV_LINE);
++                                   IA_CSS_FRAME_FORMAT_YUV_LINE);
+       /* we build up the pipeline starting at the end */
+       /* Capture post-processing */
+       if (need_pp) {
+               struct ia_css_binary_descr capture_pp_descr;
+-              ia_css_pipe_get_capturepp_binarydesc(pipe,
+-                                                      &capture_pp_descr, &post_out_info, pipe_out_info, &vf_info);
++              ia_css_pipe_get_capturepp_binarydesc(pipe, &capture_pp_descr,
++                                                   &post_out_info,
++                                                   pipe_out_info, &vf_info);
+               err = ia_css_binary_find(&capture_pp_descr,
+-                                          &pipe->pipe_settings.capture.capture_pp_binary);
++                                       &pipe->pipe_settings.capture.capture_pp_binary);
+               if (err)
+                       return err;
+       } else {
+@@ -6415,7 +6416,7 @@ static int load_low_light_binaries(
+               ia_css_pipe_get_post_anr_binarydesc(pipe,
+                                                   &post_anr_descr, &post_in_info, &post_out_info, &vf_info);
+               err = ia_css_binary_find(&post_anr_descr,
+-                                          &pipe->pipe_settings.capture.post_isp_binary);
++                                       &pipe->pipe_settings.capture.post_isp_binary);
+               if (err)
+                       return err;
+       }
+@@ -6425,9 +6426,9 @@ static int load_low_light_binaries(
+               struct ia_css_binary_descr anr_descr;
+               ia_css_pipe_get_anr_binarydesc(pipe, &anr_descr, &anr_in_info,
+-                                              &pipe->pipe_settings.capture.post_isp_binary.in_frame_info);
++                                             &pipe->pipe_settings.capture.post_isp_binary.in_frame_info);
+               err = ia_css_binary_find(&anr_descr,
+-                                          &pipe->pipe_settings.capture.anr_gdc_binary);
++                                       &pipe->pipe_settings.capture.anr_gdc_binary);
+               if (err)
+                       return err;
+       }
+@@ -6439,9 +6440,9 @@ static int load_low_light_binaries(
+               struct ia_css_binary_descr pre_anr_descr;
+               ia_css_pipe_get_pre_anr_binarydesc(pipe, &pre_anr_descr, &pre_in_info,
+-                                                  &pipe->pipe_settings.capture.anr_gdc_binary.in_frame_info);
++                                                 &pipe->pipe_settings.capture.anr_gdc_binary.in_frame_info);
+               err = ia_css_binary_find(&pre_anr_descr,
+-                                          &pipe->pipe_settings.capture.pre_isp_binary);
++                                       &pipe->pipe_settings.capture.pre_isp_binary);
+               if (err)
+                       return err;
+       }
+@@ -6460,10 +6461,10 @@ static int load_low_light_binaries(
+       {
+               struct ia_css_binary_descr vf_pp_descr;
+-              ia_css_pipe_get_vfpp_binarydesc(pipe,
+-                                              &vf_pp_descr, vf_pp_in_info, pipe_vf_out_info);
++              ia_css_pipe_get_vfpp_binarydesc(pipe, &vf_pp_descr,
++                                              vf_pp_in_info, pipe_vf_out_info);
+               err = ia_css_binary_find(&vf_pp_descr,
+-                                          &pipe->pipe_settings.capture.vf_pp_binary);
++                                       &pipe->pipe_settings.capture.vf_pp_binary);
+               if (err)
+                       return err;
+       }
+@@ -6475,8 +6476,8 @@ static int load_low_light_binaries(
+ #endif
+       if (need_isp_copy)
+               err = load_copy_binary(pipe,
+-                                      &pipe->pipe_settings.capture.copy_binary,
+-                                      &pipe->pipe_settings.capture.pre_isp_binary);
++                                     &pipe->pipe_settings.capture.copy_binary,
++                                     &pipe->pipe_settings.capture.pre_isp_binary);
+       return err;
+ }
+@@ -6510,7 +6511,7 @@ static int load_capture_binaries(
+       IA_CSS_ENTER_PRIVATE("");
+       assert(pipe);
+       assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE ||
+-              pipe->mode == IA_CSS_PIPE_ID_COPY);
++             pipe->mode == IA_CSS_PIPE_ID_COPY);
+       if (pipe->pipe_settings.capture.primary_binary[0].info) {
+               IA_CSS_LEAVE_ERR_PRIVATE(0);
+@@ -6605,7 +6606,7 @@ unload_capture_binaries(struct ia_css_pi
+ static bool
+ need_downscaling(const struct ia_css_resolution in_res,
+-                  const struct ia_css_resolution out_res)
++               const struct ia_css_resolution out_res)
+ {
+       if (in_res.width > out_res.width || in_res.height > out_res.height)
+               return true;
+@@ -6676,9 +6677,9 @@ static int ia_css_pipe_create_cas_scaler
+       descr->num_output_stage = 1;
+       hor_ds_factor = CEIL_DIV(cas_scaler_in_info->res.width,
+-                                  cas_scaler_out_info->res.width);
++                               cas_scaler_out_info->res.width);
+       ver_ds_factor = CEIL_DIV(cas_scaler_in_info->res.height,
+-                                  cas_scaler_out_info->res.height);
++                               cas_scaler_out_info->res.height);
+       /* use the same horizontal and vertical downscaling factor for simplicity */
+       assert(hor_ds_factor == ver_ds_factor);
+@@ -6688,31 +6689,36 @@ static int ia_css_pipe_create_cas_scaler
+               i *= max_scale_factor_per_stage;
+       }
+-      descr->in_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info),
+-                                  GFP_KERNEL);
++      descr->in_info = kmalloc(descr->num_stage *
++                               sizeof(struct ia_css_frame_info),
++                               GFP_KERNEL);
+       if (!descr->in_info) {
+               err = -ENOMEM;
+               goto ERR;
+       }
+-      descr->internal_out_info = kmalloc(descr->num_stage * sizeof(
+-                                              struct ia_css_frame_info), GFP_KERNEL);
++      descr->internal_out_info = kmalloc(descr->num_stage *
++                                         sizeof(struct ia_css_frame_info),
++                                         GFP_KERNEL);
+       if (!descr->internal_out_info) {
+               err = -ENOMEM;
+               goto ERR;
+       }
+-      descr->out_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info),
+-                                  GFP_KERNEL);
++      descr->out_info = kmalloc(descr->num_stage *
++                                sizeof(struct ia_css_frame_info),
++                                GFP_KERNEL);
+       if (!descr->out_info) {
+               err = -ENOMEM;
+               goto ERR;
+       }
+-      descr->vf_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info),
+-                                  GFP_KERNEL);
++      descr->vf_info = kmalloc(descr->num_stage *
++                               sizeof(struct ia_css_frame_info),
++                               GFP_KERNEL);
+       if (!descr->vf_info) {
+               err = -ENOMEM;
+               goto ERR;
+       }
+-      descr->is_output_stage = kmalloc(descr->num_stage * sizeof(bool), GFP_KERNEL);
++      descr->is_output_stage = kmalloc(descr->num_stage * sizeof(bool),
++                                       GFP_KERNEL);
+       if (!descr->is_output_stage) {
+               err = -ENOMEM;
+               goto ERR;
+@@ -6756,9 +6762,9 @@ static int ia_css_pipe_create_cas_scaler
+                               max_scale_factor_per_stage;
+                       descr->internal_out_info[i].format = IA_CSS_FRAME_FORMAT_YUV420;
+                       ia_css_frame_info_init(&descr->internal_out_info[i],
+-                                              tmp_in_info.res.width / max_scale_factor_per_stage,
+-                                              tmp_in_info.res.height / max_scale_factor_per_stage,
+-                                              IA_CSS_FRAME_FORMAT_YUV420, 0);
++                                             tmp_in_info.res.width / max_scale_factor_per_stage,
++                                             tmp_in_info.res.height / max_scale_factor_per_stage,
++                                             IA_CSS_FRAME_FORMAT_YUV420, 0);
+                       descr->out_info[i].res.width = 0;
+                       descr->out_info[i].res.height = 0;
+                       descr->vf_info[i].res.width = 0;
+@@ -6834,30 +6840,35 @@ static int ia_css_pipe_create_cas_scaler
+       descr->num_stage = num_stages;
+       descr->in_info = kmalloc_array(descr->num_stage,
+-                                      sizeof(struct ia_css_frame_info), GFP_KERNEL);
++                                     sizeof(struct ia_css_frame_info),
++                                     GFP_KERNEL);
+       if (!descr->in_info) {
+               err = -ENOMEM;
+               goto ERR;
+       }
+-      descr->internal_out_info = kmalloc(descr->num_stage * sizeof(
+-                                              struct ia_css_frame_info), GFP_KERNEL);
++      descr->internal_out_info = kmalloc(descr->num_stage *
++                                         sizeof(struct ia_css_frame_info),
++                                         GFP_KERNEL);
+       if (!descr->internal_out_info) {
+               err = -ENOMEM;
+               goto ERR;
+       }
+-      descr->out_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info),
+-                                  GFP_KERNEL);
++      descr->out_info = kmalloc(descr->num_stage *
++                                sizeof(struct ia_css_frame_info),
++                                GFP_KERNEL);
+       if (!descr->out_info) {
+               err = -ENOMEM;
+               goto ERR;
+       }
+-      descr->vf_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info),
+-                                  GFP_KERNEL);
++      descr->vf_info = kmalloc(descr->num_stage *
++                               sizeof(struct ia_css_frame_info),
++                               GFP_KERNEL);
+       if (!descr->vf_info) {
+               err = -ENOMEM;
+               goto ERR;
+       }
+-      descr->is_output_stage = kmalloc(descr->num_stage * sizeof(bool), GFP_KERNEL);
++      descr->is_output_stage = kmalloc(descr->num_stage * sizeof(bool),
++                                       GFP_KERNEL);
+       if (!descr->is_output_stage) {
+               err = -ENOMEM;
+               goto ERR;
+@@ -6867,7 +6878,7 @@ static int ia_css_pipe_create_cas_scaler
+               if (out_info[i]) {
+                       if (i > 0) {
+                               assert((out_info[i - 1]->res.width >= out_info[i]->res.width) &&
+-                                      (out_info[i - 1]->res.height >= out_info[i]->res.height));
++                                     (out_info[i - 1]->res.height >= out_info[i]->res.height));
+                       }
+               }
+       }
+@@ -6915,9 +6926,9 @@ static int ia_css_pipe_create_cas_scaler
+                               max_scale_factor_per_stage;
+                       descr->internal_out_info[i].format = IA_CSS_FRAME_FORMAT_YUV420;
+                       ia_css_frame_info_init(&descr->internal_out_info[i],
+-                                              tmp_in_info.res.width / max_scale_factor_per_stage,
+-                                              tmp_in_info.res.height / max_scale_factor_per_stage,
+-                                              IA_CSS_FRAME_FORMAT_YUV420, 0);
++                                             tmp_in_info.res.width / max_scale_factor_per_stage,
++                                             tmp_in_info.res.height / max_scale_factor_per_stage,
++                                             IA_CSS_FRAME_FORMAT_YUV420, 0);
+                       descr->out_info[i].res.width = 0;
+                       descr->out_info[i].res.height = 0;
+                       descr->vf_info[i].res.width = 0;
+@@ -6996,13 +7007,14 @@ load_yuvpp_binaries(struct ia_css_pipe *
+               struct ia_css_binary_descr yuv_scaler_descr;
+               err = ia_css_pipe_create_cas_scaler_desc(pipe,
+-                      &cas_scaler_descr);
++                                                       &cas_scaler_descr);
+               if (err)
+                       goto ERR;
+               mycs->num_output = cas_scaler_descr.num_output_stage;
+               mycs->num_yuv_scaler = cas_scaler_descr.num_stage;
+               mycs->yuv_scaler_binary = kzalloc(cas_scaler_descr.num_stage *
+-                                                  sizeof(struct ia_css_binary), GFP_KERNEL);
++                                                sizeof(struct ia_css_binary),
++                                                GFP_KERNEL);
+               if (!mycs->yuv_scaler_binary) {
+                       err = -ENOMEM;
+                       goto ERR;
+@@ -7016,12 +7028,13 @@ load_yuvpp_binaries(struct ia_css_pipe *
+               for (i = 0; i < cas_scaler_descr.num_stage; i++) {
+                       mycs->is_output_stage[i] = cas_scaler_descr.is_output_stage[i];
+                       ia_css_pipe_get_yuvscaler_binarydesc(pipe,
+-                                                              &yuv_scaler_descr, &cas_scaler_descr.in_info[i],
+-                                                              &cas_scaler_descr.out_info[i],
+-                                                              &cas_scaler_descr.internal_out_info[i],
+-                                                              &cas_scaler_descr.vf_info[i]);
++                                                           &yuv_scaler_descr,
++                                                           &cas_scaler_descr.in_info[i],
++                                                           &cas_scaler_descr.out_info[i],
++                                                           &cas_scaler_descr.internal_out_info[i],
++                                                           &cas_scaler_descr.vf_info[i]);
+                       err = ia_css_binary_find(&yuv_scaler_descr,
+-                                                  &mycs->yuv_scaler_binary[i]);
++                                               &mycs->yuv_scaler_binary[i]);
+                       if (err)
+                               goto ERR;
+               }
+@@ -7061,8 +7074,8 @@ load_yuvpp_binaries(struct ia_css_pipe *
+       if (need_isp_copy_binary) {
+               err = load_copy_binary(pipe,
+-                                      &mycs->copy_binary,
+-                                      next_binary);
++                                     &mycs->copy_binary,
++                                     next_binary);
+               if (err)
+                       goto ERR;
+@@ -7107,8 +7120,9 @@ load_yuvpp_binaries(struct ia_css_pipe *
+               mycs->num_vf_pp = 1;
+       }
+-      mycs->vf_pp_binary = kzalloc(mycs->num_vf_pp * sizeof(struct ia_css_binary),
+-                                      GFP_KERNEL);
++      mycs->vf_pp_binary = kzalloc(mycs->num_vf_pp *
++                                   sizeof(struct ia_css_binary),
++                                   GFP_KERNEL);
+       if (!mycs->vf_pp_binary) {
+               err = -ENOMEM;
+               goto ERR;
+@@ -7437,18 +7451,26 @@ create_host_yuvpp_pipeline(struct ia_css
+ #endif
+               if (need_scaler) {
+-                      ia_css_pipe_util_set_output_frames(bin_out_frame, 0, NULL);
+-                      ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
+-                                                          bin_out_frame, in_frame_local, NULL);
++                      ia_css_pipe_util_set_output_frames(bin_out_frame,
++                                                         0, NULL);
++                      ia_css_pipe_get_generic_stage_desc(&stage_desc,
++                                                         copy_binary,
++                                                         bin_out_frame,
++                                                         in_frame_local,
++                                                         NULL);
+               } else {
+-                      ia_css_pipe_util_set_output_frames(bin_out_frame, 0, out_frame[0]);
+-                      ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
+-                                                          bin_out_frame, in_frame_local, NULL);
++                      ia_css_pipe_util_set_output_frames(bin_out_frame,
++                                                         0, out_frame[0]);
++                      ia_css_pipe_get_generic_stage_desc(&stage_desc,
++                                                         copy_binary,
++                                                         bin_out_frame,
++                                                         in_frame_local,
++                                                         NULL);
+               }
+               err = ia_css_pipeline_create_and_add_stage(me,
+-                      &stage_desc,
+-                      &copy_stage);
++                                                         &stage_desc,
++                                                         &copy_stage);
+               if (err) {
+                       IA_CSS_LEAVE_ERR_PRIVATE(err);
+@@ -7480,10 +7502,11 @@ create_host_yuvpp_pipeline(struct ia_css
+                               tmp_vf_frame = NULL;
+                       }
+-                      err = add_yuv_scaler_stage(pipe, me, tmp_in_frame, tmp_out_frame,
+-                                                  NULL,
+-                                                  &yuv_scaler_binary[i],
+-                                                  &yuv_scaler_stage);
++                      err = add_yuv_scaler_stage(pipe, me, tmp_in_frame,
++                                                 tmp_out_frame,
++                                                 NULL,
++                                                 &yuv_scaler_binary[i],
++                                                 &yuv_scaler_stage);
+                       if (err) {
+                               IA_CSS_LEAVE_ERR_PRIVATE(err);
+@@ -7494,8 +7517,10 @@ create_host_yuvpp_pipeline(struct ia_css
+                       if (pipe->pipe_settings.yuvpp.is_output_stage[i]) {
+                               if (tmp_vf_frame && (tmp_vf_frame->info.res.width != 0)) {
+                                       in_frame = yuv_scaler_stage->args.out_vf_frame;
+-                                      err = add_vf_pp_stage(pipe, in_frame, tmp_vf_frame, &vf_pp_binary[j],
+-                                                              &vf_pp_stage);
++                                      err = add_vf_pp_stage(pipe, in_frame,
++                                                            tmp_vf_frame,
++                                                            &vf_pp_binary[j],
++                                                            &vf_pp_stage);
+                                       if (err) {
+                                               IA_CSS_LEAVE_ERR_PRIVATE(err);
+@@ -7508,8 +7533,8 @@ create_host_yuvpp_pipeline(struct ia_css
+       } else if (copy_stage) {
+               if (vf_frame[0] && vf_frame[0]->info.res.width != 0) {
+                       in_frame = copy_stage->args.out_vf_frame;
+-                      err = add_vf_pp_stage(pipe, in_frame, vf_frame[0], &vf_pp_binary[0],
+-                                              &vf_pp_stage);
++                      err = add_vf_pp_stage(pipe, in_frame, vf_frame[0],
++                                            &vf_pp_binary[0], &vf_pp_stage);
+               }
+               if (err) {
+                       IA_CSS_LEAVE_ERR_PRIVATE(err);
+@@ -7517,7 +7542,8 @@ create_host_yuvpp_pipeline(struct ia_css
+               }
+       }
+-      ia_css_pipeline_finalize_stages(&pipe->pipeline, pipe->stream->config.continuous);
++      ia_css_pipeline_finalize_stages(&pipe->pipeline,
++                                      pipe->stream->config.continuous);
+       IA_CSS_LEAVE_ERR_PRIVATE(0);
+@@ -7526,8 +7552,8 @@ create_host_yuvpp_pipeline(struct ia_css
+ static int
+ create_host_copy_pipeline(struct ia_css_pipe *pipe,
+-                          unsigned int max_input_width,
+-                          struct ia_css_frame *out_frame)
++                        unsigned int max_input_width,
++                        struct ia_css_frame *out_frame)
+ {
+       struct ia_css_pipeline *me;
+       int err = 0;
+@@ -7546,12 +7572,8 @@ create_host_copy_pipeline(struct ia_css_
+       if (copy_on_sp(pipe) &&
+           pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8) {
+-              ia_css_frame_info_init(
+-                  &out_frame->info,
+-                  JPEG_BYTES,
+-                  1,
+-                  IA_CSS_FRAME_FORMAT_BINARY_8,
+-                  0);
++              ia_css_frame_info_init(&out_frame->info, JPEG_BYTES, 1,
++                                     IA_CSS_FRAME_FORMAT_BINARY_8, 0);
+       } else if (out_frame->info.format == IA_CSS_FRAME_FORMAT_RAW) {
+               out_frame->info.raw_bit_depth =
+               ia_css_pipe_util_pipe_input_format_bpp(pipe);
+@@ -7562,12 +7584,12 @@ create_host_copy_pipeline(struct ia_css_
+       pipe->mode  = IA_CSS_PIPE_ID_COPY;
+       ia_css_pipe_get_sp_func_stage_desc(&stage_desc, out_frame,
+-                                          IA_CSS_PIPELINE_RAW_COPY, max_input_width);
+-      err = ia_css_pipeline_create_and_add_stage(me,
+-              &stage_desc,
+-              NULL);
++                                         IA_CSS_PIPELINE_RAW_COPY,
++                                         max_input_width);
++      err = ia_css_pipeline_create_and_add_stage(me, &stage_desc, NULL);
+-      ia_css_pipeline_finalize_stages(&pipe->pipeline, pipe->stream->config.continuous);
++      ia_css_pipeline_finalize_stages(&pipe->pipeline,
++                                      pipe->stream->config.continuous);
+       ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
+                           "create_host_copy_pipeline() leave:\n");
+@@ -7606,9 +7628,10 @@ create_host_isyscopy_capture_pipeline(st
+       me->pipe_id = IA_CSS_PIPE_ID_CAPTURE;
+       pipe->mode  = IA_CSS_PIPE_ID_CAPTURE;
+       ia_css_pipe_get_sp_func_stage_desc(&stage_desc, out_frame,
+-                                          IA_CSS_PIPELINE_ISYS_COPY, max_input_width);
++                                         IA_CSS_PIPELINE_ISYS_COPY,
++                                         max_input_width);
+       err = ia_css_pipeline_create_and_add_stage(me,
+-              &stage_desc, &out_stage);
++                                                 &stage_desc, &out_stage);
+       if (err)
+               return err;
+@@ -7660,7 +7683,8 @@ create_host_regular_capture_pipeline(str
+       IA_CSS_ENTER_PRIVATE("");
+       assert(pipe);
+       assert(pipe->stream);
+-      assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE || pipe->mode == IA_CSS_PIPE_ID_COPY);
++      assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE ||
++             pipe->mode == IA_CSS_PIPE_ID_COPY);
+       me = &pipe->pipeline;
+       mode = pipe->config.default_capture_config.mode;
+@@ -7750,26 +7774,37 @@ create_host_regular_capture_pipeline(str
+                       ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
+ #if defined(ISP2401)
+                       if (!continuous) {
+-                              ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
+-                                                                  out_frames, in_frame, NULL);
++                              ia_css_pipe_get_generic_stage_desc(&stage_desc,
++                                                                 copy_binary,
++                                                                 out_frames,
++                                                                 in_frame,
++                                                                 NULL);
+                       } else {
+                               in_frame = pipe->stream->last_pipe->continuous_frames[0];
+-                              ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
+-                                                                  out_frames, in_frame, NULL);
++                              ia_css_pipe_get_generic_stage_desc(&stage_desc,
++                                                                 copy_binary,
++                                                                 out_frames,
++                                                                 in_frame,
++                                                                 NULL);
+                       }
+ #else
+-                      ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
+-                                                          out_frames, NULL, NULL);
++                      ia_css_pipe_get_generic_stage_desc(&stage_desc,
++                                                         copy_binary,
++                                                         out_frames,
++                                                         NULL, NULL);
+ #endif
+               } else {
+-                      ia_css_pipe_util_set_output_frames(out_frames, 0, in_frame);
+-                      ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
+-                                                          out_frames, NULL, NULL);
++                      ia_css_pipe_util_set_output_frames(out_frames, 0,
++                                                         in_frame);
++                      ia_css_pipe_get_generic_stage_desc(&stage_desc,
++                                                         copy_binary,
++                                                         out_frames,
++                                                         NULL, NULL);
+               }
+               err = ia_css_pipeline_create_and_add_stage(me,
+-                      &stage_desc,
+-                      &current_stage);
++                                                         &stage_desc,
++                                                         &current_stage);
+               if (err) {
+                       IA_CSS_LEAVE_ERR_PRIVATE(err);
+                       return err;
+@@ -7806,11 +7841,14 @@ create_host_regular_capture_pipeline(str
+                           * Proper investigation should be done to come up with the clean
+                           * solution.
+                           * */
+-                      ia_css_pipe_get_generic_stage_desc(&stage_desc, primary_binary[i],
+-                                                          out_frames, local_in_frame, NULL);
++                      ia_css_pipe_get_generic_stage_desc(&stage_desc,
++                                                         primary_binary[i],
++                                                         out_frames,
++                                                         local_in_frame,
++                                                         NULL);
+                       err = ia_css_pipeline_create_and_add_stage(me,
+-                              &stage_desc,
+-                              &current_stage);
++                                                                 &stage_desc,
++                                                                 &current_stage);
+                       if (err) {
+                               IA_CSS_LEAVE_ERR_PRIVATE(err);
+                               return err;
+@@ -7826,18 +7864,18 @@ create_host_regular_capture_pipeline(str
+                   mode == IA_CSS_CAPTURE_MODE_LOW_LIGHT) {
+               ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
+               ia_css_pipe_get_generic_stage_desc(&stage_desc, pre_isp_binary,
+-                                                  out_frames, in_frame, NULL);
+-              err = ia_css_pipeline_create_and_add_stage(me,
+-                      &stage_desc, NULL);
++                                                 out_frames, in_frame, NULL);
++              err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++                                                         NULL);
+               if (err) {
+                       IA_CSS_LEAVE_ERR_PRIVATE(err);
+                       return err;
+               }
+               ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
+               ia_css_pipe_get_generic_stage_desc(&stage_desc, anr_gdc_binary,
+-                                                  out_frames, NULL, NULL);
+-              err = ia_css_pipeline_create_and_add_stage(me,
+-                      &stage_desc, NULL);
++                                                 out_frames, NULL, NULL);
++              err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++                                                         NULL);
+               if (err) {
+                       IA_CSS_LEAVE_ERR_PRIVATE(err);
+                       return err;
+@@ -7845,16 +7883,21 @@ create_host_regular_capture_pipeline(str
+               if (need_pp) {
+                       ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
+-                      ia_css_pipe_get_generic_stage_desc(&stage_desc, post_isp_binary,
+-                                                          out_frames, NULL, NULL);
++                      ia_css_pipe_get_generic_stage_desc(&stage_desc,
++                                                         post_isp_binary,
++                                                         out_frames,
++                                                         NULL, NULL);
+               } else {
+-                      ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
+-                      ia_css_pipe_get_generic_stage_desc(&stage_desc, post_isp_binary,
+-                                                          out_frames, NULL, NULL);
++                      ia_css_pipe_util_set_output_frames(out_frames, 0,
++                                                         out_frame);
++                      ia_css_pipe_get_generic_stage_desc(&stage_desc,
++                                                         post_isp_binary,
++                                                         out_frames,
++                                                         NULL, NULL);
+               }
+-              err = ia_css_pipeline_create_and_add_stage(me,
+-                      &stage_desc, &current_stage);
++              err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++                                                         &current_stage);
+               if (err) {
+                       IA_CSS_LEAVE_ERR_PRIVATE(err);
+                       return err;
+@@ -7862,10 +7905,9 @@ create_host_regular_capture_pipeline(str
+       } else if (mode == IA_CSS_CAPTURE_MODE_BAYER) {
+               ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
+               ia_css_pipe_get_generic_stage_desc(&stage_desc, pre_isp_binary,
+-                                                  out_frames, in_frame, NULL);
+-              err = ia_css_pipeline_create_and_add_stage(me,
+-                      &stage_desc,
+-                      NULL);
++                                                 out_frames, in_frame, NULL);
++              err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++                                                         NULL);
+               if (err) {
+                       IA_CSS_LEAVE_ERR_PRIVATE(err);
+                       return err;
+@@ -7880,31 +7922,34 @@ create_host_regular_capture_pipeline(str
+               if (need_ldc) {
+                       ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
+-                      ia_css_pipe_get_generic_stage_desc(&stage_desc, capture_ldc_binary,
+-                                                          out_frames, local_in_frame, NULL);
++                      ia_css_pipe_get_generic_stage_desc(&stage_desc,
++                                                         capture_ldc_binary,
++                                                         out_frames,
++                                                         local_in_frame,
++                                                         NULL);
+                       err = ia_css_pipeline_create_and_add_stage(me,
+-                              &stage_desc,
+-                              &current_stage);
++                                                                 &stage_desc,
++                                                                 &current_stage);
+                       local_in_frame = current_stage->args.out_frame[0];
+               }
+               err = add_capture_pp_stage(pipe, me, local_in_frame,
+-                                          need_yuv_pp ? NULL : out_frame,
++                                         need_yuv_pp ? NULL : out_frame,
+ #else
+       /* ldc and capture_pp not supported in same pipeline */
+       if (need_ldc && current_stage) {
+               in_frame = current_stage->args.out_frame[0];
+               ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
+               ia_css_pipe_get_generic_stage_desc(&stage_desc, capture_ldc_binary,
+-                                                  out_frames, in_frame, NULL);
+-              err = ia_css_pipeline_create_and_add_stage(me,
+-                      &stage_desc,
+-                      NULL);
++                                                 out_frames, in_frame, NULL);
++              err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
++                                                         NULL);
+       } else if (need_pp && current_stage) {
+               in_frame = current_stage->args.out_frame[0];
+-              err = add_capture_pp_stage(pipe, me, in_frame, need_yuv_pp ? NULL : out_frame,
++              err = add_capture_pp_stage(pipe, me, in_frame,
++                                         need_yuv_pp ? NULL : out_frame,
+ #endif
+-                                          capture_pp_binary,
+-                                          &current_stage);
++                                         capture_pp_binary,
++                                         &current_stage);
+               if (err) {
+                       IA_CSS_LEAVE_ERR_PRIVATE(err);
+                       return err;
+@@ -7921,10 +7966,10 @@ create_host_regular_capture_pipeline(str
+                       else
+                               tmp_out_frame = NULL;
+-                      err = add_yuv_scaler_stage(pipe, me, tmp_in_frame, tmp_out_frame,
+-                                                  NULL,
+-                                                  &yuv_scaler_binary[i],
+-                                                  &yuv_scaler_stage);
++                      err = add_yuv_scaler_stage(pipe, me, tmp_in_frame,
++                                                 tmp_out_frame, NULL,
++                                                 &yuv_scaler_binary[i],
++                                                 &yuv_scaler_stage);
+                       if (err) {
+                               IA_CSS_LEAVE_ERR_PRIVATE(err);
+                               return err;
+@@ -7946,7 +7991,7 @@ create_host_regular_capture_pipeline(str
+       if (mode != IA_CSS_CAPTURE_MODE_RAW && mode != IA_CSS_CAPTURE_MODE_BAYER && current_stage && vf_frame) {
+               in_frame = current_stage->args.out_vf_frame;
+               err = add_vf_pp_stage(pipe, in_frame, vf_frame, vf_pp_binary,
+-                                      &current_stage);
++                                    &current_stage);
+               if (err) {
+                       IA_CSS_LEAVE_ERR_PRIVATE(err);
+                       return err;
+@@ -7998,7 +8043,7 @@ static int capture_start(
+       me = &pipe->pipeline;
+       if ((pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_RAW   ||
+-              pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_BAYER) &&
++           pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_BAYER) &&
+           (pipe->config.mode != IA_CSS_PIPE_MODE_COPY)) {
+               if (copy_on_sp(pipe)) {
+                       err = start_copy_on_sp(pipe, &me->out_frame[0]);
+@@ -8042,7 +8087,7 @@ static int capture_start(
+       if (pipe->config.mode == IA_CSS_PIPE_MODE_COPY &&
+           pipe->stream->reconfigure_css_rx) {
+               ia_css_isys_rx_configure(&pipe->stream->csi_rx_config,
+-                                          pipe->stream->config.mode);
++                                       pipe->stream->config.mode);
+               pipe->stream->reconfigure_css_rx = false;
+       }
+ #endif
+@@ -8053,8 +8098,8 @@ static int capture_start(
+ static int
+ sh_css_pipe_get_output_frame_info(struct ia_css_pipe *pipe,
+-                                  struct ia_css_frame_info *info,
+-                                  unsigned int idx)
++                                struct ia_css_frame_info *info,
++                                unsigned int idx)
+ {
+       assert(pipe);
+       assert(info);
+@@ -8072,7 +8117,7 @@ sh_css_pipe_get_output_frame_info(struct
+                   IA_CSS_FRAME_FORMAT_BINARY_8,
+                   0);
+       } else if (info->format == IA_CSS_FRAME_FORMAT_RAW ||
+-                  info->format == IA_CSS_FRAME_FORMAT_RAW_PACKED) {
++                 info->format == IA_CSS_FRAME_FORMAT_RAW_PACKED) {
+               info->raw_bit_depth =
+               ia_css_pipe_util_pipe_input_format_bpp(pipe);
+       }
+@@ -8084,9 +8129,9 @@ sh_css_pipe_get_output_frame_info(struct
+ void
+ ia_css_stream_send_input_frame(const struct ia_css_stream *stream,
+-                              const unsigned short *data,
+-                              unsigned int width,
+-                              unsigned int height)
++                             const unsigned short *data,
++                             unsigned int width,
++                             unsigned int height)
+ {
+       assert(stream);
+@@ -8110,22 +8155,22 @@ ia_css_stream_start_input_frame(const st
+ void
+ ia_css_stream_send_input_line(const struct ia_css_stream *stream,
+-                              const unsigned short *data,
+-                              unsigned int width,
+-                              const unsigned short *data2,
+-                              unsigned int width2)
++                            const unsigned short *data,
++                            unsigned int width,
++                            const unsigned short *data2,
++                            unsigned int width2)
+ {
+       assert(stream);
+       ia_css_inputfifo_send_line(stream->config.channel_id,
+-                                  data, width, data2, width2);
++                                 data, width, data2, width2);
+ }
+ void
+ ia_css_stream_send_input_embedded_line(const struct ia_css_stream *stream,
+-                                      enum atomisp_input_format format,
+-                                      const unsigned short *data,
+-                                      unsigned int width)
++                                     enum atomisp_input_format format,
++                                     const unsigned short *data,
++                                     unsigned int width)
+ {
+       assert(stream);
+       if (!data || width == 0)
+@@ -8246,7 +8291,7 @@ acc_unload_extension(struct ia_css_fw_in
+ /* Load firmware for extension */
+ static int
+ ia_css_pipe_load_extension(struct ia_css_pipe *pipe,
+-                          struct ia_css_fw_info *firmware)
++                         struct ia_css_fw_info *firmware)
+ {
+       int err = 0;
+@@ -8270,7 +8315,7 @@ ia_css_pipe_load_extension(struct ia_css
+ /* Unload firmware for extension */
+ static void
+ ia_css_pipe_unload_extension(struct ia_css_pipe *pipe,
+-                              struct ia_css_fw_info *firmware)
++                           struct ia_css_fw_info *firmware)
+ {
+       IA_CSS_ENTER_PRIVATE("fw = %p pipe = %p", firmware, pipe);
+@@ -8312,7 +8357,7 @@ ia_css_pipeline_uses_params(struct ia_cs
+ static int
+ sh_css_pipeline_add_acc_stage(struct ia_css_pipeline *pipeline,
+-                              const void *acc_fw)
++                            const void *acc_fw)
+ {
+       struct ia_css_fw_info *fw = (struct ia_css_fw_info *)acc_fw;
+       /* In QoS case, load_extension already called, so skipping */
+@@ -8330,8 +8375,8 @@ sh_css_pipeline_add_acc_stage(struct ia_
+               ia_css_pipe_get_acc_stage_desc(&stage_desc, NULL, fw);
+               err = ia_css_pipeline_create_and_add_stage(pipeline,
+-                      &stage_desc,
+-                      NULL);
++                                                         &stage_desc,
++                                                         NULL);
+       }
+       ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
+@@ -8344,7 +8389,7 @@ sh_css_pipeline_add_acc_stage(struct ia_
+     * Refer to "sh_css_internal.h" for details.
+     */
+ int ia_css_stream_capture_frame(struct ia_css_stream *stream,
+-      unsigned int exp_id)
++                              unsigned int exp_id)
+ {
+       struct sh_css_tag_descr tag_descr;
+       u32 encoded_tag_descr;
+@@ -8503,22 +8548,22 @@ sh_css_init_host_sp_control_vars(void)
+       (void)HIVE_ADDR_host_sp_com;
+       sp_dmem_store_uint32(SP0_ID,
+-                              (unsigned int)sp_address_of(ia_css_ispctrl_sp_isp_started),
+-                              (uint32_t)(0));
++                           (unsigned int)sp_address_of(ia_css_ispctrl_sp_isp_started),
++                           (uint32_t)(0));
+       sp_dmem_store_uint32(SP0_ID,
+-                              (unsigned int)sp_address_of(host_sp_queues_initialized),
+-                              (uint32_t)(0));
++                           (unsigned int)sp_address_of(host_sp_queues_initialized),
++                           (uint32_t)(0));
+       sp_dmem_store_uint32(SP0_ID,
+-                              (unsigned int)sp_address_of(sp_sleep_mode),
+-                              (uint32_t)(0));
++                           (unsigned int)sp_address_of(sp_sleep_mode),
++                           (uint32_t)(0));
+       sp_dmem_store_uint32(SP0_ID,
+-                              (unsigned int)sp_address_of(ia_css_dmaproxy_sp_invalidate_tlb),
+-                              (uint32_t)(false));
++                           (unsigned int)sp_address_of(ia_css_dmaproxy_sp_invalidate_tlb),
++                           (uint32_t)(false));
+ #ifndef ISP2401
+       sp_dmem_store_uint32(SP0_ID,
+-                              (unsigned int)sp_address_of(sp_stop_copy_preview),
+-                              my_css.stop_copy_preview ? (uint32_t)(1) : (uint32_t)(0));
++                           (unsigned int)sp_address_of(sp_stop_copy_preview),
++                           my_css.stop_copy_preview ? (uint32_t)(1) : (uint32_t)(0));
+ #endif
+       store_sp_array_uint(host_sp_com, o, host2sp_cmd_ready);
+@@ -8545,8 +8590,7 @@ void ia_css_pipe_config_defaults(struct
+ }
+ void
+-ia_css_pipe_extra_config_defaults(struct ia_css_pipe_extra_config
+-                                  *extra_config)
++ia_css_pipe_extra_config_defaults(struct ia_css_pipe_extra_config *extra_config)
+ {
+       if (!extra_config) {
+               IA_CSS_ERROR("NULL input parameter");
+@@ -8620,8 +8664,8 @@ int ia_css_pipe_create(const struct ia_c
+ int
+ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config,
+-                          const struct ia_css_pipe_extra_config *extra_config,
+-                          struct ia_css_pipe **pipe)
++                       const struct ia_css_pipe_extra_config *extra_config,
++                       struct ia_css_pipe **pipe)
+ {
+       int err = -EINVAL;
+       struct ia_css_pipe *internal_pipe = NULL;
+@@ -8689,7 +8733,7 @@ ia_css_pipe_create_extra(const struct ia
+       /* YUV downscaling */
+       if ((internal_pipe->config.vf_pp_in_res.width ||
+-              internal_pipe->config.capt_pp_in_res.width)) {
++           internal_pipe->config.capt_pp_in_res.width)) {
+               enum ia_css_frame_format format;
+               if (internal_pipe->config.vf_pp_in_res.width) {
+@@ -8765,7 +8809,7 @@ ia_css_pipe_create_extra(const struct ia
+       }
+       if (internal_pipe->config.acc_extension) {
+               err = ia_css_pipe_load_extension(internal_pipe,
+-                                                  internal_pipe->config.acc_extension);
++                                               internal_pipe->config.acc_extension);
+               if (err) {
+                       IA_CSS_LEAVE_ERR_PRIVATE(err);
+                       kvfree(internal_pipe);
+@@ -8783,7 +8827,7 @@ ia_css_pipe_create_extra(const struct ia
+ int
+ ia_css_pipe_get_info(const struct ia_css_pipe *pipe,
+-                      struct ia_css_pipe_info *pipe_info)
++                   struct ia_css_pipe_info *pipe_info)
+ {
+       ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
+                           "ia_css_pipe_get_info()\n");
+@@ -8821,8 +8865,8 @@ bool ia_css_pipe_has_dvs_stats(struct ia
+ int
+ ia_css_pipe_override_frame_format(struct ia_css_pipe *pipe,
+-                                  int pin_index,
+-                                  enum ia_css_frame_format new_format)
++                                int pin_index,
++                                enum ia_css_frame_format new_format)
+ {
+       int err = 0;
+@@ -8902,10 +8946,8 @@ ia_css_stream_configure_rx(struct ia_css
+ #endif
+ static struct ia_css_pipe *
+-find_pipe(struct ia_css_pipe *pipes[],
+-          unsigned int num_pipes,
+-          enum ia_css_pipe_mode mode,
+-          bool copy_pipe)
++find_pipe(struct ia_css_pipe *pipes[], unsigned int num_pipes,
++        enum ia_css_pipe_mode mode, bool copy_pipe)
+ {
+       unsigned int i;
+@@ -8976,7 +9018,7 @@ ia_css_acc_stream_create(struct ia_css_s
+ static int
+ metadata_info_init(const struct ia_css_metadata_config *mdc,
+-                  struct ia_css_metadata_info *md)
++                 struct ia_css_metadata_info *md)
+ {
+       /* Either both width and height should be set or neither */
+       if ((mdc->resolution.height > 0) ^ (mdc->resolution.width > 0))
+@@ -9004,7 +9046,7 @@ static int check_pipe_resolutions(const
+       }
+       if (ia_css_util_check_res(pipe->config.input_effective_res.width,
+-                                  pipe->config.input_effective_res.height) != 0) {
++                                pipe->config.input_effective_res.height) != 0) {
+               IA_CSS_ERROR("effective resolution not supported");
+               err = -EINVAL;
+               goto EXIT;
+@@ -9012,7 +9054,7 @@ static int check_pipe_resolutions(const
+       if (!ia_css_util_resolution_is_zero(
+               pipe->stream->config.input_config.input_res)) {
+               if (!ia_css_util_res_leq(pipe->config.input_effective_res,
+-                                          pipe->stream->config.input_config.input_res)) {
++                                       pipe->stream->config.input_config.input_res)) {
+                       IA_CSS_ERROR("effective resolution is larger than input resolution");
+                       err = -EINVAL;
+                       goto EXIT;
+@@ -9035,9 +9077,9 @@ EXIT:
+ int
+ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
+-                      int num_pipes,
+-                      struct ia_css_pipe *pipes[],
+-                      struct ia_css_stream **stream)
++                   int num_pipes,
++                   struct ia_css_pipe *pipes[],
++                   struct ia_css_stream **stream)
+ {
+       struct ia_css_pipe *curr_pipe;
+       struct ia_css_stream *curr_stream = NULL;
+@@ -9198,11 +9240,11 @@ ia_css_stream_create(const struct ia_css
+       case IA_CSS_INPUT_MODE_TPG:
+ #if !defined(ISP2401)
+               IA_CSS_LOG("tpg_configuration: x_mask=%d, y_mask=%d, x_delta=%d, y_delta=%d, xy_mask=%d",
+-                          curr_stream->config.source.tpg.x_mask,
+-                          curr_stream->config.source.tpg.y_mask,
+-                          curr_stream->config.source.tpg.x_delta,
+-                          curr_stream->config.source.tpg.y_delta,
+-                          curr_stream->config.source.tpg.xy_mask);
++                         curr_stream->config.source.tpg.x_mask,
++                         curr_stream->config.source.tpg.y_mask,
++                         curr_stream->config.source.tpg.x_delta,
++                         curr_stream->config.source.tpg.y_delta,
++                         curr_stream->config.source.tpg.xy_mask);
+               sh_css_sp_configure_tpg(
+                   curr_stream->config.source.tpg.x_mask,
+@@ -9227,9 +9269,8 @@ ia_css_stream_create(const struct ia_css
+       }
+ #ifdef ISP2401
+-      err = aspect_ratio_crop_init(curr_stream,
+-                                      pipes,
+-                                      &aspect_ratio_crop_enabled);
++      err = aspect_ratio_crop_init(curr_stream, pipes,
++                                   &aspect_ratio_crop_enabled);
+       if (err) {
+               IA_CSS_LEAVE_ERR(err);
+               goto ERR;
+@@ -9266,8 +9307,8 @@ ia_css_stream_create(const struct ia_css
+                       curr_pipe->config.input_effective_res = effective_res;
+               }
+               IA_CSS_LOG("effective_res=%dx%d",
+-                          effective_res.width,
+-                          effective_res.height);
++                         effective_res.width,
++                         effective_res.height);
+       }
+       if (IS_ISP2401) {
+@@ -9295,13 +9336,13 @@ ia_css_stream_create(const struct ia_css
+       if (!spcopyonly) {
+               sensor_binning_changed =
+                   sh_css_params_set_binning_factor(curr_stream,
+-                                                      curr_stream->config.sensor_binning_factor);
++                                                   curr_stream->config.sensor_binning_factor);
+       } else {
+               sensor_binning_changed = false;
+       }
+       IA_CSS_LOG("sensor_binning=%d, changed=%d",
+-                  curr_stream->config.sensor_binning_factor, sensor_binning_changed);
++                 curr_stream->config.sensor_binning_factor, sensor_binning_changed);
+       /* loop over pipes */
+       IA_CSS_LOG("num_pipes=%d", num_pipes);
+       curr_stream->cont_capt = false;
+@@ -9325,17 +9366,18 @@ ia_css_stream_create(const struct ia_css
+               /* Create copy pipe here, since it may not be exposed to the driver */
+               preview_pipe = find_pipe(pipes, num_pipes,
+-                                          IA_CSS_PIPE_MODE_PREVIEW, false);
++                                       IA_CSS_PIPE_MODE_PREVIEW, false);
+               video_pipe = find_pipe(pipes, num_pipes,
+-                                      IA_CSS_PIPE_MODE_VIDEO, false);
+-              acc_pipe = find_pipe(pipes, num_pipes,
+-                                      IA_CSS_PIPE_MODE_ACC, false);
++                                     IA_CSS_PIPE_MODE_VIDEO, false);
++              acc_pipe = find_pipe(pipes, num_pipes, IA_CSS_PIPE_MODE_ACC,
++                                   false);
+               if (acc_pipe && num_pipes == 2 && curr_stream->cont_capt)
+                       curr_stream->cont_capt =
+                           false; /* preview + QoS case will not need cont_capt switch */
+               if (curr_stream->cont_capt) {
+                       capture_pipe = find_pipe(pipes, num_pipes,
+-                                                  IA_CSS_PIPE_MODE_CAPTURE, false);
++                                               IA_CSS_PIPE_MODE_CAPTURE,
++                                               false);
+                       if (!capture_pipe) {
+                               err = -EINVAL;
+                               goto ERR;
+@@ -9417,10 +9459,12 @@ ia_css_stream_create(const struct ia_css
+               if (!spcopyonly) {
+                       if (!IS_ISP2401)
+                               err = sh_css_pipe_get_shading_info(curr_pipe,
+-                                                                  &pipe_info->shading_info, NULL);
++                                                                 &pipe_info->shading_info,
++                                                                 NULL);
+                       else
+                               err = sh_css_pipe_get_shading_info(curr_pipe,
+-                                                                  &pipe_info->shading_info, &curr_pipe->config);
++                                                                 &pipe_info->shading_info,
++                                                                 &curr_pipe->config);
+                       if (err)
+                               goto ERR;
+@@ -9430,7 +9474,8 @@ ia_css_stream_create(const struct ia_css
+                               goto ERR;
+                       for (j = 0; j < IA_CSS_PIPE_MAX_OUTPUT_STAGE; j++) {
+                               sh_css_pipe_get_viewfinder_frame_info(curr_pipe,
+-                                                                      &pipe_info->vf_output_info[j], j);
++                                                                    &pipe_info->vf_output_info[j],
++                                                                    j);
+                               if (err)
+                                       goto ERR;
+                       }
+@@ -9615,7 +9660,7 @@ ia_css_stream_destroy(struct ia_css_stre
+ int
+ ia_css_stream_get_info(const struct ia_css_stream *stream,
+-                      struct ia_css_stream_info *stream_info)
++                     struct ia_css_stream_info *stream_info)
+ {
+       ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_get_info: enter/exit\n");
+       assert(stream);
+@@ -9903,7 +9948,7 @@ ia_css_stream_get_3a_binary(const struct
+ int
+ ia_css_stream_set_output_padded_width(struct ia_css_stream *stream,
+-                                      unsigned int output_padded_width)
++                                    unsigned int output_padded_width)
+ {
+       struct ia_css_pipe *pipe;
+@@ -10380,7 +10425,7 @@ ia_css_unlock_raw_frame(struct ia_css_st
+     */
+ int
+ ia_css_pipe_set_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle,
+-                              bool enable)
++                            bool enable)
+ {
+       unsigned int thread_id;
+       struct ia_css_pipeline_stage *stage;
+@@ -10426,7 +10471,7 @@ ia_css_pipe_set_qos_ext_state(struct ia_
+     */
+ int
+ ia_css_pipe_get_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle,
+-                              bool *enable)
++                            bool *enable)
+ {
+       struct ia_css_pipeline_stage *stage;
+       unsigned int thread_id;
+@@ -10462,9 +10507,9 @@ ia_css_pipe_get_qos_ext_state(struct ia_
+ /* ISP2401 */
+ int
+ ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe,
+-                                      u32 fw_handle,
+-                                      struct ia_css_isp_param_css_segments *css_seg,
+-                                      struct ia_css_isp_param_isp_segments *isp_seg)
++                                    u32 fw_handle,
++                                    struct ia_css_isp_param_css_segments *css_seg,
++                                    struct ia_css_isp_param_isp_segments *isp_seg)
+ {
+       unsigned int HIVE_ADDR_sp_group;
+       static struct sh_css_sp_group sp_group;
+@@ -10499,7 +10544,7 @@ ia_css_pipe_update_qos_ext_mapped_arg(st
+               if (!err) {
+                       /* Get the Extension State */
+                       enabled = (SH_CSS_QOS_STAGE_IS_ENABLED(&sh_css_sp_group.pipe[thread_id],
+-                                                              stage->stage_num)) ? true : false;
++                                                             stage->stage_num)) ? true : false;
+                       /* Update mapped arg only when extension stage is not enabled */
+                       if (enabled) {
+                               IA_CSS_ERROR("Leaving: cannot update when stage is enabled.");
+@@ -10509,13 +10554,14 @@ ia_css_pipe_update_qos_ext_mapped_arg(st
+                               HIVE_ADDR_sp_group = fw->info.sp.group;
+                               sp_dmem_load(SP0_ID,
+-                                              (unsigned int)sp_address_of(sp_group),
+-                                              &sp_group, sizeof(struct sh_css_sp_group));
++                                           (unsigned int)sp_address_of(sp_group),
++                                           &sp_group,
++                                           sizeof(struct sh_css_sp_group));
+                               hmm_load(sp_group.pipe[thread_id].sp_stage_addr[stage_num],
+-                                          &sp_stage, sizeof(struct sh_css_sp_stage));
++                                       &sp_stage, sizeof(struct sh_css_sp_stage));
+                               hmm_load(sp_stage.isp_stage_addr,
+-                                          &isp_stage, sizeof(struct sh_css_isp_stage));
++                                       &isp_stage, sizeof(struct sh_css_isp_stage));
+                               for (mem = 0; mem < N_IA_CSS_ISP_MEMORIES; mem++) {
+                                       isp_stage.mem_initializers.params[IA_CSS_PARAM_CLASS_PARAM][mem].address =
+@@ -10531,7 +10577,8 @@ ia_css_pipe_update_qos_ext_mapped_arg(st
+                               }
+                               hmm_store(sp_stage.isp_stage_addr,
+-                                          &isp_stage, sizeof(struct sh_css_isp_stage));
++                                        &isp_stage,
++                                        sizeof(struct sh_css_isp_stage));
+                       }
+               }
+       }
+@@ -10542,8 +10589,8 @@ ia_css_pipe_update_qos_ext_mapped_arg(st
+ #ifdef ISP2401
+ static int
+ aspect_ratio_crop_init(struct ia_css_stream *curr_stream,
+-                      struct ia_css_pipe *pipes[],
+-                      bool *do_crop_status)
++                     struct ia_css_pipe *pipes[],
++                     bool *do_crop_status)
+ {
+       int err = 0;
+       int i;
+@@ -10589,7 +10636,7 @@ aspect_ratio_crop_check(bool enabled, st
+ static int
+ aspect_ratio_crop(struct ia_css_pipe *curr_pipe,
+-                  struct ia_css_resolution *effective_res)
++                struct ia_css_resolution *effective_res)
+ {
+       int err = 0;
+       struct ia_css_resolution crop_res;
+@@ -10649,7 +10696,7 @@ aspect_ratio_crop(struct ia_css_pipe *cu
+       case IA_CSS_PIPE_MODE_YUVPP:
+       default:
+               IA_CSS_ERROR("aspect ratio cropping invalid args: mode[%d]\n",
+-                              curr_pipe->config.mode);
++                           curr_pipe->config.mode);
+               assert(0);
+               break;
+       }
+@@ -10713,7 +10760,7 @@ static struct sh_css_hmm_buffer_record
+       assert(h_vbuf);
+       assert((type > IA_CSS_BUFFER_TYPE_INVALID) &&
+-              (type < IA_CSS_NUM_DYNAMIC_BUFFER_TYPE));
++             (type < IA_CSS_NUM_DYNAMIC_BUFFER_TYPE));
+       assert(kernel_ptr != 0);
+       buffer_record = &hmm_buffer_record[0];
diff --git a/queue-5.10/media-staging-media-atomisp-fix-sh_css.c-brace-coding-style-issues.patch b/queue-5.10/media-staging-media-atomisp-fix-sh_css.c-brace-coding-style-issues.patch
new file mode 100644 (file)
index 0000000..8e3268a
--- /dev/null
@@ -0,0 +1,655 @@
+From stable+bounces-274530-greg=kroah.com@vger.kernel.org Tue Jul 14 22:02:29 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 16:01:54 -0400
+Subject: media: staging: media: atomisp: Fix sh_css.c brace coding style issues
+To: stable@vger.kernel.org
+Cc: Martiros Shakhzadyan <vrzh@vrzh.net>, Hans Verkuil <hverkuil-cisco@xs4all.nl>, Mauro Carvalho Chehab <mchehab+huawei@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714200158.3152137-2-sashal@kernel.org>
+
+From: Martiros Shakhzadyan <vrzh@vrzh.net>
+
+[ Upstream commit 6ceb557604e85c55bce0585216623c21c7a00453 ]
+
+Fix brace coding style issues.
+
+Signed-off-by: Martiros Shakhzadyan <vrzh@vrzh.net>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: f4d51e55dd47 ("staging: media: atomisp: reduce load_primary_binaries() stack usage")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/media/atomisp/pci/sh_css.c |  224 +++++++++++------------------
+ 1 file changed, 90 insertions(+), 134 deletions(-)
+
+--- a/drivers/staging/media/atomisp/pci/sh_css.c
++++ b/drivers/staging/media/atomisp/pci/sh_css.c
+@@ -456,15 +456,15 @@ static enum ia_css_frame_format yuv422_c
+  * by the copy binary given the stream format.
+  * */
+ static int
+-verify_copy_out_frame_format(struct ia_css_pipe *pipe) {
++verify_copy_out_frame_format(struct ia_css_pipe *pipe)
++{
+       enum ia_css_frame_format out_fmt = pipe->output_info[0].format;
+       unsigned int i, found = 0;
+       assert(pipe);
+       assert(pipe->stream);
+-      switch (pipe->stream->config.input_config.format)
+-      {
++      switch (pipe->stream->config.input_config.format) {
+       case ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY:
+       case ATOMISP_INPUT_FORMAT_YUV420_8:
+               for (i = 0; i < ARRAY_SIZE(yuv420_copy_formats) && !found; i++)
+@@ -532,7 +532,8 @@ ia_css_stream_input_format_bits_per_pixe
+ #if !defined(ISP2401)
+ static int
+-sh_css_config_input_network(struct ia_css_stream *stream) {
++sh_css_config_input_network(struct ia_css_stream *stream)
++{
+       unsigned int fmt_type;
+       struct ia_css_pipe *pipe = stream->last_pipe;
+       struct ia_css_binary *binary = NULL;
+@@ -558,8 +559,7 @@ sh_css_config_input_network(struct ia_cs
+                                       stream->config.mode);
+       if ((binary && (binary->online || stream->config.continuous)) ||
+-          pipe->config.mode == IA_CSS_PIPE_MODE_COPY)
+-      {
++          pipe->config.mode == IA_CSS_PIPE_MODE_COPY) {
+               err = ia_css_ifmtr_configure(&stream->config,
+                                            binary);
+               if (err)
+@@ -567,8 +567,7 @@ sh_css_config_input_network(struct ia_cs
+       }
+       if (stream->config.mode == IA_CSS_INPUT_MODE_TPG ||
+-          stream->config.mode == IA_CSS_INPUT_MODE_PRBS)
+-      {
++          stream->config.mode == IA_CSS_INPUT_MODE_PRBS) {
+               unsigned int hblank_cycles = 100,
+               vblank_lines = 6,
+               width,
+@@ -723,35 +722,32 @@ static bool sh_css_translate_stream_cfg_
+       switch (stream_cfg->mode) {
+       case IA_CSS_INPUT_MODE_TPG:
+-              if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID0) {
++              if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID0)
+                       isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT0_ID;
+-              } else if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID1) {
++              else if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID1)
+                       isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT1_ID;
+-              } else if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID2) {
++              else if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID2)
+                       isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT2_ID;
+-              }
+               break;
+       case IA_CSS_INPUT_MODE_PRBS:
+-              if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID0) {
++              if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID0)
+                       isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT0_ID;
+-              } else if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID1) {
++              else if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID1)
+                       isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT1_ID;
+-              } else if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID2) {
++              else if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID2)
+                       isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT2_ID;
+-              }
+               break;
+       case IA_CSS_INPUT_MODE_BUFFERED_SENSOR:
+-              if (stream_cfg->source.port.port == MIPI_PORT0_ID) {
++              if (stream_cfg->source.port.port == MIPI_PORT0_ID)
+                       isys_stream_descr->input_port_id = INPUT_SYSTEM_CSI_PORT0_ID;
+-              } else if (stream_cfg->source.port.port == MIPI_PORT1_ID) {
++              else if (stream_cfg->source.port.port == MIPI_PORT1_ID)
+                       isys_stream_descr->input_port_id = INPUT_SYSTEM_CSI_PORT1_ID;
+-              } else if (stream_cfg->source.port.port == MIPI_PORT2_ID) {
++              else if (stream_cfg->source.port.port == MIPI_PORT2_ID)
+                       isys_stream_descr->input_port_id = INPUT_SYSTEM_CSI_PORT2_ID;
+-              }
+               break;
+       default:
+@@ -804,15 +800,14 @@ static bool sh_css_translate_stream_cfg_
+       rc = true;
+       switch (stream_cfg->mode) {
+       case IA_CSS_INPUT_MODE_TPG:
+-              if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_RAMP) {
++              if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_RAMP)
+                       isys_stream_descr->tpg_port_attr.mode = PIXELGEN_TPG_MODE_RAMP;
+-              } else if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_CHECKERBOARD) {
++              else if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_CHECKERBOARD)
+                       isys_stream_descr->tpg_port_attr.mode = PIXELGEN_TPG_MODE_CHBO;
+-              } else if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_MONO) {
++              else if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_MONO)
+                       isys_stream_descr->tpg_port_attr.mode = PIXELGEN_TPG_MODE_MONO;
+-              } else {
++              else
+                       rc = false;
+-              }
+               /*
+                * TODO
+@@ -951,12 +946,12 @@ static bool sh_css_translate_stream_cfg_
+            stream_cfg->mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR) &&
+           stream_cfg->source.port.compression.type != IA_CSS_CSI2_COMPRESSION_TYPE_NONE) {
+               if (stream_cfg->source.port.compression.uncompressed_bits_per_pixel ==
+-                  UNCOMPRESSED_BITS_PER_PIXEL_10) {
++                  UNCOMPRESSED_BITS_PER_PIXEL_10)
+                       fmt_type = ATOMISP_INPUT_FORMAT_RAW_10;
+-              } else if (stream_cfg->source.port.compression.uncompressed_bits_per_pixel ==
+-                         UNCOMPRESSED_BITS_PER_PIXEL_12) {
++              else if (stream_cfg->source.port.compression.uncompressed_bits_per_pixel ==
++                         UNCOMPRESSED_BITS_PER_PIXEL_12)
+                       fmt_type = ATOMISP_INPUT_FORMAT_RAW_12;
+-              } else
++              else
+                       return false;
+       }
+@@ -1043,7 +1038,8 @@ static bool sh_css_translate_binary_info
+ }
+ static int
+-sh_css_config_input_network(struct ia_css_stream *stream) {
++sh_css_config_input_network(struct ia_css_stream *stream)
++{
+       bool                                    rc;
+       ia_css_isys_descr_t                     isys_stream_descr;
+       unsigned int                            sp_thread_id;
+@@ -1058,19 +1054,16 @@ sh_css_config_input_network(struct ia_cs
+       ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
+                           "sh_css_config_input_network() enter 0x%p:\n", stream);
+-      if (stream->config.continuous)
+-      {
+-              if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE) {
++      if (stream->config.continuous) {
++              if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE)
+                       pipe = stream->last_pipe;
+-              } else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_YUVPP) {
++              else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_YUVPP)
+                       pipe = stream->last_pipe;
+-              } else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_PREVIEW) {
++              else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_PREVIEW)
+                       pipe = stream->last_pipe->pipe_settings.preview.copy_pipe;
+-              } else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_VIDEO) {
++              else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_VIDEO)
+                       pipe = stream->last_pipe->pipe_settings.video.copy_pipe;
+-              }
+-      } else
+-      {
++      } else {
+               pipe = stream->last_pipe;
+               if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE) {
+                       /*
+@@ -1093,8 +1086,7 @@ sh_css_config_input_network(struct ia_cs
+               if (pipe->pipeline.stages->binary)
+                       binary = pipe->pipeline.stages->binary;
+-      if (binary)
+-      {
++      if (binary) {
+               /* this was being done in ifmtr in 2400.
+                * online and cont bypass the init_in_frameinfo_memory_defaults
+                * so need to do it here
+@@ -1208,11 +1200,10 @@ static inline struct ia_css_pipe *stream
+       struct ia_css_pipe *target_pipe;
+       /* get the pipe that consumes the stream */
+-      if (stream->config.continuous) {
++      if (stream->config.continuous)
+               target_pipe = stream_get_copy_pipe(stream);
+-      } else {
++      else
+               target_pipe = stream_get_last_pipe(stream);
+-      }
+       return target_pipe;
+ }
+@@ -1386,7 +1377,8 @@ start_binary(struct ia_css_pipe *pipe,
+ /* start the copy function on the SP */
+ static int
+ start_copy_on_sp(struct ia_css_pipe *pipe,
+-               struct ia_css_frame *out_frame) {
++               struct ia_css_frame *out_frame)
++{
+       (void)out_frame;
+       assert(pipe);
+       assert(pipe->stream);
+@@ -1404,8 +1396,7 @@ start_copy_on_sp(struct ia_css_pipe *pip
+       sh_css_sp_start_binary_copy(ia_css_pipe_get_pipe_num(pipe), out_frame, pipe->stream->config.pixels_per_clock == 2);
+ #if !defined(ISP2401)
+-      if (pipe->stream->reconfigure_css_rx)
+-      {
++      if (pipe->stream->reconfigure_css_rx) {
+               ia_css_isys_rx_configure(&pipe->stream->csi_rx_config,
+                                        pipe->stream->config.mode);
+               pipe->stream->reconfigure_css_rx = false;
+@@ -1594,7 +1585,8 @@ ia_css_reset_defaults(struct sh_css *css
+ int
+ ia_css_load_firmware(struct device *dev, const struct ia_css_env *env,
+-                   const struct ia_css_fw  *fw) {
++                   const struct ia_css_fw  *fw)
++{
+       int err;
+       if (!env)
+@@ -1605,16 +1597,14 @@ ia_css_load_firmware(struct device *dev,
+       ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_load_firmware() enter\n");
+       /* make sure we initialize my_css */
+-      if (my_css.flush != env->cpu_mem_env.flush)
+-      {
++      if (my_css.flush != env->cpu_mem_env.flush) {
+               ia_css_reset_defaults(&my_css);
+               my_css.flush = env->cpu_mem_env.flush;
+       }
+       ia_css_unload_firmware(); /* in case we are called twice */
+       err = sh_css_load_firmware(dev, fw->data, fw->bytes);
+-      if (!err)
+-      {
++      if (!err) {
+               err = ia_css_binary_init_infos();
+               if (!err)
+                       fw_explicitly_loaded = true;
+@@ -1628,7 +1618,8 @@ int
+ ia_css_init(struct device *dev, const struct ia_css_env *env,
+           const struct ia_css_fw  *fw,
+           u32                 mmu_l1_base,
+-          enum ia_css_irq_type     irq_type) {
++          enum ia_css_irq_type     irq_type)
++{
+       int err;
+       ia_css_spctrl_cfg spctrl_cfg;
+@@ -1702,16 +1693,14 @@ ia_css_init(struct device *dev, const st
+       my_css.flush     = flush_func;
+       err = ia_css_rmgr_init();
+-      if (err)
+-      {
++      if (err) {
+               IA_CSS_LEAVE_ERR(err);
+               return err;
+       }
+       IA_CSS_LOG("init: %d", my_css_save_initialized);
+-      if (!my_css_save_initialized)
+-      {
++      if (!my_css_save_initialized) {
+               my_css_save_initialized = true;
+               my_css_save.mode = sh_css_mode_working;
+               memset(my_css_save.stream_seeds, 0,
+@@ -1739,19 +1728,16 @@ ia_css_init(struct device *dev, const st
+       gpio_reg_store(GPIO0_ID, _gpio_block_reg_do_0, 0);
+       err = ia_css_refcount_init(REFCOUNT_SIZE);
+-      if (err)
+-      {
++      if (err) {
+               IA_CSS_LEAVE_ERR(err);
+               return err;
+       }
+       err = sh_css_params_init();
+-      if (err)
+-      {
++      if (err) {
+               IA_CSS_LEAVE_ERR(err);
+               return err;
+       }
+-      if (fw)
+-      {
++      if (fw) {
+               ia_css_unload_firmware(); /* in case we already had firmware loaded */
+               err = sh_css_load_firmware(dev, fw->data, fw->bytes);
+               if (err) {
+@@ -1772,23 +1758,20 @@ ia_css_init(struct device *dev, const st
+               return -EINVAL;
+       err = ia_css_spctrl_load_fw(SP0_ID, &spctrl_cfg);
+-      if (err)
+-      {
++      if (err) {
+               IA_CSS_LEAVE_ERR(err);
+               return err;
+       }
+ #if WITH_PC_MONITORING
+-      if (!thread_alive)
+-      {
++      if (!thread_alive) {
+               thread_alive++;
+               sh_css_print("PC_MONITORING: %s() -- create thread DISABLED\n",
+                            __func__);
+               spying_thread_create();
+       }
+ #endif
+-      if (!sh_css_hrt_system_is_idle())
+-      {
++      if (!sh_css_hrt_system_is_idle()) {
+               IA_CSS_LEAVE_ERR(-EBUSY);
+               return -EBUSY;
+       }
+@@ -1821,7 +1804,8 @@ ia_css_init(struct device *dev, const st
+ }
+ int
+-ia_css_enable_isys_event_queue(bool enable) {
++ia_css_enable_isys_event_queue(bool enable)
++{
+       if (sh_css_sp_is_running())
+               return -EBUSY;
+       sh_css_sp_enable_isys_event_queue(enable);
+@@ -1842,7 +1826,8 @@ sh_css_flush(struct ia_css_acc_fw *fw)
+  * doing it from stream_create since we could run out of sp threads due to
+  * allocation on inactive pipelines. */
+ static int
+-map_sp_threads(struct ia_css_stream *stream, bool map) {
++map_sp_threads(struct ia_css_stream *stream, bool map)
++{
+       struct ia_css_pipe *main_pipe = NULL;
+       struct ia_css_pipe *copy_pipe = NULL;
+       struct ia_css_pipe *capture_pipe = NULL;
+@@ -1854,8 +1839,7 @@ map_sp_threads(struct ia_css_stream *str
+       IA_CSS_ENTER_PRIVATE("stream = %p, map = %s",
+                            stream, map ? "true" : "false");
+-      if (!stream)
+-      {
++      if (!stream) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+       }
+@@ -1865,8 +1849,7 @@ map_sp_threads(struct ia_css_stream *str
+       ia_css_pipeline_map(main_pipe->pipe_num, map);
+-      switch (pipe_id)
+-      {
++      switch (pipe_id) {
+       case IA_CSS_PIPE_ID_PREVIEW:
+               copy_pipe    = main_pipe->pipe_settings.preview.copy_pipe;
+               capture_pipe = main_pipe->pipe_settings.preview.capture_pipe;
+@@ -1885,23 +1868,17 @@ map_sp_threads(struct ia_css_stream *str
+       }
+       if (acc_pipe)
+-      {
+               ia_css_pipeline_map(acc_pipe->pipe_num, map);
+-      }
+       if (capture_pipe)
+-      {
+               ia_css_pipeline_map(capture_pipe->pipe_num, map);
+-      }
+       /* Firmware expects copy pipe to be the last pipe mapped. (if needed) */
+       if (copy_pipe)
+-      {
+               ia_css_pipeline_map(copy_pipe->pipe_num, map);
+-      }
++
+       /* DH regular multi pipe - not continuous mode: map the next pipes too */
+-      if (!stream->config.continuous)
+-      {
++      if (!stream->config.continuous) {
+               int i;
+               for (i = 1; i < stream->num_pipes; i++)
+@@ -1915,7 +1892,8 @@ map_sp_threads(struct ia_css_stream *str
+ /* creates a host pipeline skeleton for all pipes in a stream. Called during
+  * stream_create. */
+ static int
+-create_host_pipeline_structure(struct ia_css_stream *stream) {
++create_host_pipeline_structure(struct ia_css_stream *stream)
++{
+       struct ia_css_pipe *copy_pipe = NULL, *capture_pipe = NULL;
+       struct ia_css_pipe *acc_pipe = NULL;
+       enum ia_css_pipe_id pipe_id;
+@@ -1927,24 +1905,21 @@ create_host_pipeline_structure(struct ia
+       assert(stream);
+       IA_CSS_ENTER_PRIVATE("stream = %p", stream);
+-      if (!stream)
+-      {
++      if (!stream) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+       }
+       main_pipe       = stream->last_pipe;
+       assert(main_pipe);
+-      if (!main_pipe)
+-      {
++      if (!main_pipe) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+       }
+       pipe_id = main_pipe->mode;
+-      switch (pipe_id)
+-      {
++      switch (pipe_id) {
+       case IA_CSS_PIPE_ID_PREVIEW:
+               copy_pipe    = main_pipe->pipe_settings.preview.copy_pipe;
+               copy_pipe_delay = main_pipe->dvs_frame_delay;
+@@ -1984,30 +1959,23 @@ create_host_pipeline_structure(struct ia
+       }
+       if (!(err) && copy_pipe)
+-      {
+               err = ia_css_pipeline_create(&copy_pipe->pipeline,
+                                            copy_pipe->mode,
+                                            copy_pipe->pipe_num,
+                                            copy_pipe_delay);
+-      }
+       if (!(err) && capture_pipe)
+-      {
+               err = ia_css_pipeline_create(&capture_pipe->pipeline,
+                                            capture_pipe->mode,
+                                            capture_pipe->pipe_num,
+                                            capture_pipe_delay);
+-      }
+       if (!(err) && acc_pipe)
+-      {
+               err = ia_css_pipeline_create(&acc_pipe->pipeline, acc_pipe->mode,
+                                            acc_pipe->pipe_num, main_pipe->dvs_frame_delay);
+-      }
+       /* DH regular multi pipe - not continuous mode: create the next pipelines too */
+-      if (!stream->config.continuous)
+-      {
++      if (!stream->config.continuous) {
+               int i;
+               for (i = 1; i < stream->num_pipes && 0 == err; i++) {
+@@ -2026,7 +1994,8 @@ create_host_pipeline_structure(struct ia
+ /* creates a host pipeline for all pipes in a stream. Called during
+  * stream_start. */
+ static int
+-create_host_pipeline(struct ia_css_stream *stream) {
++create_host_pipeline(struct ia_css_stream *stream)
++{
+       struct ia_css_pipe *copy_pipe = NULL, *capture_pipe = NULL;
+       struct ia_css_pipe *acc_pipe = NULL;
+       enum ia_css_pipe_id pipe_id;
+@@ -2035,8 +2004,7 @@ create_host_pipeline(struct ia_css_strea
+       unsigned int max_input_width = 0;
+       IA_CSS_ENTER_PRIVATE("stream = %p", stream);
+-      if (!stream)
+-      {
++      if (!stream) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+       }
+@@ -2047,8 +2015,7 @@ create_host_pipeline(struct ia_css_strea
+       /* No continuous frame allocation for capture pipe. It uses the
+        * "main" pipe's frames. */
+       if ((pipe_id == IA_CSS_PIPE_ID_PREVIEW) ||
+-          (pipe_id == IA_CSS_PIPE_ID_VIDEO))
+-      {
++          (pipe_id == IA_CSS_PIPE_ID_VIDEO)) {
+               /* About pipe_id == IA_CSS_PIPE_ID_PREVIEW && stream->config.mode != IA_CSS_INPUT_MODE_MEMORY:
+                * The original condition pipe_id == IA_CSS_PIPE_ID_PREVIEW is too strong. E.g. in SkyCam (with memory
+                * based input frames) there is no continuous mode and thus no need for allocated continuous frames
+@@ -2066,24 +2033,21 @@ create_host_pipeline(struct ia_css_strea
+ #if !defined(ISP2401)
+       /* old isys: need to allocate_mipi_frames() even in IA_CSS_PIPE_MODE_COPY */
+-      if (pipe_id != IA_CSS_PIPE_ID_ACC)
+-      {
++      if (pipe_id != IA_CSS_PIPE_ID_ACC) {
+               err = allocate_mipi_frames(main_pipe, &stream->info);
+               if (err)
+                       goto ERR;
+       }
+ #elif defined(ISP2401)
+       if ((pipe_id != IA_CSS_PIPE_ID_ACC) &&
+-          (main_pipe->config.mode != IA_CSS_PIPE_MODE_COPY))
+-      {
++          (main_pipe->config.mode != IA_CSS_PIPE_MODE_COPY)) {
+               err = allocate_mipi_frames(main_pipe, &stream->info);
+               if (err)
+                       goto ERR;
+       }
+ #endif
+-      switch (pipe_id)
+-      {
++      switch (pipe_id) {
+       case IA_CSS_PIPE_ID_PREVIEW:
+               copy_pipe    = main_pipe->pipe_settings.preview.copy_pipe;
+               capture_pipe = main_pipe->pipe_settings.preview.capture_pipe;
+@@ -2133,31 +2097,27 @@ create_host_pipeline(struct ia_css_strea
+       if (err)
+               goto ERR;
+-      if (copy_pipe)
+-      {
++      if (copy_pipe) {
+               err = create_host_copy_pipeline(copy_pipe, max_input_width,
+                                               main_pipe->continuous_frames[0]);
+               if (err)
+                       goto ERR;
+       }
+-      if (capture_pipe)
+-      {
++      if (capture_pipe) {
+               err = create_host_capture_pipeline(capture_pipe);
+               if (err)
+                       goto ERR;
+       }
+-      if (acc_pipe)
+-      {
++      if (acc_pipe) {
+               err = create_host_acc_pipeline(acc_pipe);
+               if (err)
+                       goto ERR;
+       }
+       /* DH regular multi pipe - not continuous mode: create the next pipelines too */
+-      if (!stream->config.continuous)
+-      {
++      if (!stream->config.continuous) {
+               int i;
+               for (i = 1; i < stream->num_pipes && 0 == err; i++) {
+@@ -2199,10 +2159,10 @@ static const struct ia_css_yuvpp_setting
+ static int
+ init_pipe_defaults(enum ia_css_pipe_mode mode,
+                  struct ia_css_pipe *pipe,
+-                 bool copy_pipe) {
++                 bool copy_pipe)
++{
+-      if (!pipe)
+-      {
++      if (!pipe) {
+               IA_CSS_ERROR("NULL pipe parameter");
+               return -EINVAL;
+       }
+@@ -2211,18 +2171,17 @@ init_pipe_defaults(enum ia_css_pipe_mode
+       memcpy(pipe, &default_pipe, sizeof(default_pipe));
+       /* TODO: JB should not be needed, but temporary backward reference */
+-      switch (mode)
+-      {
++      switch (mode) {
+       case IA_CSS_PIPE_MODE_PREVIEW:
+               pipe->mode = IA_CSS_PIPE_ID_PREVIEW;
+               memcpy(&pipe->pipe_settings.preview, &preview, sizeof(preview));
+               break;
+       case IA_CSS_PIPE_MODE_CAPTURE:
+-              if (copy_pipe) {
++              if (copy_pipe)
+                       pipe->mode = IA_CSS_PIPE_ID_COPY;
+-              } else {
++              else
+                       pipe->mode = IA_CSS_PIPE_ID_CAPTURE;
+-              }
++
+               memcpy(&pipe->pipe_settings.capture, &capture, sizeof(capture));
+               break;
+       case IA_CSS_PIPE_MODE_VIDEO:
+@@ -2252,27 +2211,25 @@ pipe_global_init(void)
+       u8 i;
+       my_css.pipe_counter = 0;
+-      for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++) {
++      for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++)
+               my_css.all_pipes[i] = NULL;
+-      }
+ }
+ static int
+ pipe_generate_pipe_num(const struct ia_css_pipe *pipe,
+-                     unsigned int *pipe_number) {
++                     unsigned int *pipe_number)
++{
+       const u8 INVALID_PIPE_NUM = (uint8_t)~(0);
+       u8 pipe_num = INVALID_PIPE_NUM;
+       u8 i;
+-      if (!pipe)
+-      {
++      if (!pipe) {
+               IA_CSS_ERROR("NULL pipe parameter");
+               return -EINVAL;
+       }
+       /* Assign a new pipe_num .... search for empty place */
+-      for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++)
+-      {
++      for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++) {
+               if (!my_css.all_pipes[i]) {
+                       /*position is reserved */
+                       my_css.all_pipes[i] = (struct ia_css_pipe *)pipe;
+@@ -2280,8 +2237,7 @@ pipe_generate_pipe_num(const struct ia_c
+                       break;
+               }
+       }
+-      if (pipe_num == INVALID_PIPE_NUM)
+-      {
++      if (pipe_num == INVALID_PIPE_NUM) {
+               /* Max number of pipes already allocated */
+               IA_CSS_ERROR("Max number of pipes already created");
+               return -ENOSPC;
diff --git a/queue-5.10/media-staging-media-atomisp-fix-the-rest-of-sh_css.c-brace-issues.patch b/queue-5.10/media-staging-media-atomisp-fix-the-rest-of-sh_css.c-brace-issues.patch
new file mode 100644 (file)
index 0000000..98c2aab
--- /dev/null
@@ -0,0 +1,3438 @@
+From stable+bounces-274532-greg=kroah.com@vger.kernel.org Tue Jul 14 22:02:41 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 16:01:55 -0400
+Subject: media: staging: media: atomisp: Fix the rest of sh_css.c brace issues
+To: stable@vger.kernel.org
+Cc: Martiros Shakhzadyan <vrzh@vrzh.net>, Hans Verkuil <hverkuil-cisco@xs4all.nl>, Mauro Carvalho Chehab <mchehab+huawei@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714200158.3152137-3-sashal@kernel.org>
+
+From: Martiros Shakhzadyan <vrzh@vrzh.net>
+
+[ Upstream commit 7394bf6d3c1e8316484fcf3a9d71daaab489f211 ]
+
+Fix the remainder of brace coding style issues.
+
+Signed-off-by: Martiros Shakhzadyan <vrzh@vrzh.net>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: f4d51e55dd47 ("staging: media: atomisp: reduce load_primary_binaries() stack usage")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/media/atomisp/pci/sh_css.c | 1134 ++++++++++++-----------------
+ 1 file changed, 498 insertions(+), 636 deletions(-)
+
+--- a/drivers/staging/media/atomisp/pci/sh_css.c
++++ b/drivers/staging/media/atomisp/pci/sh_css.c
+@@ -1101,8 +1101,7 @@ sh_css_config_input_network(struct ia_cs
+       /* get the target input terminal */
+       sp_pipeline_input_terminal = &sh_css_sp_group.pipe_io[sp_thread_id].input;
+-      for (i = 0; i < IA_CSS_STREAM_MAX_ISYS_STREAM_PER_CH; i++)
+-      {
++      for (i = 0; i < IA_CSS_STREAM_MAX_ISYS_STREAM_PER_CH; i++) {
+               /* initialization */
+               memset((void *)(&isys_stream_descr), 0, sizeof(ia_css_isys_descr_t));
+               sp_pipeline_input_terminal->context.virtual_input_system_stream[i].valid = 0;
+@@ -2161,7 +2160,6 @@ init_pipe_defaults(enum ia_css_pipe_mode
+                  struct ia_css_pipe *pipe,
+                  bool copy_pipe)
+ {
+-
+       if (!pipe) {
+               IA_CSS_ERROR("NULL pipe parameter");
+               return -EINVAL;
+@@ -2263,12 +2261,12 @@ pipe_release_pipe_num(unsigned int pipe_
+ static int
+ create_pipe(enum ia_css_pipe_mode mode,
+           struct ia_css_pipe **pipe,
+-          bool copy_pipe) {
++          bool copy_pipe)
++{
+       int err = 0;
+       struct ia_css_pipe *me;
+-      if (!pipe)
+-      {
++      if (!pipe) {
+               IA_CSS_ERROR("NULL pipe parameter");
+               return -EINVAL;
+       }
+@@ -2278,15 +2276,13 @@ create_pipe(enum ia_css_pipe_mode mode,
+               return -ENOMEM;
+       err = init_pipe_defaults(mode, me, copy_pipe);
+-      if (err)
+-      {
++      if (err) {
+               kfree(me);
+               return err;
+       }
+       err = pipe_generate_pipe_num(me, &me->pipe_num);
+-      if (err)
+-      {
++      if (err) {
+               kfree(me);
+               return err;
+       }
+@@ -2332,26 +2328,24 @@ static void sh_css_pipe_free_acc_binarie
+ }
+ int
+-ia_css_pipe_destroy(struct ia_css_pipe *pipe) {
++ia_css_pipe_destroy(struct ia_css_pipe *pipe)
++{
+       int err = 0;
+       IA_CSS_ENTER("pipe = %p", pipe);
+-      if (!pipe)
+-      {
++      if (!pipe) {
+               IA_CSS_LEAVE_ERR(-EINVAL);
+               return -EINVAL;
+       }
+-      if (pipe->stream)
+-      {
++      if (pipe->stream) {
+               IA_CSS_LOG("ia_css_stream_destroy not called!");
+               IA_CSS_LEAVE_ERR(-EINVAL);
+               return -EINVAL;
+       }
+-      switch (pipe->config.mode)
+-      {
++      switch (pipe->config.mode) {
+       case IA_CSS_PIPE_MODE_PREVIEW:
+               /* need to take into account that this function is also called
+                  on the internal copy pipe */
+@@ -2415,9 +2409,8 @@ ia_css_pipe_destroy(struct ia_css_pipe *
+       /* Temporarily, not every sh_css_pipe has an acc_extension. */
+       if (pipe->config.acc_extension)
+-      {
+               ia_css_pipe_unload_extension(pipe, pipe->config.acc_extension);
+-      }
++
+       kfree(pipe);
+       IA_CSS_LEAVE("err = %d", err);
+       return err;
+@@ -2447,9 +2440,9 @@ ia_css_uninit(void)
+       ifmtr_set_if_blocking_mode_reset = true;
+ #endif
+-      if (!fw_explicitly_loaded) {
++      if (!fw_explicitly_loaded)
+               ia_css_unload_firmware();
+-      }
++
+       ia_css_spctrl_unload_fw(SP0_ID);
+       sh_css_sp_set_sp_running(false);
+       /* check and free any remaining mipi frames */
+@@ -2636,7 +2629,8 @@ static int load_copy_binary(
+ static int
+ alloc_continuous_frames(
+-    struct ia_css_pipe *pipe, bool init_time) {
++    struct ia_css_pipe *pipe, bool init_time)
++{
+       int err = 0;
+       struct ia_css_frame_info ref_info;
+       enum ia_css_pipe_id pipe_id;
+@@ -2646,8 +2640,7 @@ alloc_continuous_frames(
+       IA_CSS_ENTER_PRIVATE("pipe = %p, init_time = %d", pipe, init_time);
+-      if ((!pipe) || (!pipe->stream))
+-      {
++      if ((!pipe) || (!pipe->stream)) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+       }
+@@ -2655,26 +2648,22 @@ alloc_continuous_frames(
+       pipe_id = pipe->mode;
+       continuous = pipe->stream->config.continuous;
+-      if (continuous)
+-      {
++      if (continuous) {
+               if (init_time) {
+                       num_frames = pipe->stream->config.init_num_cont_raw_buf;
+                       pipe->stream->continuous_pipe = pipe;
+-              } else
++              } else {
+                       num_frames = pipe->stream->config.target_num_cont_raw_buf;
+-      } else
+-      {
++              }
++      } else {
+               num_frames = NUM_ONLINE_INIT_CONTINUOUS_FRAMES;
+       }
+-      if (pipe_id == IA_CSS_PIPE_ID_PREVIEW)
+-      {
++      if (pipe_id == IA_CSS_PIPE_ID_PREVIEW) {
+               ref_info = pipe->pipe_settings.preview.preview_binary.in_frame_info;
+-      } else if (pipe_id == IA_CSS_PIPE_ID_VIDEO)
+-      {
++      } else if (pipe_id == IA_CSS_PIPE_ID_VIDEO) {
+               ref_info = pipe->pipe_settings.video.video_binary.in_frame_info;
+-      } else
+-      {
++      } else {
+               /* should not happen */
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+@@ -2690,8 +2679,7 @@ alloc_continuous_frames(
+ #endif
+ #if !defined(HAS_NO_PACKED_RAW_PIXELS)
+-      if (pipe->stream->config.pack_raw_pixels)
+-      {
++      if (pipe->stream->config.pack_raw_pixels) {
+               ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
+                                   "alloc_continuous_frames() IA_CSS_FRAME_FORMAT_RAW_PACKED\n");
+               ref_info.format = IA_CSS_FRAME_FORMAT_RAW_PACKED;
+@@ -2720,8 +2708,7 @@ alloc_continuous_frames(
+       else
+               idx = pipe->stream->config.init_num_cont_raw_buf;
+-      for (i = idx; i < NUM_CONTINUOUS_FRAMES; i++)
+-      {
++      for (i = idx; i < NUM_CONTINUOUS_FRAMES; i++) {
+               /* free previous frame */
+               if (pipe->continuous_frames[i]) {
+                       ia_css_frame_free(pipe->continuous_frames[i]);
+@@ -2751,14 +2738,16 @@ alloc_continuous_frames(
+ }
+ int
+-ia_css_alloc_continuous_frame_remain(struct ia_css_stream *stream) {
++ia_css_alloc_continuous_frame_remain(struct ia_css_stream *stream)
++{
+       if (!stream)
+               return -EINVAL;
+       return alloc_continuous_frames(stream->continuous_pipe, false);
+ }
+ static int
+-load_preview_binaries(struct ia_css_pipe *pipe) {
++load_preview_binaries(struct ia_css_pipe *pipe)
++{
+       struct ia_css_frame_info prev_in_info,
+               prev_bds_out_info,
+               prev_out_info,
+@@ -2866,8 +2855,7 @@ load_preview_binaries(struct ia_css_pipe
+        * then the preview binary selection is done again.
+        */
+       if (need_vf_pp &&
+-          (mycs->preview_binary.out_frame_info[0].format != IA_CSS_FRAME_FORMAT_YUV_LINE))
+-      {
++          (mycs->preview_binary.out_frame_info[0].format != IA_CSS_FRAME_FORMAT_YUV_LINE)) {
+               /* Preview step 2 */
+               if (pipe->vf_yuv_ds_input_info.res.width)
+                       prev_vf_info = pipe->vf_yuv_ds_input_info;
+@@ -2892,8 +2880,7 @@ load_preview_binaries(struct ia_css_pipe
+                       return err;
+       }
+-      if (need_vf_pp)
+-      {
++      if (need_vf_pp) {
+               struct ia_css_binary_descr vf_pp_descr;
+               /* Viewfinder post-processing */
+@@ -2924,8 +2911,7 @@ load_preview_binaries(struct ia_css_pipe
+ #endif
+       /* Copy */
+-      if (need_isp_copy_binary)
+-      {
++      if (need_isp_copy_binary) {
+               err = load_copy_binary(pipe,
+                                      &mycs->copy_binary,
+                                      &mycs->preview_binary);
+@@ -2933,8 +2919,7 @@ load_preview_binaries(struct ia_css_pipe
+                       return err;
+       }
+-      if (pipe->shading_table)
+-      {
++      if (pipe->shading_table) {
+               ia_css_shading_table_free(pipe->shading_table);
+               pipe->shading_table = NULL;
+       }
+@@ -2949,11 +2934,11 @@ ia_css_binary_unload(struct ia_css_binar
+ }
+ static int
+-unload_preview_binaries(struct ia_css_pipe *pipe) {
++unload_preview_binaries(struct ia_css_pipe *pipe)
++{
+       IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
+-      if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW))
+-      {
++      if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW)) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+       }
+@@ -3006,15 +2991,15 @@ static int add_firmwares(
+               struct ia_css_frame *in = NULL;
+               struct ia_css_frame *vf = NULL;
+-              if ((fw == last_fw) && (fw->info.isp.sp.enable.out_frame  != 0)) {
++              if ((fw == last_fw) && (fw->info.isp.sp.enable.out_frame  != 0))
+                       out[0] = out_frame;
+-              }
+-              if (fw->info.isp.sp.enable.in_frame != 0) {
++
++              if (fw->info.isp.sp.enable.in_frame != 0)
+                       in = in_frame;
+-              }
+-              if (fw->info.isp.sp.enable.out_frame != 0) {
++
++              if (fw->info.isp.sp.enable.out_frame != 0)
+                       vf = vf_frame;
+-              }
++
+               ia_css_pipe_get_firmwares_stage_desc(&stage_desc, binary,
+                                                    out, in, vf, fw, binary_mode);
+               err = ia_css_pipeline_create_and_add_stage(me,
+@@ -3228,7 +3213,8 @@ static void sh_css_setup_queues(void)
+ static int
+ init_vf_frameinfo_defaults(struct ia_css_pipe *pipe,
+-                         struct ia_css_frame *vf_frame, unsigned int idx) {
++                         struct ia_css_frame *vf_frame, unsigned int idx)
++{
+       int err = 0;
+       unsigned int thread_id;
+       enum sh_css_queue_id queue_id;
+@@ -3393,7 +3379,8 @@ ia_css_get_crop_offsets(
+ static int
+ init_in_frameinfo_memory_defaults(struct ia_css_pipe *pipe,
+-                                struct ia_css_frame *frame, enum ia_css_frame_format format) {
++                                struct ia_css_frame *frame, enum ia_css_frame_format format)
++{
+       struct ia_css_frame *in_frame;
+       int err = 0;
+       unsigned int thread_id;
+@@ -3434,7 +3421,8 @@ init_in_frameinfo_memory_defaults(struct
+ static int
+ init_out_frameinfo_defaults(struct ia_css_pipe *pipe,
+-                          struct ia_css_frame *out_frame, unsigned int idx) {
++                          struct ia_css_frame *out_frame, unsigned int idx)
++{
+       int err = 0;
+       unsigned int thread_id;
+       enum sh_css_queue_id queue_id;
+@@ -3665,14 +3653,14 @@ ERR:
+ }
+ static int
+-create_host_acc_pipeline(struct ia_css_pipe *pipe) {
++create_host_acc_pipeline(struct ia_css_pipe *pipe)
++{
+       int err = 0;
+       const struct ia_css_fw_info *fw;
+       unsigned int i;
+       IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
+-      if ((!pipe) || (!pipe->stream))
+-      {
++      if ((!pipe) || (!pipe->stream)) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+       }
+@@ -3683,15 +3671,13 @@ create_host_acc_pipeline(struct ia_css_p
+               pipe->pipeline.pipe_qos_config = 0;
+       fw = pipe->vf_stage;
+-      for (i = 0; fw; fw = fw->next)
+-      {
++      for (i = 0; fw; fw = fw->next) {
+               err = sh_css_pipeline_add_acc_stage(&pipe->pipeline, fw);
+               if (err)
+                       goto ERR;
+       }
+-      for (i = 0; i < pipe->config.num_acc_stages; i++)
+-      {
++      for (i = 0; i < pipe->config.num_acc_stages; i++) {
+               struct ia_css_fw_info *fw = pipe->config.acc_stages[i];
+               err = sh_css_pipeline_add_acc_stage(&pipe->pipeline, fw);
+@@ -3708,7 +3694,8 @@ ERR:
+ /* Create stages for preview */
+ static int
+-create_host_preview_pipeline(struct ia_css_pipe *pipe) {
++create_host_preview_pipeline(struct ia_css_pipe *pipe)
++{
+       struct ia_css_pipeline_stage *copy_stage = NULL;
+       struct ia_css_pipeline_stage *preview_stage = NULL;
+       struct ia_css_pipeline_stage *vf_pp_stage = NULL;
+@@ -3728,8 +3715,7 @@ create_host_preview_pipeline(struct ia_c
+ #endif
+       IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
+-      if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW))
+-      {
++      if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW)) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+       }
+@@ -3757,16 +3743,14 @@ create_host_preview_pipeline(struct ia_c
+       /* Construct in_frame info (only in case we have dynamic input */
+       need_in_frameinfo_memory = pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY;
+ #endif
+-      if (need_in_frameinfo_memory)
+-      {
++      if (need_in_frameinfo_memory) {
+               err = init_in_frameinfo_memory_defaults(pipe, &me->in_frame,
+                                                       IA_CSS_FRAME_FORMAT_RAW);
+               if (err)
+                       goto ERR;
+               in_frame = &me->in_frame;
+-      } else
+-      {
++      } else {
+               in_frame = NULL;
+       }
+@@ -3780,8 +3764,7 @@ create_host_preview_pipeline(struct ia_c
+       if (pipe->pipe_settings.preview.vf_pp_binary.info)
+               vf_pp_binary = &pipe->pipe_settings.preview.vf_pp_binary;
+-      if (pipe->pipe_settings.preview.copy_binary.info)
+-      {
++      if (pipe->pipe_settings.preview.copy_binary.info) {
+               ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
+               ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
+                                                  out_frames, NULL, NULL);
+@@ -3796,21 +3779,19 @@ create_host_preview_pipeline(struct ia_c
+               /* When continuous is enabled, configure in_frame with the
+                * last pipe, which is the copy pipe.
+                */
+-              if (continuous || !online) {
++              if (continuous || !online)
+                       in_frame = pipe->stream->last_pipe->continuous_frames[0];
+-              }
++
+ #else
+               in_frame = pipe->continuous_frames[0];
+ #endif
+       }
+-      if (vf_pp_binary)
+-      {
++      if (vf_pp_binary) {
+               ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
+               ia_css_pipe_get_generic_stage_desc(&stage_desc, preview_binary,
+                                                  out_frames, in_frame, NULL);
+-      } else
+-      {
++      } else {
+               ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
+               ia_css_pipe_get_generic_stage_desc(&stage_desc, preview_binary,
+                                                  out_frames, in_frame, NULL);
+@@ -3824,14 +3805,12 @@ create_host_preview_pipeline(struct ia_c
+       preview_stage->args.copy_vf =
+           preview_binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_COPY;
+       preview_stage->args.copy_output = !preview_stage->args.copy_vf;
+-      if (preview_stage->args.copy_vf && !preview_stage->args.out_vf_frame)
+-      {
++      if (preview_stage->args.copy_vf && !preview_stage->args.out_vf_frame) {
+               /* in case of copy, use the vf frame as output frame */
+               preview_stage->args.out_vf_frame =
+                   preview_stage->args.out_frame[0];
+       }
+-      if (vf_pp_binary)
+-      {
++      if (vf_pp_binary) {
+               if (preview_binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_COPY)
+                       in_frame = preview_stage->args.out_vf_frame;
+               else
+@@ -3871,7 +3850,8 @@ static void send_raw_frames(struct ia_cs
+ }
+ static int
+-preview_start(struct ia_css_pipe *pipe) {
++preview_start(struct ia_css_pipe *pipe)
++{
+       int err = 0;
+       struct ia_css_pipe *copy_pipe, *capture_pipe;
+       struct ia_css_pipe *acc_pipe;
+@@ -3881,8 +3861,7 @@ preview_start(struct ia_css_pipe *pipe)
+       const struct ia_css_isp_parameters *params = NULL;
+       IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
+-      if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW))
+-      {
++      if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW)) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+       }
+@@ -3909,8 +3888,7 @@ preview_start(struct ia_css_pipe *pipe)
+               ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
+               copy_ovrd = 1 << thread_id;
+-              if (pipe->stream->cont_capt)
+-              {
++              if (pipe->stream->cont_capt) {
+                       ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(capture_pipe),
+                                                        &thread_id);
+                       copy_ovrd |= 1 << thread_id;
+@@ -3923,8 +3901,7 @@ preview_start(struct ia_css_pipe *pipe)
+       }
+       /* Construct and load the copy pipe */
+-      if (pipe->stream->config.continuous)
+-      {
++      if (pipe->stream->config.continuous) {
+               sh_css_sp_init_pipeline(&copy_pipe->pipeline,
+                                       IA_CSS_PIPE_ID_COPY,
+                                       (uint8_t)ia_css_pipe_get_pipe_num(copy_pipe),
+@@ -3945,8 +3922,7 @@ preview_start(struct ia_css_pipe *pipe)
+       }
+       /* Construct and load the capture pipe */
+-      if (pipe->stream->cont_capt)
+-      {
++      if (pipe->stream->cont_capt) {
+               sh_css_sp_init_pipeline(&capture_pipe->pipeline,
+                                       IA_CSS_PIPE_ID_CAPTURE,
+                                       (uint8_t)ia_css_pipe_get_pipe_num(capture_pipe),
+@@ -3964,8 +3940,7 @@ preview_start(struct ia_css_pipe *pipe)
+                                       params);
+       }
+-      if (acc_pipe)
+-      {
++      if (acc_pipe) {
+               sh_css_sp_init_pipeline(&acc_pipe->pipeline,
+                                       IA_CSS_PIPE_ID_ACC,
+                                       (uint8_t)ia_css_pipe_get_pipe_num(acc_pipe),
+@@ -3991,7 +3966,8 @@ preview_start(struct ia_css_pipe *pipe)
+ int
+ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
+-                         const struct ia_css_buffer *buffer) {
++                         const struct ia_css_buffer *buffer)
++{
+       int return_err = 0;
+       unsigned int thread_id;
+       enum sh_css_queue_id queue_id;
+@@ -4006,8 +3982,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+       IA_CSS_ENTER("pipe=%p, buffer=%p", pipe, buffer);
+-      if ((!pipe) || (!buffer))
+-      {
++      if ((!pipe) || (!buffer)) {
+               IA_CSS_LEAVE_ERR(-EINVAL);
+               return -EINVAL;
+       }
+@@ -4016,8 +3991,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+       /* following code will be enabled when IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME
+          is removed */
+ #if 0
+-      if (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)
+-      {
++      if (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME) {
+               bool found_pipe = false;
+               for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
+@@ -4031,8 +4005,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+               if (!found_pipe)
+                       return -EINVAL;
+       }
+-      if (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME)
+-      {
++      if (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME) {
+               bool found_pipe = false;
+               for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
+@@ -4055,34 +4028,29 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+       assert(buf_type < IA_CSS_NUM_DYNAMIC_BUFFER_TYPE);
+       if ((buf_type == IA_CSS_BUFFER_TYPE_INVALID) ||
+           (buf_type >= IA_CSS_NUM_DYNAMIC_BUFFER_TYPE) ||
+-          (pipe_id >= IA_CSS_PIPE_ID_NUM))
+-      {
++          (pipe_id >= IA_CSS_PIPE_ID_NUM)) {
+               IA_CSS_LEAVE_ERR(-EINVAL);
+               return -EINVAL;
+       }
+       ret_err = ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
+-      if (!ret_err)
+-      {
++      if (!ret_err) {
+               IA_CSS_LEAVE_ERR(-EINVAL);
+               return -EINVAL;
+       }
+       ret_err = ia_css_query_internal_queue_id(buf_type, thread_id, &queue_id);
+-      if (!ret_err)
+-      {
++      if (!ret_err) {
+               IA_CSS_LEAVE_ERR(-EINVAL);
+               return -EINVAL;
+       }
+-      if ((queue_id <= SH_CSS_INVALID_QUEUE_ID) || (queue_id >= SH_CSS_MAX_NUM_QUEUES))
+-      {
++      if ((queue_id <= SH_CSS_INVALID_QUEUE_ID) || (queue_id >= SH_CSS_MAX_NUM_QUEUES)) {
+               IA_CSS_LEAVE_ERR(-EINVAL);
+               return -EINVAL;
+       }
+-      if (!sh_css_sp_is_running())
+-      {
++      if (!sh_css_sp_is_running()) {
+               IA_CSS_LOG("SP is not running!");
+               IA_CSS_LEAVE_ERR(-EBUSY);
+               /* SP is not running. The queues are not valid */
+@@ -4100,24 +4068,21 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+       ddr_buffer.cookie_ptr = buffer->driver_cookie;
+       ddr_buffer.timing_data = buffer->timing_data;
+-      if (buf_type == IA_CSS_BUFFER_TYPE_3A_STATISTICS)
+-      {
++      if (buf_type == IA_CSS_BUFFER_TYPE_3A_STATISTICS) {
+               if (!buffer->data.stats_3a) {
+                       IA_CSS_LEAVE_ERR(-EINVAL);
+                       return -EINVAL;
+               }
+               ddr_buffer.kernel_ptr = HOST_ADDRESS(buffer->data.stats_3a);
+               ddr_buffer.payload.s3a = *buffer->data.stats_3a;
+-      } else if (buf_type == IA_CSS_BUFFER_TYPE_DIS_STATISTICS)
+-      {
++      } else if (buf_type == IA_CSS_BUFFER_TYPE_DIS_STATISTICS) {
+               if (!buffer->data.stats_dvs) {
+                       IA_CSS_LEAVE_ERR(-EINVAL);
+                       return -EINVAL;
+               }
+               ddr_buffer.kernel_ptr = HOST_ADDRESS(buffer->data.stats_dvs);
+               ddr_buffer.payload.dis = *buffer->data.stats_dvs;
+-      } else if (buf_type == IA_CSS_BUFFER_TYPE_METADATA)
+-      {
++      } else if (buf_type == IA_CSS_BUFFER_TYPE_METADATA) {
+               if (!buffer->data.metadata) {
+                       IA_CSS_LEAVE_ERR(-EINVAL);
+                       return -EINVAL;
+@@ -4128,8 +4093,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+                  || (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)
+                  || (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME)
+                  || (buf_type == IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME)
+-                 || (buf_type == IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME))
+-      {
++                 || (buf_type == IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME)) {
+               if (!buffer->data.frame) {
+                       IA_CSS_LEAVE_ERR(-EINVAL);
+                       return -EINVAL;
+@@ -4164,8 +4128,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+       assert(h_vbuf);
+       assert(h_vbuf->vptr != 0x0);
+-      if ((!h_vbuf) || (h_vbuf->vptr == 0x0))
+-      {
++      if ((!h_vbuf) || (h_vbuf->vptr == 0x0)) {
+               IA_CSS_LEAVE_ERR(-EINVAL);
+               return -EINVAL;
+       }
+@@ -4175,8 +4138,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+                  sizeof(struct sh_css_hmm_buffer));
+       if ((buf_type == IA_CSS_BUFFER_TYPE_3A_STATISTICS)
+           || (buf_type == IA_CSS_BUFFER_TYPE_DIS_STATISTICS)
+-          || (buf_type == IA_CSS_BUFFER_TYPE_LACE_STATISTICS))
+-      {
++          || (buf_type == IA_CSS_BUFFER_TYPE_LACE_STATISTICS)) {
+               if (!pipeline) {
+                       ia_css_rmgr_rel_vbuf(hmm_buffer_pool, &h_vbuf);
+                       IA_CSS_LOG("pipeline is empty!");
+@@ -4199,8 +4161,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+                  || (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME)
+                  || (buf_type == IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME)
+                  || (buf_type == IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME)
+-                 || (buf_type == IA_CSS_BUFFER_TYPE_METADATA))
+-      {
++                 || (buf_type == IA_CSS_BUFFER_TYPE_METADATA)) {
+               return_err = ia_css_bufq_enqueue_buffer(thread_id,
+                                                       queue_id,
+                                                       (uint32_t)h_vbuf->vptr);
+@@ -4214,8 +4175,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+ #endif
+       }
+-      if (!return_err)
+-      {
++      if (!return_err) {
+               if (sh_css_hmm_buffer_record_acquire(
+                       h_vbuf, buf_type,
+                       HOST_ADDRESS(ddr_buffer.kernel_ptr))) {
+@@ -4230,8 +4190,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+        * Tell the SP which queues are not empty,
+        * by sending the software event.
+        */
+-      if (!return_err)
+-      {
++      if (!return_err) {
+               if (!sh_css_sp_is_running()) {
+                       /* SP is not running. The queues are not valid */
+                       IA_CSS_LOG("SP is not running!");
+@@ -4243,8 +4202,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+                                (uint8_t)thread_id,
+                                queue_id,
+                                0);
+-      } else
+-      {
++      } else {
+               ia_css_rmgr_rel_vbuf(hmm_buffer_pool, &h_vbuf);
+               IA_CSS_ERROR("buffer not enqueued");
+       }
+@@ -4259,7 +4217,8 @@ ia_css_pipe_enqueue_buffer(struct ia_css
+        */
+ int
+ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
+-                         struct ia_css_buffer *buffer) {
++                         struct ia_css_buffer *buffer)
++{
+       int return_err;
+       enum sh_css_queue_id queue_id;
+       ia_css_ptr ddr_buffer_addr = (ia_css_ptr)0;
+@@ -4272,8 +4231,7 @@ ia_css_pipe_dequeue_buffer(struct ia_css
+       IA_CSS_ENTER("pipe=%p, buffer=%p", pipe, buffer);
+-      if ((!pipe) || (!buffer))
+-      {
++      if ((!pipe) || (!buffer)) {
+               IA_CSS_LEAVE_ERR(-EINVAL);
+               return -EINVAL;
+       }
+@@ -4287,27 +4245,23 @@ ia_css_pipe_dequeue_buffer(struct ia_css
+       ddr_buffer.kernel_ptr = 0;
+       ret_err = ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
+-      if (!ret_err)
+-      {
++      if (!ret_err) {
+               IA_CSS_LEAVE_ERR(-EINVAL);
+               return -EINVAL;
+       }
+       ret_err = ia_css_query_internal_queue_id(buf_type, thread_id, &queue_id);
+-      if (!ret_err)
+-      {
++      if (!ret_err) {
+               IA_CSS_LEAVE_ERR(-EINVAL);
+               return -EINVAL;
+       }
+-      if ((queue_id <= SH_CSS_INVALID_QUEUE_ID) || (queue_id >= SH_CSS_MAX_NUM_QUEUES))
+-      {
++      if ((queue_id <= SH_CSS_INVALID_QUEUE_ID) || (queue_id >= SH_CSS_MAX_NUM_QUEUES)) {
+               IA_CSS_LEAVE_ERR(-EINVAL);
+               return -EINVAL;
+       }
+-      if (!sh_css_sp_is_running())
+-      {
++      if (!sh_css_sp_is_running()) {
+               IA_CSS_LOG("SP is not running!");
+               IA_CSS_LEAVE_ERR(-EBUSY);
+               /* SP is not running. The queues are not valid */
+@@ -4317,8 +4271,7 @@ ia_css_pipe_dequeue_buffer(struct ia_css
+       return_err = ia_css_bufq_dequeue_buffer(queue_id,
+                                               (uint32_t *)&ddr_buffer_addr);
+-      if (!return_err)
+-      {
++      if (!return_err) {
+               struct ia_css_frame *frame;
+               struct sh_css_hmm_buffer_record *hmm_buffer_record = NULL;
+@@ -4460,8 +4413,7 @@ ia_css_pipe_dequeue_buffer(struct ia_css
+        * Tell the SP which queues are not full,
+        * by sending the software event.
+        */
+-      if (!return_err)
+-      {
++      if (!return_err) {
+               if (!sh_css_sp_is_running()) {
+                       IA_CSS_LOG("SP is not running!");
+                       IA_CSS_LEAVE_ERR(-EBUSY);
+@@ -4510,12 +4462,14 @@ static enum ia_css_event_type convert_ev
+ };
+ int
+-ia_css_dequeue_event(struct ia_css_event *event) {
++ia_css_dequeue_event(struct ia_css_event *event)
++{
+       return ia_css_dequeue_psys_event(event);
+ }
+ int
+-ia_css_dequeue_psys_event(struct ia_css_event *event) {
++ia_css_dequeue_psys_event(struct ia_css_event *event)
++{
+       enum ia_css_pipe_id pipe_id = 0;
+       u8 payload[4] = {0, 0, 0, 0};
+       int ret_err;
+@@ -4530,11 +4484,9 @@ ia_css_dequeue_psys_event(struct ia_css_
+       if (!event)
+               return -EINVAL;
++      /* SP is not running. The queues are not valid */
+       if (!sh_css_sp_is_running())
+-      {
+-              /* SP is not running. The queues are not valid */
+               return -EBUSY;
+-      }
+       /* dequeue the event (if any) from the psys event queue */
+       ret_err = ia_css_bufq_dequeue_psys_event(payload);
+@@ -4561,8 +4513,7 @@ ia_css_dequeue_psys_event(struct ia_css_
+       event->timer_code = 0;
+       event->timer_subcode = 0;
+-      if (event->type == IA_CSS_EVENT_TYPE_TIMER)
+-      {
++      if (event->type == IA_CSS_EVENT_TYPE_TIMER) {
+               /* timer event ??? get the 2nd event and decode the data into the event struct */
+               u32 tmp_data;
+               /* 1st event: LSB 16-bit timer data and code */
+@@ -4586,37 +4537,32 @@ ia_css_dequeue_psys_event(struct ia_css_
+                       tmp_data = ((payload[1] & 0xFF) | ((payload[3] & 0xFF) << 8));
+                       event->timer_data |= (tmp_data << 16);
+                       event->timer_subcode = payload[2];
+-              }
++              } else {
+               /* It's a non timer event. So clear first half of the timer event data.
+               * If the second part of the TIMER event is not received, we discard
+               * the first half of the timer data and process the non timer event without
+               * affecting the flow. So the non timer event falls through
+               * the code. */
+-              else {
+                       event->timer_data = 0;
+                       event->timer_code = 0;
+                       event->timer_subcode = 0;
+                       IA_CSS_ERROR("Missing 2nd timer event. Timer event discarded");
+               }
+       }
+-      if (event->type == IA_CSS_EVENT_TYPE_PORT_EOF)
+-      {
++      if (event->type == IA_CSS_EVENT_TYPE_PORT_EOF) {
+               event->port = (enum mipi_port_id)payload[1];
+               event->exp_id = payload[3];
+-      } else if (event->type == IA_CSS_EVENT_TYPE_FW_WARNING)
+-      {
++      } else if (event->type == IA_CSS_EVENT_TYPE_FW_WARNING) {
+               event->fw_warning = (enum ia_css_fw_warning)payload[1];
+               /* exp_id is only available in these warning types */
+               if (event->fw_warning == IA_CSS_FW_WARNING_EXP_ID_LOCKED ||
+                   event->fw_warning == IA_CSS_FW_WARNING_TAG_EXP_ID_FAILED)
+                       event->exp_id = payload[3];
+-      } else if (event->type == IA_CSS_EVENT_TYPE_FW_ASSERT)
+-      {
++      } else if (event->type == IA_CSS_EVENT_TYPE_FW_ASSERT) {
+               event->fw_assert_module_id = payload[1]; /* module */
+               event->fw_assert_line_no = (payload[2] << 8) + payload[3];
+               /* payload[2] is line_no>>8, payload[3] is line_no&0xff */
+-      } else if (event->type != IA_CSS_EVENT_TYPE_TIMER)
+-      {
++      } else if (event->type != IA_CSS_EVENT_TYPE_TIMER) {
+               /* pipe related events.
+                * payload[1] contains the pipe_num,
+                * payload[2] contains the pipe_id. These are different. */
+@@ -4666,7 +4612,8 @@ ia_css_dequeue_psys_event(struct ia_css_
+ }
+ int
+-ia_css_dequeue_isys_event(struct ia_css_event *event) {
++ia_css_dequeue_isys_event(struct ia_css_event *event)
++{
+       u8 payload[4] = {0, 0, 0, 0};
+       int err = 0;
+@@ -4676,11 +4623,9 @@ ia_css_dequeue_isys_event(struct ia_css_
+       if (!event)
+               return -EINVAL;
++      /* SP is not running. The queues are not valid */
+       if (!sh_css_sp_is_running())
+-      {
+-              /* SP is not running. The queues are not valid */
+               return -EBUSY;
+-      }
+       err = ia_css_bufq_dequeue_isys_event(payload);
+       if (err)
+@@ -4713,7 +4658,8 @@ acc_start(struct ia_css_pipe *pipe)
+ }
+ static int
+-sh_css_pipe_start(struct ia_css_stream *stream) {
++sh_css_pipe_start(struct ia_css_stream *stream)
++{
+       int err = 0;
+       struct ia_css_pipe *pipe;
+@@ -4722,22 +4668,19 @@ sh_css_pipe_start(struct ia_css_stream *
+       IA_CSS_ENTER_PRIVATE("stream = %p", stream);
+-      if (!stream)
+-      {
++      if (!stream) {
+               IA_CSS_LEAVE_ERR(-EINVAL);
+               return -EINVAL;
+       }
+       pipe = stream->last_pipe;
+-      if (!pipe)
+-      {
++      if (!pipe) {
+               IA_CSS_LEAVE_ERR(-EINVAL);
+               return -EINVAL;
+       }
+       pipe_id = pipe->mode;
+-      if (stream->started)
+-      {
++      if (stream->started) {
+               IA_CSS_WARNING("Cannot start stream that is already started");
+               IA_CSS_LEAVE_ERR(err);
+               return err;
+@@ -4745,8 +4688,7 @@ sh_css_pipe_start(struct ia_css_stream *
+       pipe->stop_requested = false;
+-      switch (pipe_id)
+-      {
++      switch (pipe_id) {
+       case IA_CSS_PIPE_ID_PREVIEW:
+               err = preview_start(pipe);
+               break;
+@@ -4766,8 +4708,7 @@ sh_css_pipe_start(struct ia_css_stream *
+               err = -EINVAL;
+       }
+       /* DH regular multi pipe - not continuous mode: start the next pipes too */
+-      if (!stream->config.continuous)
+-      {
++      if (!stream->config.continuous) {
+               int i;
+               for (i = 1; i < stream->num_pipes && 0 == err ; i++) {
+@@ -4797,8 +4738,7 @@ sh_css_pipe_start(struct ia_css_stream *
+                       }
+               }
+       }
+-      if (err)
+-      {
++      if (err) {
+               IA_CSS_LEAVE_ERR_PRIVATE(err);
+               return err;
+       }
+@@ -4808,8 +4748,7 @@ sh_css_pipe_start(struct ia_css_stream *
+        * don't use ISP parameters anyway. So this should be okay.
+        * The SP binary (jpeg) copy does not use any parameters.
+        */
+-      if (!copy_on_sp(pipe))
+-      {
++      if (!copy_on_sp(pipe)) {
+               sh_css_invalidate_params(stream);
+               err = sh_css_param_update_isp_params(pipe,
+                                                    stream->isp_params_configs, true, NULL);
+@@ -4823,8 +4762,7 @@ sh_css_pipe_start(struct ia_css_stream *
+       ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
+-      if (!sh_css_sp_is_running())
+-      {
++      if (!sh_css_sp_is_running()) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-EBUSY);
+               /* SP is not running. The queues are not valid */
+               return -EBUSY;
+@@ -4833,8 +4771,7 @@ sh_css_pipe_start(struct ia_css_stream *
+                                      (uint8_t)thread_id, 0, 0);
+       /* DH regular multi pipe - not continuous mode: enqueue event to the next pipes too */
+-      if (!stream->config.continuous)
+-      {
++      if (!stream->config.continuous) {
+               int i;
+               for (i = 1; i < stream->num_pipes; i++) {
+@@ -4848,8 +4785,7 @@ sh_css_pipe_start(struct ia_css_stream *
+       }
+       /* in case of continuous capture mode, we also start capture thread and copy thread*/
+-      if (pipe->stream->config.continuous)
+-      {
++      if (pipe->stream->config.continuous) {
+               struct ia_css_pipe *copy_pipe = NULL;
+               if (pipe_id == IA_CSS_PIPE_ID_PREVIEW)
+@@ -4868,8 +4804,7 @@ sh_css_pipe_start(struct ia_css_stream *
+                   IA_CSS_PSYS_SW_EVENT_START_STREAM,
+                   (uint8_t)thread_id, 0,  0);
+       }
+-      if (pipe->stream->cont_capt)
+-      {
++      if (pipe->stream->cont_capt) {
+               struct ia_css_pipe *capture_pipe = NULL;
+               if (pipe_id == IA_CSS_PIPE_ID_PREVIEW)
+@@ -4890,8 +4825,7 @@ sh_css_pipe_start(struct ia_css_stream *
+       }
+       /* in case of PREVIEW mode, check whether QOS acc_pipe is available, then start the qos pipe */
+-      if (pipe_id == IA_CSS_PIPE_ID_PREVIEW)
+-      {
++      if (pipe_id == IA_CSS_PIPE_ID_PREVIEW) {
+               struct ia_css_pipe *acc_pipe = NULL;
+               acc_pipe = pipe->pipe_settings.preview.acc_pipe;
+@@ -4942,7 +4876,8 @@ sh_css_continuous_is_enabled(uint8_t pip
+ /* ISP2400 */
+ int
+ ia_css_stream_get_max_buffer_depth(struct ia_css_stream *stream,
+-                                 int *buffer_depth) {
++                                 int *buffer_depth)
++{
+       if (!buffer_depth)
+               return -EINVAL;
+       ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_get_max_buffer_depth() enter: void\n");
+@@ -4952,7 +4887,8 @@ ia_css_stream_get_max_buffer_depth(struc
+ }
+ int
+-ia_css_stream_set_buffer_depth(struct ia_css_stream *stream, int buffer_depth) {
++ia_css_stream_set_buffer_depth(struct ia_css_stream *stream, int buffer_depth)
++{
+       ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_set_buffer_depth() enter: num_frames=%d\n", buffer_depth);
+       (void)stream;
+       if (buffer_depth > NUM_CONTINUOUS_FRAMES || buffer_depth < 1)
+@@ -4966,7 +4902,8 @@ ia_css_stream_set_buffer_depth(struct ia
+ /* ISP2401 */
+ int
+ ia_css_stream_get_buffer_depth(struct ia_css_stream *stream,
+-                             int *buffer_depth) {
++                             int *buffer_depth)
++{
+       if (!buffer_depth)
+               return -EINVAL;
+       ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_get_buffer_depth() enter: void\n");
+@@ -4991,8 +4928,7 @@ sh_css_pipes_stop(struct ia_css_stream *
+       int i;
+       assert(stream);
+-      if (!stream)
+-      {
++      if (!stream) {
+               IA_CSS_LOG("stream does NOT exist!");
+               err = -EINVAL;
+               goto ERR;
+@@ -5000,8 +4936,7 @@ sh_css_pipes_stop(struct ia_css_stream *
+       main_pipe = stream->last_pipe;
+       assert(main_pipe);
+-      if (!main_pipe)
+-      {
++      if (!main_pipe) {
+               IA_CSS_LOG("main_pipe does NOT exist!");
+               err = -EINVAL;
+               goto ERR;
+@@ -5014,8 +4949,7 @@ sh_css_pipes_stop(struct ia_css_stream *
+        * Stop all "ia_css_pipe" instances in this target
+        * "ia_css_stream" instance.
+        */
+-      for (i = 0; i < stream->num_pipes; i++)
+-      {
++      for (i = 0; i < stream->num_pipes; i++) {
+               /* send the "stop" request to the "ia_css_pipe" instance */
+               IA_CSS_LOG("Send the stop-request to the pipe: pipe_id=%d",
+                       stream->pipes[i]->pipeline.pipe_id);
+@@ -5049,8 +4983,7 @@ sh_css_pipes_stop(struct ia_css_stream *
+        *
+        * We need to stop this "Copy Pipe", as well.
+        */
+-      if (main_pipe->stream->config.continuous)
+-      {
++      if (main_pipe->stream->config.continuous) {
+               struct ia_css_pipe *copy_pipe = NULL;
+               /* get the reference to "Copy Pipe" */
+@@ -5226,8 +5159,7 @@ sh_css_pipe_get_shading_info(struct ia_c
+       binary = ia_css_pipe_get_shading_correction_binary(pipe);
+-      if (binary)
+-      {
++      if (binary) {
+               err = ia_css_binary_get_shading_info(binary,
+                                                    IA_CSS_SHADING_CORRECTION_TYPE_1,
+                                                    pipe->required_bds_factor,
+@@ -5237,8 +5169,7 @@ sh_css_pipe_get_shading_info(struct ia_c
+               /* Other function calls can be added here when other shading correction types will be added
+                * in the future.
+                */
+-      } else
+-      {
++      } else {
+               /* When the pipe does not have a binary which has the shading
+                * correction, this function does not need to fill the shading
+                * information. It is not a error case, and then
+@@ -5251,7 +5182,8 @@ sh_css_pipe_get_shading_info(struct ia_c
+ static int
+ sh_css_pipe_get_grid_info(struct ia_css_pipe *pipe,
+-                        struct ia_css_grid_info *info) {
++                        struct ia_css_grid_info *info)
++{
+       int err = 0;
+       struct ia_css_binary *binary = NULL;
+@@ -5262,30 +5194,27 @@ sh_css_pipe_get_grid_info(struct ia_css_
+       binary = ia_css_pipe_get_s3a_binary(pipe);
+-      if (binary)
+-      {
++      if (binary) {
+               err = ia_css_binary_3a_grid_info(binary, info, pipe);
+               if (err)
+                       goto ERR;
+-      } else
++      } else {
+               memset(&info->s3a_grid, 0, sizeof(info->s3a_grid));
++      }
+       binary = ia_css_pipe_get_sdis_binary(pipe);
+-      if (binary)
+-      {
++      if (binary) {
+               ia_css_binary_dvs_grid_info(binary, info, pipe);
+               ia_css_binary_dvs_stat_grid_info(binary, info, pipe);
+-      } else
+-      {
++      } else {
+               memset(&info->dvs_grid.dvs_grid_info, 0,
+                      sizeof(info->dvs_grid.dvs_grid_info));
+               memset(&info->dvs_grid.dvs_stat_grid_info, 0,
+                      sizeof(info->dvs_grid.dvs_stat_grid_info));
+       }
+-      if (binary)
+-      {
++      if (binary) {
+               /* copy pipe does not have ISP binary*/
+               info->isp_in_width = binary->internal_frame_info.res.width;
+               info->isp_in_height = binary->internal_frame_info.res.height;
+@@ -5305,7 +5234,8 @@ ERR :
+  */
+ static int
+ ia_css_pipe_check_format(struct ia_css_pipe *pipe,
+-                       enum ia_css_frame_format format) {
++                       enum ia_css_frame_format format)
++{
+       const enum ia_css_frame_format *supported_formats;
+       int number_of_formats;
+       int found = 0;
+@@ -5313,8 +5243,7 @@ ia_css_pipe_check_format(struct ia_css_p
+       IA_CSS_ENTER_PRIVATE("");
+-      if (NULL == pipe || NULL == pipe->pipe_settings.video.video_binary.info)
+-      {
++      if (NULL == pipe || NULL == pipe->pipe_settings.video.video_binary.info) {
+               IA_CSS_ERROR("Pipe or binary info is not set");
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+@@ -5323,15 +5252,13 @@ ia_css_pipe_check_format(struct ia_css_p
+       supported_formats = pipe->pipe_settings.video.video_binary.info->output_formats;
+       number_of_formats = sizeof(pipe->pipe_settings.video.video_binary.info->output_formats) / sizeof(enum ia_css_frame_format);
+-      for (i = 0; i < number_of_formats && !found; i++)
+-      {
++      for (i = 0; i < number_of_formats && !found; i++) {
+               if (supported_formats[i] == format) {
+                       found = 1;
+                       break;
+               }
+       }
+-      if (!found)
+-      {
++      if (!found) {
+               IA_CSS_ERROR("Requested format is not supported by binary");
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+@@ -5483,10 +5410,10 @@ static int load_video_binaries(struct ia
+                                        &mycs->video_binary);
+               if (err) {
+-                      if (video_vf_info) {
+-                              /* This will do another video binary lookup later for YUV_LINE format*/
++                      /* This will do another video binary lookup later for YUV_LINE format*/
++                      if (video_vf_info)
+                               need_vf_pp = true;
+-                      } else
++                      else
+                               return err;
+               } else if (video_vf_info) {
+                       /* The first video binary lookup is successful, but we may
+@@ -5649,13 +5576,13 @@ static int load_video_binaries(struct ia
+ }
+ static int
+-unload_video_binaries(struct ia_css_pipe *pipe) {
++unload_video_binaries(struct ia_css_pipe *pipe)
++{
+       unsigned int i;
+       IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
+-      if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_VIDEO))
+-      {
++      if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_VIDEO)) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+       }
+@@ -5805,31 +5732,29 @@ static int
+ sh_css_pipe_configure_viewfinder(struct ia_css_pipe *pipe, unsigned int width,
+                                unsigned int height, unsigned int min_width,
+                                enum ia_css_frame_format format,
+-                               unsigned int idx) {
++                               unsigned int idx)
++{
+       int err = 0;
+       IA_CSS_ENTER_PRIVATE("pipe = %p, width = %d, height = %d, min_width = %d, format = %d, idx = %d\n",
+                            pipe, width, height, min_width, format, idx);
+-      if (!pipe)
+-      {
++      if (!pipe) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+       }
+       err = ia_css_util_check_res(width, height);
+-      if (err)
+-      {
++      if (err) {
+               IA_CSS_LEAVE_ERR_PRIVATE(err);
+               return err;
+       }
+       if (pipe->vf_output_info[idx].res.width != width ||
+           pipe->vf_output_info[idx].res.height != height ||
+           pipe->vf_output_info[idx].format != format)
+-      {
+               ia_css_frame_info_init(&pipe->vf_output_info[idx], width, height,
+                                      format, min_width);
+-      }
++
+       IA_CSS_LEAVE_ERR_PRIVATE(0);
+       return 0;
+ }
+@@ -6209,7 +6134,8 @@ static int load_primary_binaries(
+ }
+ static int
+-allocate_delay_frames(struct ia_css_pipe *pipe) {
++allocate_delay_frames(struct ia_css_pipe *pipe)
++{
+       unsigned int num_delay_frames = 0, i = 0;
+       unsigned int dvs_frame_delay = 0;
+       struct ia_css_frame_info ref_info;
+@@ -6219,8 +6145,7 @@ allocate_delay_frames(struct ia_css_pipe
+       IA_CSS_ENTER_PRIVATE("");
+-      if (!pipe)
+-      {
++      if (!pipe) {
+               IA_CSS_ERROR("Invalid args - pipe %p", pipe);
+               return -EINVAL;
+       }
+@@ -6231,8 +6156,7 @@ allocate_delay_frames(struct ia_css_pipe
+       if (dvs_frame_delay > 0)
+               num_delay_frames = dvs_frame_delay + 1;
+-      switch (mode)
+-      {
++      switch (mode) {
+       case IA_CSS_PIPE_ID_CAPTURE: {
+               struct ia_css_capture_settings *mycs_capture = &pipe->pipe_settings.capture;
+               (void)mycs_capture;
+@@ -6284,8 +6208,7 @@ allocate_delay_frames(struct ia_css_pipe
+       ref_info.raw_bit_depth = SH_CSS_REF_BIT_DEPTH;
+       assert(num_delay_frames <= MAX_NUM_VIDEO_DELAY_FRAMES);
+-      for (i = 0; i < num_delay_frames; i++)
+-      {
++      for (i = 0; i < num_delay_frames; i++) {
+               err = ia_css_frame_allocate_from_info(&delay_frames[i], &ref_info);
+               if (err)
+                       return err;
+@@ -6295,7 +6218,8 @@ allocate_delay_frames(struct ia_css_pipe
+ }
+ static int load_advanced_binaries(
+-    struct ia_css_pipe *pipe) {
++    struct ia_css_pipe *pipe)
++{
+       struct ia_css_frame_info pre_in_info, gdc_in_info,
+                       post_in_info, post_out_info,
+                       vf_info, *vf_pp_in_info, *pipe_out_info,
+@@ -6412,7 +6336,8 @@ static int load_advanced_binaries(
+ }
+ static int load_bayer_isp_binaries(
+-    struct ia_css_pipe *pipe) {
++    struct ia_css_pipe *pipe)
++{
+       struct ia_css_frame_info pre_isp_in_info, *pipe_out_info;
+       int err = 0;
+       struct ia_css_binary_descr pre_de_descr;
+@@ -6441,7 +6366,8 @@ static int load_bayer_isp_binaries(
+ }
+ static int load_low_light_binaries(
+-    struct ia_css_pipe *pipe) {
++    struct ia_css_pipe *pipe)
++{
+       struct ia_css_frame_info pre_in_info, anr_in_info,
+                       post_in_info, post_out_info,
+                       vf_info, *pipe_vf_out_info, *pipe_out_info,
+@@ -6579,7 +6505,8 @@ static bool copy_on_sp(struct ia_css_pip
+ }
+ static int load_capture_binaries(
+-    struct ia_css_pipe *pipe) {
++    struct ia_css_pipe *pipe)
++{
+       int err = 0;
+       bool must_be_raw;
+@@ -6647,13 +6574,13 @@ static int load_capture_binaries(
+ }
+ static int
+-unload_capture_binaries(struct ia_css_pipe *pipe) {
++unload_capture_binaries(struct ia_css_pipe *pipe)
++{
+       unsigned int i;
+       IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
+-      if ((!pipe) || ((pipe->mode != IA_CSS_PIPE_ID_CAPTURE) && (pipe->mode != IA_CSS_PIPE_ID_COPY)))
+-      {
++      if ((!pipe) || ((pipe->mode != IA_CSS_PIPE_ID_CAPTURE) && (pipe->mode != IA_CSS_PIPE_ID_COPY))) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+       }
+@@ -6681,7 +6608,8 @@ unload_capture_binaries(struct ia_css_pi
+ static bool
+ need_downscaling(const struct ia_css_resolution in_res,
+-                  const struct ia_css_resolution out_res) {
++                  const struct ia_css_resolution out_res)
++{
+       if (in_res.width > out_res.width || in_res.height > out_res.height)
+               return true;
+@@ -6689,7 +6617,8 @@ need_downscaling(const struct ia_css_res
+ }
+ static bool
+-need_yuv_scaler_stage(const struct ia_css_pipe *pipe) {
++need_yuv_scaler_stage(const struct ia_css_pipe *pipe)
++{
+       unsigned int i;
+       struct ia_css_resolution in_res, out_res;
+@@ -6731,7 +6660,8 @@ static int ia_css_pipe_create_cas_scaler
+     struct ia_css_frame_info *cas_scaler_in_info,
+     struct ia_css_frame_info *cas_scaler_out_info,
+     struct ia_css_frame_info *cas_scaler_vf_info,
+-    struct ia_css_cas_binary_descr *descr) {
++    struct ia_css_cas_binary_descr *descr)
++{
+       unsigned int i;
+       unsigned int hor_ds_factor = 0, ver_ds_factor = 0;
+       int err = 0;
+@@ -6849,7 +6779,8 @@ ERR:
+ /* FIXME: merge most of this and single output version */
+ static int ia_css_pipe_create_cas_scaler_desc(
+     struct ia_css_pipe *pipe,
+-    struct ia_css_cas_binary_descr *descr) {
++    struct ia_css_cas_binary_descr *descr)
++{
+       struct ia_css_frame_info in_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO;
+       struct ia_css_frame_info *out_info[IA_CSS_PIPE_MAX_OUTPUT_STAGE];
+       struct ia_css_frame_info *vf_out_info[IA_CSS_PIPE_MAX_OUTPUT_STAGE];
+@@ -7005,7 +6936,8 @@ ERR:
+ }
+ static void ia_css_pipe_destroy_cas_scaler_desc(struct ia_css_cas_binary_descr
+-      *descr) {
++      *descr)
++{
+       ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
+                           "ia_css_pipe_destroy_cas_scaler_desc() enter:\n");
+       kfree(descr->in_info);
+@@ -7023,7 +6955,8 @@ static void ia_css_pipe_destroy_cas_scal
+ }
+ static int
+-load_yuvpp_binaries(struct ia_css_pipe *pipe) {
++load_yuvpp_binaries(struct ia_css_pipe *pipe)
++{
+       int err = 0;
+       bool need_scaler = false;
+       struct ia_css_frame_info *vf_pp_in_info[IA_CSS_PIPE_MAX_OUTPUT_STAGE];
+@@ -7048,8 +6981,7 @@ load_yuvpp_binaries(struct ia_css_pipe *
+       mycs = &pipe->pipe_settings.yuvpp;
+-      for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++)
+-      {
++      for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
+               if (pipe->vf_output_info[i].res.width != 0) {
+                       err = ia_css_util_check_vf_out_info(&pipe->output_info[i],
+                                                           &pipe->vf_output_info[i]);
+@@ -7063,8 +6995,7 @@ load_yuvpp_binaries(struct ia_css_pipe *
+       /* we build up the pipeline starting at the end */
+       /* Capture post-processing */
+-      if (need_scaler)
+-      {
++      if (need_scaler) {
+               struct ia_css_binary_descr yuv_scaler_descr;
+               err = ia_css_pipe_create_cas_scaler_desc(pipe,
+@@ -7098,18 +7029,14 @@ load_yuvpp_binaries(struct ia_css_pipe *
+                               goto ERR;
+               }
+               ia_css_pipe_destroy_cas_scaler_desc(&cas_scaler_descr);
+-      } else
+-      {
++      } else {
+               mycs->num_output = 1;
+       }
+       if (need_scaler)
+-      {
+               next_binary = &mycs->yuv_scaler_binary[0];
+-      } else
+-      {
++      else
+               next_binary = NULL;
+-      }
+ #if defined(ISP2401)
+       /*
+@@ -7135,8 +7062,7 @@ load_yuvpp_binaries(struct ia_css_pipe *
+       need_isp_copy_binary = true;
+ #endif /*  ISP2401 */
+-      if (need_isp_copy_binary)
+-      {
++      if (need_isp_copy_binary) {
+               err = load_copy_binary(pipe,
+                                       &mycs->copy_binary,
+                                       next_binary);
+@@ -7166,8 +7092,7 @@ load_yuvpp_binaries(struct ia_css_pipe *
+       }
+       /* Viewfinder post-processing */
+-      if (need_scaler)
+-      {
++      if (need_scaler) {
+               for (i = 0, j = 0; i < mycs->num_yuv_scaler; i++) {
+                       if (mycs->is_output_stage[i]) {
+                               assert(j < 2);
+@@ -7177,19 +7102,17 @@ load_yuvpp_binaries(struct ia_css_pipe *
+                       }
+               }
+               mycs->num_vf_pp = j;
+-      } else
+-      {
++      } else {
+               vf_pp_in_info[0] =
+                   &mycs->copy_binary.vf_frame_info;
+-              for (i = 1; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
++              for (i = 1; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++)
+                       vf_pp_in_info[i] = NULL;
+-              }
++
+               mycs->num_vf_pp = 1;
+       }
+       mycs->vf_pp_binary = kzalloc(mycs->num_vf_pp * sizeof(struct ia_css_binary),
+                                       GFP_KERNEL);
+-      if (!mycs->vf_pp_binary)
+-      {
++      if (!mycs->vf_pp_binary) {
+               err = -ENOMEM;
+               goto ERR;
+       }
+@@ -7197,8 +7120,7 @@ load_yuvpp_binaries(struct ia_css_pipe *
+       {
+               struct ia_css_binary_descr vf_pp_descr;
+-              for (i = 0; i < mycs->num_vf_pp; i++)
+-              {
++              for (i = 0; i < mycs->num_vf_pp; i++) {
+                       if (pipe->vf_output_info[i].res.width != 0) {
+                               ia_css_pipe_get_vfpp_binarydesc(pipe,
+                                                               &vf_pp_descr, vf_pp_in_info[i], &pipe->vf_output_info[i]);
+@@ -7214,34 +7136,31 @@ load_yuvpp_binaries(struct ia_css_pipe *
+ ERR:
+       if (need_scaler)
+-      {
+               ia_css_pipe_destroy_cas_scaler_desc(&cas_scaler_descr);
+-      }
++
+       ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "load_yuvpp_binaries() leave, err=%d\n",
+                           err);
+       return err;
+ }
+ static int
+-unload_yuvpp_binaries(struct ia_css_pipe *pipe) {
++unload_yuvpp_binaries(struct ia_css_pipe *pipe)
++{
+       unsigned int i;
+       IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
+-      if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_YUVPP))
+-      {
++      if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_YUVPP)) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+       }
+       ia_css_binary_unload(&pipe->pipe_settings.yuvpp.copy_binary);
+       for (i = 0; i < pipe->pipe_settings.yuvpp.num_yuv_scaler; i++)
+-      {
+               ia_css_binary_unload(&pipe->pipe_settings.yuvpp.yuv_scaler_binary[i]);
+-      }
++
+       for (i = 0; i < pipe->pipe_settings.yuvpp.num_vf_pp; i++)
+-      {
+               ia_css_binary_unload(&pipe->pipe_settings.yuvpp.vf_pp_binary[i]);
+-      }
++
+       kfree(pipe->pipe_settings.yuvpp.is_output_stage);
+       pipe->pipe_settings.yuvpp.is_output_stage = NULL;
+       kfree(pipe->pipe_settings.yuvpp.yuv_scaler_binary);
+@@ -7291,25 +7210,23 @@ static int yuvpp_start(struct ia_css_pip
+ }
+ static int
+-sh_css_pipe_unload_binaries(struct ia_css_pipe *pipe) {
++sh_css_pipe_unload_binaries(struct ia_css_pipe *pipe)
++{
+       int err = 0;
+       IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
+-      if (!pipe)
+-      {
++      if (!pipe) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+       }
+       /* PIPE_MODE_COPY has no binaries, but has output frames to outside*/
+-      if (pipe->config.mode == IA_CSS_PIPE_MODE_COPY)
+-      {
++      if (pipe->config.mode == IA_CSS_PIPE_MODE_COPY) {
+               IA_CSS_LEAVE_ERR_PRIVATE(0);
+               return 0;
+       }
+-      switch (pipe->mode)
+-      {
++      switch (pipe->mode) {
+       case IA_CSS_PIPE_ID_PREVIEW:
+               err = unload_preview_binaries(pipe);
+               break;
+@@ -7330,7 +7247,8 @@ sh_css_pipe_unload_binaries(struct ia_cs
+ }
+ static int
+-sh_css_pipe_load_binaries(struct ia_css_pipe *pipe) {
++sh_css_pipe_load_binaries(struct ia_css_pipe *pipe)
++{
+       int err = 0;
+       assert(pipe);
+@@ -7340,8 +7258,7 @@ sh_css_pipe_load_binaries(struct ia_css_
+       if (pipe->config.mode == IA_CSS_PIPE_MODE_COPY)
+               return err;
+-      switch (pipe->mode)
+-      {
++      switch (pipe->mode) {
+       case IA_CSS_PIPE_ID_PREVIEW:
+               err = load_preview_binaries(pipe);
+               break;
+@@ -7360,8 +7277,7 @@ sh_css_pipe_load_binaries(struct ia_css_
+               err = -EINVAL;
+               break;
+       }
+-      if (err)
+-      {
++      if (err) {
+               if (sh_css_pipe_unload_binaries(pipe)) {
+                       /* currently css does not support multiple error returns in a single function,
+                           * using -EINVAL in this case */
+@@ -7372,7 +7288,8 @@ sh_css_pipe_load_binaries(struct ia_css_
+ }
+ static int
+-create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) {
++create_host_yuvpp_pipeline(struct ia_css_pipe *pipe)
++{
+       struct ia_css_pipeline *me;
+       int err = 0;
+       struct ia_css_pipeline_stage *vf_pp_stage = NULL,
+@@ -7399,15 +7316,13 @@ create_host_yuvpp_pipeline(struct ia_css
+ #endif
+       IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
+-      if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_YUVPP))
+-      {
++      if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_YUVPP)) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+       }
+       me = &pipe->pipeline;
+       ia_css_pipeline_clean(me);
+-      for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++)
+-      {
++      for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
+               out_frame[i] = NULL;
+               vf_frame[i] = NULL;
+       }
+@@ -7435,8 +7350,7 @@ create_host_yuvpp_pipeline(struct ia_css
+       /* the input frame can come from:
+           *  a) memory: connect yuvscaler to me->in_frame
+           *  b) sensor, via copy binary: connect yuvscaler to copy binary later on */
+-      if (need_in_frameinfo_memory)
+-      {
++      if (need_in_frameinfo_memory) {
+               /* TODO: improve for different input formats. */
+               /*
+@@ -7485,13 +7399,11 @@ create_host_yuvpp_pipeline(struct ia_css
+               }
+               in_frame = &me->in_frame;
+-      } else
+-      {
++      } else {
+               in_frame = NULL;
+       }
+-      for (i = 0; i < num_output_stage; i++)
+-      {
++      for (i = 0; i < num_output_stage; i++) {
+               assert(i < IA_CSS_PIPE_MAX_OUTPUT_STAGE);
+               if (pipe->output_info[i].res.width != 0) {
+                       err = init_out_frameinfo_defaults(pipe, &me->out_frame[i], i);
+@@ -7518,8 +7430,7 @@ create_host_yuvpp_pipeline(struct ia_css
+       yuv_scaler_binary = pipe->pipe_settings.yuvpp.yuv_scaler_binary;
+       need_scaler = need_yuv_scaler_stage(pipe);
+-      if (pipe->pipe_settings.yuvpp.copy_binary.info)
+-      {
++      if (pipe->pipe_settings.yuvpp.copy_binary.info) {
+               struct ia_css_frame *in_frame_local = NULL;
+ #ifdef ISP2401
+@@ -7557,8 +7468,7 @@ create_host_yuvpp_pipeline(struct ia_css
+               }
+       }
+-      if (need_scaler)
+-      {
++      if (need_scaler) {
+               struct ia_css_frame *tmp_out_frame = NULL;
+               struct ia_css_frame *tmp_vf_frame = NULL;
+               struct ia_css_frame *tmp_in_frame = in_frame;
+@@ -7598,8 +7508,7 @@ create_host_yuvpp_pipeline(struct ia_css
+                               j++;
+                       }
+               }
+-      } else if (copy_stage)
+-      {
++      } else if (copy_stage) {
+               if (vf_frame[0] && vf_frame[0]->info.res.width != 0) {
+                       in_frame = copy_stage->args.out_vf_frame;
+                       err = add_vf_pp_stage(pipe, in_frame, vf_frame[0], &vf_pp_binary[0],
+@@ -7621,7 +7530,8 @@ create_host_yuvpp_pipeline(struct ia_css
+ static int
+ create_host_copy_pipeline(struct ia_css_pipe *pipe,
+                           unsigned int max_input_width,
+-                          struct ia_css_frame *out_frame) {
++                          struct ia_css_frame *out_frame)
++{
+       struct ia_css_pipeline *me;
+       int err = 0;
+       struct ia_css_pipeline_stage_desc stage_desc;
+@@ -7638,16 +7548,14 @@ create_host_copy_pipeline(struct ia_css_
+       out_frame->flash_state = IA_CSS_FRAME_FLASH_STATE_NONE;
+       if (copy_on_sp(pipe) &&
+-          pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8)
+-      {
++          pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8) {
+               ia_css_frame_info_init(
+                   &out_frame->info,
+                   JPEG_BYTES,
+                   1,
+                   IA_CSS_FRAME_FORMAT_BINARY_8,
+                   0);
+-      } else if (out_frame->info.format == IA_CSS_FRAME_FORMAT_RAW)
+-      {
++      } else if (out_frame->info.format == IA_CSS_FRAME_FORMAT_RAW) {
+               out_frame->info.raw_bit_depth =
+               ia_css_pipe_util_pipe_input_format_bpp(pipe);
+       }
+@@ -7671,7 +7579,8 @@ create_host_copy_pipeline(struct ia_css_
+ }
+ static int
+-create_host_isyscopy_capture_pipeline(struct ia_css_pipe *pipe) {
++create_host_isyscopy_capture_pipeline(struct ia_css_pipe *pipe)
++{
+       struct ia_css_pipeline *me = &pipe->pipeline;
+       int err = 0;
+       struct ia_css_pipeline_stage_desc stage_desc;
+@@ -7715,7 +7624,8 @@ create_host_isyscopy_capture_pipeline(st
+ }
+ static int
+-create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) {
++create_host_regular_capture_pipeline(struct ia_css_pipe *pipe)
++{
+       struct ia_css_pipeline *me;
+       int err = 0;
+       enum ia_css_capture_mode mode;
+@@ -7779,8 +7689,7 @@ create_host_regular_capture_pipeline(str
+       /* Construct in_frame info (only in case we have dynamic input */
+       need_in_frameinfo_memory = pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY;
+ #endif
+-      if (need_in_frameinfo_memory)
+-      {
++      if (need_in_frameinfo_memory) {
+               err = init_in_frameinfo_memory_defaults(pipe, &me->in_frame,
+                                                       IA_CSS_FRAME_FORMAT_RAW);
+               if (err) {
+@@ -7789,22 +7698,19 @@ create_host_regular_capture_pipeline(str
+               }
+               in_frame = &me->in_frame;
+-      } else
+-      {
++      } else {
+               in_frame = NULL;
+       }
+       err = init_out_frameinfo_defaults(pipe, &me->out_frame[0], 0);
+-      if (err)
+-      {
++      if (err) {
+               IA_CSS_LEAVE_ERR_PRIVATE(err);
+               return err;
+       }
+       out_frame = &me->out_frame[0];
+       /* Construct vf_frame info (only in case we have VF) */
+-      if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0])
+-      {
++      if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0]) {
+               if (mode == IA_CSS_CAPTURE_MODE_RAW || mode == IA_CSS_CAPTURE_MODE_BAYER) {
+                       /* These modes don't support viewfinder output */
+                       vf_frame = NULL;
+@@ -7812,22 +7718,20 @@ create_host_regular_capture_pipeline(str
+                       init_vf_frameinfo_defaults(pipe, &me->vf_frame[0], 0);
+                       vf_frame = &me->vf_frame[0];
+               }
+-      } else
+-      {
++      } else {
+               vf_frame = NULL;
+       }
+       copy_binary       = &pipe->pipe_settings.capture.copy_binary;
+       num_primary_stage = pipe->pipe_settings.capture.num_primary_stage;
+-      if ((num_primary_stage == 0) && (mode == IA_CSS_CAPTURE_MODE_PRIMARY))
+-      {
++      if ((num_primary_stage == 0) && (mode == IA_CSS_CAPTURE_MODE_PRIMARY)) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+       }
++
+       for (i = 0; i < num_primary_stage; i++)
+-      {
+               primary_binary[i] = &pipe->pipe_settings.capture.primary_binary[i];
+-      }
++
+       vf_pp_binary      = &pipe->pipe_settings.capture.vf_pp_binary;
+       pre_isp_binary    = &pipe->pipe_settings.capture.pre_isp_binary;
+       anr_gdc_binary    = &pipe->pipe_settings.capture.anr_gdc_binary;
+@@ -7844,8 +7748,7 @@ create_host_regular_capture_pipeline(str
+       need_yuv_pp = (yuv_scaler_binary && yuv_scaler_binary->info);
+       need_ldc = (capture_ldc_binary && capture_ldc_binary->info);
+-      if (pipe->pipe_settings.capture.copy_binary.info)
+-      {
++      if (pipe->pipe_settings.capture.copy_binary.info) {
+               if (raw) {
+                       ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
+ #if defined(ISP2401)
+@@ -7874,13 +7777,11 @@ create_host_regular_capture_pipeline(str
+                       IA_CSS_LEAVE_ERR_PRIVATE(err);
+                       return err;
+               }
+-      } else if (pipe->stream->config.continuous)
+-      {
++      } else if (pipe->stream->config.continuous) {
+               in_frame = pipe->stream->last_pipe->continuous_frames[0];
+       }
+-      if (mode == IA_CSS_CAPTURE_MODE_PRIMARY)
+-      {
++      if (mode == IA_CSS_CAPTURE_MODE_PRIMARY) {
+               struct ia_css_frame *local_in_frame = NULL;
+               struct ia_css_frame *local_out_frame = NULL;
+@@ -7925,8 +7826,7 @@ create_host_regular_capture_pipeline(str
+                   IA_CSS_BINARY_MODE_COPY;
+               current_stage->args.copy_output = current_stage->args.copy_vf;
+       } else if (mode == IA_CSS_CAPTURE_MODE_ADVANCED ||
+-                  mode == IA_CSS_CAPTURE_MODE_LOW_LIGHT)
+-      {
++                  mode == IA_CSS_CAPTURE_MODE_LOW_LIGHT) {
+               ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
+               ia_css_pipe_get_generic_stage_desc(&stage_desc, pre_isp_binary,
+                                                   out_frames, in_frame, NULL);
+@@ -7962,8 +7862,7 @@ create_host_regular_capture_pipeline(str
+                       IA_CSS_LEAVE_ERR_PRIVATE(err);
+                       return err;
+               }
+-      } else if (mode == IA_CSS_CAPTURE_MODE_BAYER)
+-      {
++      } else if (mode == IA_CSS_CAPTURE_MODE_BAYER) {
+               ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
+               ia_css_pipe_get_generic_stage_desc(&stage_desc, pre_isp_binary,
+                                                   out_frames, in_frame, NULL);
+@@ -7977,8 +7876,7 @@ create_host_regular_capture_pipeline(str
+       }
+ #ifndef ISP2401
+-      if (need_pp && current_stage)
+-      {
++      if (need_pp && current_stage) {
+               struct ia_css_frame *local_in_frame = NULL;
+               local_in_frame = current_stage->args.out_frame[0];
+@@ -7996,8 +7894,7 @@ create_host_regular_capture_pipeline(str
+                                           need_yuv_pp ? NULL : out_frame,
+ #else
+       /* ldc and capture_pp not supported in same pipeline */
+-      if (need_ldc && current_stage)
+-      {
++      if (need_ldc && current_stage) {
+               in_frame = current_stage->args.out_frame[0];
+               ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
+               ia_css_pipe_get_generic_stage_desc(&stage_desc, capture_ldc_binary,
+@@ -8005,8 +7902,7 @@ create_host_regular_capture_pipeline(str
+               err = ia_css_pipeline_create_and_add_stage(me,
+                       &stage_desc,
+                       NULL);
+-      } else if (need_pp && current_stage)
+-      {
++      } else if (need_pp && current_stage) {
+               in_frame = current_stage->args.out_frame[0];
+               err = add_capture_pp_stage(pipe, me, in_frame, need_yuv_pp ? NULL : out_frame,
+ #endif
+@@ -8018,8 +7914,7 @@ create_host_regular_capture_pipeline(str
+               }
+       }
+-      if (need_yuv_pp && current_stage)
+-      {
++      if (need_yuv_pp && current_stage) {
+               struct ia_css_frame *tmp_in_frame = current_stage->args.out_frame[0];
+               struct ia_css_frame *tmp_out_frame = NULL;
+@@ -8051,8 +7946,7 @@ create_host_regular_capture_pipeline(str
+           * should not be considered as a clean solution. Proper
+           * investigation should be done to come up with the clean solution.
+           * */
+-      if (mode != IA_CSS_CAPTURE_MODE_RAW && mode != IA_CSS_CAPTURE_MODE_BAYER && current_stage && vf_frame)
+-      {
++      if (mode != IA_CSS_CAPTURE_MODE_RAW && mode != IA_CSS_CAPTURE_MODE_BAYER && current_stage && vf_frame) {
+               in_frame = current_stage->args.out_vf_frame;
+               err = add_vf_pp_stage(pipe, in_frame, vf_frame, vf_pp_binary,
+                                       &current_stage);
+@@ -8070,7 +7964,8 @@ create_host_regular_capture_pipeline(str
+ }
+ static int
+-create_host_capture_pipeline(struct ia_css_pipe *pipe) {
++create_host_capture_pipeline(struct ia_css_pipe *pipe)
++{
+       int err = 0;
+       IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
+@@ -8079,8 +7974,7 @@ create_host_capture_pipeline(struct ia_c
+               err = create_host_isyscopy_capture_pipeline(pipe);
+       else
+               err = create_host_regular_capture_pipeline(pipe);
+-      if (err)
+-      {
++      if (err) {
+               IA_CSS_LEAVE_ERR_PRIVATE(err);
+               return err;
+       }
+@@ -8091,7 +7985,8 @@ create_host_capture_pipeline(struct ia_c
+ }
+ static int capture_start(
+-    struct ia_css_pipe *pipe) {
++    struct ia_css_pipe *pipe)
++{
+       struct ia_css_pipeline *me;
+       int err = 0;
+@@ -8162,7 +8057,8 @@ static int capture_start(
+ static int
+ sh_css_pipe_get_output_frame_info(struct ia_css_pipe *pipe,
+                                   struct ia_css_frame_info *info,
+-                                  unsigned int idx) {
++                                  unsigned int idx)
++{
+       assert(pipe);
+       assert(info);
+@@ -8171,8 +8067,7 @@ sh_css_pipe_get_output_frame_info(struct
+       *info = pipe->output_info[idx];
+       if (copy_on_sp(pipe) &&
+-          pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8)
+-      {
++          pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8) {
+               ia_css_frame_info_init(
+                   info,
+                   JPEG_BYTES,
+@@ -8180,8 +8075,7 @@ sh_css_pipe_get_output_frame_info(struct
+                   IA_CSS_FRAME_FORMAT_BINARY_8,
+                   0);
+       } else if (info->format == IA_CSS_FRAME_FORMAT_RAW ||
+-                  info->format == IA_CSS_FRAME_FORMAT_RAW_PACKED)
+-      {
++                  info->format == IA_CSS_FRAME_FORMAT_RAW_PACKED) {
+               info->raw_bit_depth =
+               ia_css_pipe_util_pipe_input_format_bpp(pipe);
+       }
+@@ -8195,7 +8089,8 @@ void
+ ia_css_stream_send_input_frame(const struct ia_css_stream *stream,
+                               const unsigned short *data,
+                               unsigned int width,
+-                              unsigned int height) {
++                              unsigned int height)
++{
+       assert(stream);
+       ia_css_inputfifo_send_input_frame(
+@@ -8206,7 +8101,8 @@ ia_css_stream_send_input_frame(const str
+ }
+ void
+-ia_css_stream_start_input_frame(const struct ia_css_stream *stream) {
++ia_css_stream_start_input_frame(const struct ia_css_stream *stream)
++{
+       assert(stream);
+       ia_css_inputfifo_start_frame(
+@@ -8220,7 +8116,8 @@ ia_css_stream_send_input_line(const stru
+                               const unsigned short *data,
+                               unsigned int width,
+                               const unsigned short *data2,
+-                              unsigned int width2) {
++                              unsigned int width2)
++{
+       assert(stream);
+       ia_css_inputfifo_send_line(stream->config.channel_id,
+@@ -8231,7 +8128,8 @@ void
+ ia_css_stream_send_input_embedded_line(const struct ia_css_stream *stream,
+                                       enum atomisp_input_format format,
+                                       const unsigned short *data,
+-                                      unsigned int width) {
++                                      unsigned int width)
++{
+       assert(stream);
+       if (!data || width == 0)
+               return;
+@@ -8240,14 +8138,16 @@ ia_css_stream_send_input_embedded_line(c
+ }
+ void
+-ia_css_stream_end_input_frame(const struct ia_css_stream *stream) {
++ia_css_stream_end_input_frame(const struct ia_css_stream *stream)
++{
+       assert(stream);
+       ia_css_inputfifo_end_frame(stream->config.channel_id);
+ }
+ static void
+-append_firmware(struct ia_css_fw_info **l, struct ia_css_fw_info *firmware) {
++append_firmware(struct ia_css_fw_info **l, struct ia_css_fw_info *firmware)
++{
+       IA_CSS_ENTER_PRIVATE("l = %p, firmware = %p", l, firmware);
+       if (!l) {
+               IA_CSS_ERROR("NULL fw_info");
+@@ -8262,7 +8162,8 @@ append_firmware(struct ia_css_fw_info **
+ }
+ static void
+-remove_firmware(struct ia_css_fw_info **l, struct ia_css_fw_info *firmware) {
++remove_firmware(struct ia_css_fw_info **l, struct ia_css_fw_info *firmware)
++{
+       assert(*l);
+       assert(firmware);
+       (void)l;
+@@ -8304,12 +8205,12 @@ static int upload_isp_code(struct ia_css
+ }
+ static int
+-acc_load_extension(struct ia_css_fw_info *firmware) {
++acc_load_extension(struct ia_css_fw_info *firmware)
++{
+       int err;
+       struct ia_css_fw_info *hd = firmware;
+-      while (hd)
+-      {
++      while (hd) {
+               err = upload_isp_code(hd);
+               if (err)
+                       return err;
+@@ -8323,7 +8224,8 @@ acc_load_extension(struct ia_css_fw_info
+ }
+ static void
+-acc_unload_extension(struct ia_css_fw_info *firmware) {
++acc_unload_extension(struct ia_css_fw_info *firmware)
++{
+       struct ia_css_fw_info *hd = firmware;
+       struct ia_css_fw_info *hdn = NULL;
+@@ -8347,13 +8249,13 @@ acc_unload_extension(struct ia_css_fw_in
+ /* Load firmware for extension */
+ static int
+ ia_css_pipe_load_extension(struct ia_css_pipe *pipe,
+-                          struct ia_css_fw_info *firmware) {
++                          struct ia_css_fw_info *firmware)
++{
+       int err = 0;
+       IA_CSS_ENTER_PRIVATE("fw = %p pipe = %p", firmware, pipe);
+-      if ((!firmware) || (!pipe))
+-      {
++      if ((!firmware) || (!pipe)) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+       }
+@@ -8371,7 +8273,8 @@ ia_css_pipe_load_extension(struct ia_css
+ /* Unload firmware for extension */
+ static void
+ ia_css_pipe_unload_extension(struct ia_css_pipe *pipe,
+-                              struct ia_css_fw_info *firmware) {
++                              struct ia_css_fw_info *firmware)
++{
+       IA_CSS_ENTER_PRIVATE("fw = %p pipe = %p", firmware, pipe);
+       if ((!firmware) || (!pipe)) {
+@@ -8390,7 +8293,8 @@ ia_css_pipe_unload_extension(struct ia_c
+ }
+ bool
+-ia_css_pipeline_uses_params(struct ia_css_pipeline *me) {
++ia_css_pipeline_uses_params(struct ia_css_pipeline *me)
++{
+       struct ia_css_pipeline_stage *stage;
+       assert(me);
+@@ -8411,7 +8315,8 @@ ia_css_pipeline_uses_params(struct ia_cs
+ static int
+ sh_css_pipeline_add_acc_stage(struct ia_css_pipeline *pipeline,
+-                              const void *acc_fw) {
++                              const void *acc_fw)
++{
+       struct ia_css_fw_info *fw = (struct ia_css_fw_info *)acc_fw;
+       /* In QoS case, load_extension already called, so skipping */
+       int     err = 0;
+@@ -8423,8 +8328,7 @@ sh_css_pipeline_add_acc_stage(struct ia_
+                           "sh_css_pipeline_add_acc_stage() enter: pipeline=%p, acc_fw=%p\n",
+                           pipeline, acc_fw);
+-      if (!err)
+-      {
++      if (!err) {
+               struct ia_css_pipeline_stage_desc stage_desc;
+               ia_css_pipe_get_acc_stage_desc(&stage_desc, NULL, fw);
+@@ -8443,7 +8347,8 @@ sh_css_pipeline_add_acc_stage(struct ia_
+     * Refer to "sh_css_internal.h" for details.
+     */
+ int ia_css_stream_capture_frame(struct ia_css_stream *stream,
+-      unsigned int exp_id) {
++      unsigned int exp_id)
++{
+       struct sh_css_tag_descr tag_descr;
+       u32 encoded_tag_descr;
+       int err;
+@@ -8485,7 +8390,8 @@ int ia_css_stream_capture(
+     struct ia_css_stream *stream,
+     int num_captures,
+     unsigned int skip,
+-    int offset) {
++    int offset)
++{
+       struct sh_css_tag_descr tag_descr;
+       unsigned int encoded_tag_descr;
+       int return_err;
+@@ -8548,8 +8454,9 @@ void ia_css_stream_request_flash(struct
+                       ia_css_debug_dump_sp_sw_debug_info();
+                       ia_css_debug_dump_debug_info(NULL);
+               }
+-      } else
++      } else {
+               IA_CSS_LOG("SP is not running!");
++      }
+ #endif
+       ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
+@@ -8557,7 +8464,8 @@ void ia_css_stream_request_flash(struct
+ }
+ static void
+-sh_css_init_host_sp_control_vars(void) {
++sh_css_init_host_sp_control_vars(void)
++{
+       const struct ia_css_fw_info *fw;
+       unsigned int HIVE_ADDR_ia_css_ispctrl_sp_isp_started;
+@@ -8641,7 +8549,8 @@ void ia_css_pipe_config_defaults(struct
+ void
+ ia_css_pipe_extra_config_defaults(struct ia_css_pipe_extra_config
+-                                  *extra_config) {
++                                  *extra_config)
++{
+       if (!extra_config) {
+               IA_CSS_ERROR("NULL input parameter");
+               return;
+@@ -8671,11 +8580,11 @@ void ia_css_stream_config_defaults(struc
+ }
+ static int
+-ia_css_acc_pipe_create(struct ia_css_pipe *pipe) {
++ia_css_acc_pipe_create(struct ia_css_pipe *pipe)
++{
+       int err = 0;
+-      if (!pipe)
+-      {
++      if (!pipe) {
+               IA_CSS_ERROR("NULL input parameter");
+               return -EINVAL;
+       }
+@@ -8685,9 +8594,7 @@ ia_css_acc_pipe_create(struct ia_css_pip
+               pipe->config.acc_num_execs = 1;
+       if (pipe->config.acc_extension)
+-      {
+               err = ia_css_pipe_load_extension(pipe, pipe->config.acc_extension);
+-      }
+       return err;
+ }
+@@ -8706,9 +8613,8 @@ int ia_css_pipe_create(const struct ia_c
+       err = ia_css_pipe_create_extra(config, NULL, pipe);
+-      if (err == 0) {
++      if (err == 0)
+               IA_CSS_LOG("pipe created successfully = %p", *pipe);
+-      }
+       IA_CSS_LEAVE_ERR_PRIVATE(err);
+@@ -8718,7 +8624,8 @@ int ia_css_pipe_create(const struct ia_c
+ int
+ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config,
+                           const struct ia_css_pipe_extra_config *extra_config,
+-                          struct ia_css_pipe **pipe) {
++                          struct ia_css_pipe **pipe)
++{
+       int err = -EINVAL;
+       struct ia_css_pipe *internal_pipe = NULL;
+       unsigned int i;
+@@ -8726,14 +8633,12 @@ ia_css_pipe_create_extra(const struct ia
+       IA_CSS_ENTER_PRIVATE("config = %p, extra_config = %p and pipe = %p", config, extra_config, pipe);
+       /* do not allow to create more than the maximum limit */
+-      if (my_css.pipe_counter >= IA_CSS_PIPELINE_NUM_MAX)
+-      {
++      if (my_css.pipe_counter >= IA_CSS_PIPELINE_NUM_MAX) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-ENOSPC);
+               return -EINVAL;
+       }
+-      if ((!pipe) || (!config))
+-      {
++      if ((!pipe) || (!config)) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+       }
+@@ -8742,8 +8647,7 @@ ia_css_pipe_create_extra(const struct ia
+       ia_css_debug_dump_pipe_extra_config(extra_config);
+       err = create_pipe(config->mode, &internal_pipe, false);
+-      if (err)
+-      {
++      if (err) {
+               IA_CSS_LEAVE_ERR_PRIVATE(err);
+               return err;
+       }
+@@ -8755,8 +8659,7 @@ ia_css_pipe_create_extra(const struct ia
+       else
+               ia_css_pipe_extra_config_defaults(&internal_pipe->extra_config);
+-      if (config->mode == IA_CSS_PIPE_MODE_ACC)
+-      {
++      if (config->mode == IA_CSS_PIPE_MODE_ACC) {
+               /* Temporary hack to migrate acceleration to CSS 2.0.
+                   * In the future the code for all pipe types should be
+                   * unified. */
+@@ -8783,15 +8686,13 @@ ia_css_pipe_create_extra(const struct ia
+           set bayer_ds_out_res equal to IF output resolution(IF may do cropping on
+           sensor output) or use default decimation factor 1. */
+       if (internal_pipe->extra_config.enable_raw_binning &&
+-          internal_pipe->config.bayer_ds_out_res.width)
+-      {
++          internal_pipe->config.bayer_ds_out_res.width) {
+               /* fill some code here, if no code is needed, please remove it during integration */
+       }
+       /* YUV downscaling */
+       if ((internal_pipe->config.vf_pp_in_res.width ||
+-              internal_pipe->config.capt_pp_in_res.width))
+-      {
++              internal_pipe->config.capt_pp_in_res.width)) {
+               enum ia_css_frame_format format;
+               if (internal_pipe->config.vf_pp_in_res.width) {
+@@ -8812,8 +8713,7 @@ ia_css_pipe_create_extra(const struct ia
+               }
+       }
+       if (internal_pipe->config.vf_pp_in_res.width &&
+-          internal_pipe->config.mode == IA_CSS_PIPE_MODE_PREVIEW)
+-      {
++          internal_pipe->config.mode == IA_CSS_PIPE_MODE_PREVIEW) {
+               ia_css_frame_info_init(
+                   &internal_pipe->vf_yuv_ds_input_info,
+                   internal_pipe->config.vf_pp_in_res.width,
+@@ -8821,8 +8721,7 @@ ia_css_pipe_create_extra(const struct ia
+                   IA_CSS_FRAME_FORMAT_YUV_LINE, 0);
+       }
+       /* handle bayer downscaling output info */
+-      if (internal_pipe->config.bayer_ds_out_res.width)
+-      {
++      if (internal_pipe->config.bayer_ds_out_res.width) {
+               ia_css_frame_info_init(
+                   &internal_pipe->bds_output_info,
+                   internal_pipe->config.bayer_ds_out_res.width,
+@@ -8831,8 +8730,7 @@ ia_css_pipe_create_extra(const struct ia
+       }
+       /* handle output info, assume always needed */
+-      for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++)
+-      {
++      for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
+               if (internal_pipe->config.output_info[i].res.width) {
+                       err = sh_css_pipe_configure_output(
+                                   internal_pipe,
+@@ -8868,8 +8766,7 @@ ia_css_pipe_create_extra(const struct ia
+                       }
+               }
+       }
+-      if (internal_pipe->config.acc_extension)
+-      {
++      if (internal_pipe->config.acc_extension) {
+               err = ia_css_pipe_load_extension(internal_pipe,
+                                                   internal_pipe->config.acc_extension);
+               if (err) {
+@@ -8889,18 +8786,18 @@ ia_css_pipe_create_extra(const struct ia
+ int
+ ia_css_pipe_get_info(const struct ia_css_pipe *pipe,
+-                      struct ia_css_pipe_info *pipe_info) {
++                      struct ia_css_pipe_info *pipe_info)
++{
+       ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
+                           "ia_css_pipe_get_info()\n");
++
+       assert(pipe_info);
+-      if (!pipe_info)
+-      {
++      if (!pipe_info) {
+               ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
+                                   "ia_css_pipe_get_info: pipe_info cannot be NULL\n");
+               return -EINVAL;
+       }
+-      if (!pipe || !pipe->stream)
+-      {
++      if (!pipe || !pipe->stream) {
+               ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
+                                   "ia_css_pipe_get_info: ia_css_stream_create needs to be called before ia_css_[stream/pipe]_get_info\n");
+               return -EINVAL;
+@@ -8928,40 +8825,36 @@ bool ia_css_pipe_has_dvs_stats(struct ia
+ int
+ ia_css_pipe_override_frame_format(struct ia_css_pipe *pipe,
+                                   int pin_index,
+-                                  enum ia_css_frame_format new_format) {
++                                  enum ia_css_frame_format new_format)
++{
+       int err = 0;
+       IA_CSS_ENTER_PRIVATE("pipe = %p, pin_index = %d, new_formats = %d", pipe, pin_index, new_format);
+-      if (!pipe)
+-      {
++      if (!pipe) {
+               IA_CSS_ERROR("pipe is not set");
+               err = -EINVAL;
+               IA_CSS_LEAVE_ERR_PRIVATE(err);
+               return err;
+       }
+-      if (0 != pin_index && 1 != pin_index)
+-      {
++      if (0 != pin_index && 1 != pin_index) {
+               IA_CSS_ERROR("pin index is not valid");
+               err = -EINVAL;
+               IA_CSS_LEAVE_ERR_PRIVATE(err);
+               return err;
+       }
+-      if (new_format != IA_CSS_FRAME_FORMAT_NV12_TILEY)
+-      {
++      if (new_format != IA_CSS_FRAME_FORMAT_NV12_TILEY) {
+               IA_CSS_ERROR("new format is not valid");
+               err = -EINVAL;
+               IA_CSS_LEAVE_ERR_PRIVATE(err);
+               return err;
+-      } else
+-      {
++      } else {
+               err = ia_css_pipe_check_format(pipe, new_format);
+               if (!err) {
+-                      if (pin_index == 0) {
++                      if (pin_index == 0)
+                               pipe->output_info[0].format = new_format;
+-                      } else {
++                      else
+                               pipe->vf_output_info[0].format = new_format;
+-                      }
+               }
+       }
+       IA_CSS_LEAVE_ERR_PRIVATE(err);
+@@ -8971,7 +8864,8 @@ ia_css_pipe_override_frame_format(struct
+ #if !defined(ISP2401)
+ /* Configuration of INPUT_SYSTEM_VERSION_2401 is done on SP */
+ static int
+-ia_css_stream_configure_rx(struct ia_css_stream *stream) {
++ia_css_stream_configure_rx(struct ia_css_stream *stream)
++{
+       struct ia_css_input_port *config;
+       assert(stream);
+@@ -9000,11 +8894,10 @@ ia_css_stream_configure_rx(struct ia_css
+       if (config->compression.type == IA_CSS_CSI2_COMPRESSION_TYPE_NONE)
+               stream->csi_rx_config.comp = MIPI_PREDICTOR_NONE;
+       else
+-      {
+               /* not implemented yet, requires extension of the rx_cfg_t
+                   * struct */
+               return -EINVAL;
+-      }
++
+       stream->csi_rx_config.is_two_ppc = (stream->config.pixels_per_clock == 2);
+       stream->reconfigure_css_rx = true;
+       return 0;
+@@ -9015,7 +8908,8 @@ static struct ia_css_pipe *
+ find_pipe(struct ia_css_pipe *pipes[],
+           unsigned int num_pipes,
+           enum ia_css_pipe_mode mode,
+-          bool copy_pipe) {
++          bool copy_pipe)
++{
+       unsigned int i;
+       assert(pipes);
+@@ -9031,21 +8925,20 @@ find_pipe(struct ia_css_pipe *pipes[],
+ }
+ static int
+-ia_css_acc_stream_create(struct ia_css_stream *stream) {
++ia_css_acc_stream_create(struct ia_css_stream *stream)
++{
+       int i;
+       int err = 0;
+       assert(stream);
+       IA_CSS_ENTER_PRIVATE("stream = %p", stream);
+-      if (!stream)
+-      {
++      if (!stream) {
+               IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+               return -EINVAL;
+       }
+-      for (i = 0;  i < stream->num_pipes; i++)
+-      {
++      for (i = 0;  i < stream->num_pipes; i++) {
+               struct ia_css_pipe *pipe = stream->pipes[i];
+               assert(pipe);
+@@ -9059,14 +8952,12 @@ ia_css_acc_stream_create(struct ia_css_s
+       /* Map SP threads before doing anything. */
+       err = map_sp_threads(stream, true);
+-      if (err)
+-      {
++      if (err) {
+               IA_CSS_LEAVE_ERR_PRIVATE(err);
+               return err;
+       }
+-      for (i = 0;  i < stream->num_pipes; i++)
+-      {
++      for (i = 0;  i < stream->num_pipes; i++) {
+               struct ia_css_pipe *pipe = stream->pipes[i];
+               assert(pipe);
+@@ -9074,8 +8965,7 @@ ia_css_acc_stream_create(struct ia_css_s
+       }
+       err = create_host_pipeline_structure(stream);
+-      if (err)
+-      {
++      if (err) {
+               IA_CSS_LEAVE_ERR_PRIVATE(err);
+               return err;
+       }
+@@ -9089,7 +8979,8 @@ ia_css_acc_stream_create(struct ia_css_s
+ static int
+ metadata_info_init(const struct ia_css_metadata_config *mdc,
+-                  struct ia_css_metadata_info *md) {
++                  struct ia_css_metadata_info *md)
++{
+       /* Either both width and height should be set or neither */
+       if ((mdc->resolution.height > 0) ^ (mdc->resolution.width > 0))
+               return -EINVAL;
+@@ -9149,7 +9040,8 @@ int
+ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
+                       int num_pipes,
+                       struct ia_css_pipe *pipes[],
+-                      struct ia_css_stream **stream) {
++                      struct ia_css_stream **stream)
++{
+       struct ia_css_pipe *curr_pipe;
+       struct ia_css_stream *curr_stream = NULL;
+       bool spcopyonly;
+@@ -9168,8 +9060,7 @@ ia_css_stream_create(const struct ia_css
+       /* some checks */
+       if (num_pipes == 0 ||
+           !stream ||
+-          !pipes)
+-      {
++          !pipes) {
+               err = -EINVAL;
+               IA_CSS_LEAVE_ERR(err);
+               return err;
+@@ -9178,8 +9069,7 @@ ia_css_stream_create(const struct ia_css
+ #if !defined(ISP2401)
+       /* We don't support metadata for JPEG stream, since they both use str2mem */
+       if (stream_config->input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8 &&
+-          stream_config->metadata_config.resolution.height > 0)
+-      {
++          stream_config->metadata_config.resolution.height > 0) {
+               err = -EINVAL;
+               IA_CSS_LEAVE_ERR(err);
+               return err;
+@@ -9187,8 +9077,7 @@ ia_css_stream_create(const struct ia_css
+ #endif
+ #ifdef ISP2401
+-      if (stream_config->online && stream_config->pack_raw_pixels)
+-      {
++      if (stream_config->online && stream_config->pack_raw_pixels) {
+               IA_CSS_LOG("online and pack raw is invalid on input system 2401");
+               err = -EINVAL;
+               IA_CSS_LEAVE_ERR(err);
+@@ -9243,16 +9132,14 @@ ia_css_stream_create(const struct ia_css
+       /* Currently we only supported metadata up to a certain size. */
+       err = metadata_info_init(&stream_config->metadata_config, &md_info);
+-      if (err)
+-      {
++      if (err) {
+               IA_CSS_LEAVE_ERR(err);
+               return err;
+       }
+       /* allocate the stream instance */
+       curr_stream = kzalloc(sizeof(struct ia_css_stream), GFP_KERNEL);
+-      if (!curr_stream)
+-      {
++      if (!curr_stream) {
+               err = -ENOMEM;
+               IA_CSS_LEAVE_ERR(err);
+               return err;
+@@ -9263,8 +9150,7 @@ ia_css_stream_create(const struct ia_css
+       /* allocate pipes */
+       curr_stream->num_pipes = num_pipes;
+       curr_stream->pipes = kcalloc(num_pipes, sizeof(struct ia_css_pipe *), GFP_KERNEL);
+-      if (!curr_stream->pipes)
+-      {
++      if (!curr_stream->pipes) {
+               curr_stream->num_pipes = 0;
+               kfree(curr_stream);
+               curr_stream = NULL;
+@@ -9287,8 +9173,7 @@ ia_css_stream_create(const struct ia_css
+ #endif
+ #ifdef ISP2401
+-      if (curr_stream->config.online)
+-      {
++      if (curr_stream->config.online) {
+               curr_stream->config.source.port.num_lanes =
+                   stream_config->source.port.num_lanes;
+               curr_stream->config.mode =  IA_CSS_INPUT_MODE_BUFFERED_SENSOR;
+@@ -9306,8 +9191,7 @@ ia_css_stream_create(const struct ia_css
+                   curr_stream->config.lock_all);
+       /* copy mode specific stuff */
+-      switch (curr_stream->config.mode)
+-      {
++      switch (curr_stream->config.mode) {
+       case IA_CSS_INPUT_MODE_SENSOR:
+       case IA_CSS_INPUT_MODE_BUFFERED_SENSOR:
+ #if !defined(ISP2401)
+@@ -9349,14 +9233,12 @@ ia_css_stream_create(const struct ia_css
+       err = aspect_ratio_crop_init(curr_stream,
+                                       pipes,
+                                       &aspect_ratio_crop_enabled);
+-      if (err)
+-      {
++      if (err) {
+               IA_CSS_LEAVE_ERR(err);
+               goto ERR;
+       }
+ #endif
+-      for (i = 0; i < num_pipes; i++)
+-      {
++      for (i = 0; i < num_pipes; i++) {
+               struct ia_css_resolution effective_res;
+               curr_pipe = pipes[i];
+@@ -9396,9 +9278,8 @@ ia_css_stream_create(const struct ia_css
+                       if (pipes[i]->config.mode != IA_CSS_PIPE_MODE_ACC &&
+                           pipes[i]->config.mode != IA_CSS_PIPE_MODE_COPY) {
+                               err = check_pipe_resolutions(pipes[i]);
+-                              if (err) {
++                              if (err)
+                                       goto ERR;
+-                              }
+                       }
+               }
+       }
+@@ -9408,20 +9289,17 @@ ia_css_stream_create(const struct ia_css
+               goto ERR;
+       IA_CSS_LOG("isp_params_configs: %p", curr_stream->isp_params_configs);
+-      if (num_pipes == 1 && pipes[0]->config.mode == IA_CSS_PIPE_MODE_ACC)
+-      {
++      if (num_pipes == 1 && pipes[0]->config.mode == IA_CSS_PIPE_MODE_ACC) {
+               *stream = curr_stream;
+               err = ia_css_acc_stream_create(curr_stream);
+               goto ERR;
+       }
+       /* sensor binning */
+-      if (!spcopyonly)
+-      {
++      if (!spcopyonly) {
+               sensor_binning_changed =
+                   sh_css_params_set_binning_factor(curr_stream,
+                                                       curr_stream->config.sensor_binning_factor);
+-      } else
+-      {
++      } else {
+               sensor_binning_changed = false;
+       }
+@@ -9432,8 +9310,7 @@ ia_css_stream_create(const struct ia_css
+       curr_stream->cont_capt = false;
+       /* Temporary hack: we give the preview pipe a reference to the capture
+           * pipe in continuous capture mode. */
+-      if (curr_stream->config.continuous)
+-      {
++      if (curr_stream->config.continuous) {
+               /* Search for the preview pipe and create the copy pipe */
+               struct ia_css_pipe *preview_pipe;
+               struct ia_css_pipe *video_pipe;
+@@ -9481,9 +9358,9 @@ ia_css_stream_create(const struct ia_css
+                       preview_pipe->pipe_settings.preview.copy_pipe = copy_pipe;
+                       copy_pipe->stream = curr_stream;
+               }
+-              if (preview_pipe && curr_stream->cont_capt) {
++              if (preview_pipe && curr_stream->cont_capt)
+                       preview_pipe->pipe_settings.preview.capture_pipe = capture_pipe;
+-              }
++
+               if (video_pipe && !video_pipe->pipe_settings.video.copy_pipe) {
+                       err = create_pipe(IA_CSS_PIPE_MODE_CAPTURE, &copy_pipe, true);
+                       if (err)
+@@ -9492,15 +9369,13 @@ ia_css_stream_create(const struct ia_css
+                       video_pipe->pipe_settings.video.copy_pipe = copy_pipe;
+                       copy_pipe->stream = curr_stream;
+               }
+-              if (video_pipe && curr_stream->cont_capt) {
++              if (video_pipe && curr_stream->cont_capt)
+                       video_pipe->pipe_settings.video.capture_pipe = capture_pipe;
+-              }
+-              if (preview_pipe && acc_pipe) {
++
++              if (preview_pipe && acc_pipe)
+                       preview_pipe->pipe_settings.preview.acc_pipe = acc_pipe;
+-              }
+       }
+-      for (i = 0; i < num_pipes; i++)
+-      {
++      for (i = 0; i < num_pipes; i++) {
+               curr_pipe = pipes[i];
+               /* set current stream */
+               curr_pipe->stream = curr_stream;
+@@ -9521,8 +9396,7 @@ ia_css_stream_create(const struct ia_css
+       }
+       /* now pipes have been configured, info should be available */
+-      for (i = 0; i < num_pipes; i++)
+-      {
++      for (i = 0; i < num_pipes; i++) {
+               struct ia_css_pipe_info *pipe_info = NULL;
+               curr_pipe = pipes[i];
+@@ -9572,22 +9446,19 @@ ia_css_stream_create(const struct ia_css
+       /* Map SP threads before doing anything. */
+       err = map_sp_threads(curr_stream, true);
+-      if (err)
+-      {
++      if (err) {
+               IA_CSS_LOG("map_sp_threads: return_err=%d", err);
+               goto ERR;
+       }
+-      for (i = 0; i < num_pipes; i++)
+-      {
++      for (i = 0; i < num_pipes; i++) {
+               curr_pipe = pipes[i];
+               ia_css_pipe_map_queue(curr_pipe, true);
+       }
+       /* Create host side pipeline objects without stages */
+       err = create_host_pipeline_structure(curr_stream);
+-      if (err)
+-      {
++      if (err) {
+               IA_CSS_LOG("create_host_pipeline_structure: return_err=%d", err);
+               goto ERR;
+       }
+@@ -9625,13 +9496,13 @@ ERR:
+ }
+ int
+-ia_css_stream_destroy(struct ia_css_stream *stream) {
++ia_css_stream_destroy(struct ia_css_stream *stream)
++{
+       int i;
+       int err = 0;
+       IA_CSS_ENTER_PRIVATE("stream = %p", stream);
+-      if (!stream)
+-      {
++      if (!stream) {
+               err = -EINVAL;
+               IA_CSS_LEAVE_ERR_PRIVATE(err);
+               return err;
+@@ -9640,8 +9511,7 @@ ia_css_stream_destroy(struct ia_css_stre
+       ia_css_stream_isp_parameters_uninit(stream);
+       if ((stream->last_pipe) &&
+-          ia_css_pipeline_is_mapped(stream->last_pipe->pipe_num))
+-      {
++          ia_css_pipeline_is_mapped(stream->last_pipe->pipe_num)) {
+ #if defined(ISP2401)
+               bool free_mpi;
+@@ -9703,8 +9573,7 @@ ia_css_stream_destroy(struct ia_css_stre
+       }
+       /* remove references from pipes to stream */
+-      for (i = 0; i < stream->num_pipes; i++)
+-      {
++      for (i = 0; i < stream->num_pipes; i++) {
+               struct ia_css_pipe *entry = stream->pipes[i];
+               assert(entry);
+@@ -9733,8 +9602,7 @@ ia_css_stream_destroy(struct ia_css_stre
+       /* working mode: take out of the seed list */
+       if (my_css_save.mode == sh_css_mode_working) {
+               for (i = 0; i < MAX_ACTIVE_STREAMS; i++) {
+-                      if (my_css_save.stream_seeds[i].stream == stream)
+-                      {
++                      if (my_css_save.stream_seeds[i].stream == stream) {
+                               IA_CSS_LOG("took out stream %d", i);
+                               my_css_save.stream_seeds[i].stream = NULL;
+                               break;
+@@ -9750,7 +9618,8 @@ ia_css_stream_destroy(struct ia_css_stre
+ int
+ ia_css_stream_get_info(const struct ia_css_stream *stream,
+-                      struct ia_css_stream_info *stream_info) {
++                      struct ia_css_stream_info *stream_info)
++{
+       ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_get_info: enter/exit\n");
+       assert(stream);
+       assert(stream_info);
+@@ -9766,15 +9635,15 @@ ia_css_stream_get_info(const struct ia_c
+     * The stream handle is used to identify the correct entry in the css_save struct
+     */
+ int
+-ia_css_stream_load(struct ia_css_stream *stream) {
++ia_css_stream_load(struct ia_css_stream *stream)
++{
+       if (!IS_ISP2401) {
+               int i;
+               int err;
+               assert(stream);
+               ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_load() enter,\n");
+-              for (i = 0; i < MAX_ACTIVE_STREAMS; i++)
+-              {
++              for (i = 0; i < MAX_ACTIVE_STREAMS; i++) {
+                       if (my_css_save.stream_seeds[i].stream == stream) {
+                               int j;
+@@ -9813,12 +9682,12 @@ ia_css_stream_load(struct ia_css_stream
+ }
+ int
+-ia_css_stream_start(struct ia_css_stream *stream) {
++ia_css_stream_start(struct ia_css_stream *stream)
++{
+       int err = 0;
+       IA_CSS_ENTER("stream = %p", stream);
+-      if ((!stream) || (!stream->last_pipe))
+-      {
++      if ((!stream) || (!stream->last_pipe)) {
+               IA_CSS_LEAVE_ERR(-EINVAL);
+               return -EINVAL;
+       }
+@@ -9828,8 +9697,7 @@ ia_css_stream_start(struct ia_css_stream
+       /* Create host side pipeline. */
+       err = create_host_pipeline(stream);
+-      if (err)
+-      {
++      if (err) {
+               IA_CSS_LEAVE_ERR(err);
+               return err;
+       }
+@@ -9842,8 +9710,7 @@ ia_css_stream_start(struct ia_css_stream
+ #if !defined(ISP2401)
+       /* Initialize mipi size checks */
+-      if (stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR)
+-      {
++      if (stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR) {
+               unsigned int idx;
+               unsigned int port = (unsigned int)(stream->config.source.port.port);
+@@ -9854,8 +9721,7 @@ ia_css_stream_start(struct ia_css_stream
+       }
+ #endif
+-      if (stream->config.mode != IA_CSS_INPUT_MODE_MEMORY)
+-      {
++      if (stream->config.mode != IA_CSS_INPUT_MODE_MEMORY) {
+               err = sh_css_config_input_network(stream);
+               if (err)
+                       return err;
+@@ -9867,7 +9733,8 @@ ia_css_stream_start(struct ia_css_stream
+ }
+ int
+-ia_css_stream_stop(struct ia_css_stream *stream) {
++ia_css_stream_stop(struct ia_css_stream *stream)
++{
+       int err = 0;
+       ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_stop() enter/exit\n");
+@@ -9878,22 +9745,19 @@ ia_css_stream_stop(struct ia_css_stream
+ #if !defined(ISP2401)
+       /* De-initialize mipi size checks */
+-      if (stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR)
+-      {
++      if (stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR) {
+               unsigned int idx;
+               unsigned int port = (unsigned int)(stream->config.source.port.port);
+-              for (idx = 0; idx < IA_CSS_MIPI_SIZE_CHECK_MAX_NOF_ENTRIES_PER_PORT; idx++) {
++              for (idx = 0; idx < IA_CSS_MIPI_SIZE_CHECK_MAX_NOF_ENTRIES_PER_PORT; idx++)
+                       sh_css_sp_group.config.mipi_sizes_for_check[port][idx] = 0;
+-              }
+       }
+ #endif
+-      if (!IS_ISP2401) {
++      if (!IS_ISP2401)
+               err = ia_css_pipeline_request_stop(&stream->last_pipe->pipeline);
+-      } else {
++      else
+               err = sh_css_pipes_stop(stream);
+-      }
+       if (err)
+               return err;
+@@ -9906,16 +9770,16 @@ ia_css_stream_stop(struct ia_css_stream
+ }
+ bool
+-ia_css_stream_has_stopped(struct ia_css_stream *stream) {
++ia_css_stream_has_stopped(struct ia_css_stream *stream)
++{
+       bool stopped;
+       assert(stream);
+-      if (!IS_ISP2401) {
++      if (!IS_ISP2401)
+               stopped = ia_css_pipeline_has_stopped(&stream->last_pipe->pipeline);
+-      } else {
++      else
+               stopped = sh_css_pipes_have_stopped(stream);
+-      }
+       return stopped;
+ }
+@@ -9926,7 +9790,8 @@ ia_css_stream_has_stopped(struct ia_css_
+     * The stream handle is used to identify the correct entry in the css_save struct
+     */
+ int
+-ia_css_stream_unload(struct ia_css_stream *stream) {
++ia_css_stream_unload(struct ia_css_stream *stream)
++{
+       int i;
+       assert(stream);
+@@ -9934,8 +9799,7 @@ ia_css_stream_unload(struct ia_css_strea
+       /* some checks */
+       assert(stream);
+       for (i = 0; i < MAX_ACTIVE_STREAMS; i++)
+-              if (my_css_save.stream_seeds[i].stream == stream)
+-              {
++              if (my_css_save.stream_seeds[i].stream == stream) {
+                       int j;
+                       ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
+@@ -9955,7 +9819,8 @@ ia_css_stream_unload(struct ia_css_strea
+ int
+ ia_css_temp_pipe_to_pipe_id(const struct ia_css_pipe *pipe,
+-                          enum ia_css_pipe_id *pipe_id) {
++                          enum ia_css_pipe_id *pipe_id)
++{
+       ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_temp_pipe_to_pipe_id() enter/exit\n");
+       if (pipe)
+               *pipe_id = pipe->mode;
+@@ -9966,18 +9831,21 @@ ia_css_temp_pipe_to_pipe_id(const struct
+ }
+ enum atomisp_input_format
+-ia_css_stream_get_format(const struct ia_css_stream *stream) {
++ia_css_stream_get_format(const struct ia_css_stream *stream)
++{
+       return stream->config.input_config.format;
+ }
+ bool
+-ia_css_stream_get_two_pixels_per_clock(const struct ia_css_stream *stream) {
++ia_css_stream_get_two_pixels_per_clock(const struct ia_css_stream *stream)
++{
+       return (stream->config.pixels_per_clock == 2);
+ }
+ struct ia_css_binary *
+ ia_css_stream_get_shading_correction_binary(const struct ia_css_stream
+-      *stream) {
++      *stream)
++{
+       struct ia_css_pipe *pipe;
+       assert(stream);
+@@ -9995,7 +9863,8 @@ ia_css_stream_get_shading_correction_bin
+ }
+ struct ia_css_binary *
+-ia_css_stream_get_dvs_binary(const struct ia_css_stream *stream) {
++ia_css_stream_get_dvs_binary(const struct ia_css_stream *stream)
++{
+       int i;
+       struct ia_css_pipe *video_pipe = NULL;
+@@ -10014,7 +9883,8 @@ ia_css_stream_get_dvs_binary(const struc
+ }
+ struct ia_css_binary *
+-ia_css_stream_get_3a_binary(const struct ia_css_stream *stream) {
++ia_css_stream_get_3a_binary(const struct ia_css_stream *stream)
++{
+       struct ia_css_pipe *pipe;
+       struct ia_css_binary *s3a_binary = NULL;
+@@ -10036,7 +9906,8 @@ ia_css_stream_get_3a_binary(const struct
+ int
+ ia_css_stream_set_output_padded_width(struct ia_css_stream *stream,
+-                                      unsigned int output_padded_width) {
++                                      unsigned int output_padded_width)
++{
+       struct ia_css_pipe *pipe;
+       assert(stream);
+@@ -10053,7 +9924,8 @@ ia_css_stream_set_output_padded_width(st
+ }
+ static struct ia_css_binary *
+-ia_css_pipe_get_shading_correction_binary(const struct ia_css_pipe *pipe) {
++ia_css_pipe_get_shading_correction_binary(const struct ia_css_pipe *pipe)
++{
+       struct ia_css_binary *binary = NULL;
+       assert(pipe);
+@@ -10098,7 +9970,8 @@ ia_css_pipe_get_shading_correction_binar
+ }
+ static struct ia_css_binary *
+-ia_css_pipe_get_s3a_binary(const struct ia_css_pipe *pipe) {
++ia_css_pipe_get_s3a_binary(const struct ia_css_pipe *pipe)
++{
+       struct ia_css_binary *binary = NULL;
+       assert(pipe);
+@@ -10121,9 +9994,9 @@ ia_css_pipe_get_s3a_binary(const struct
+                               }
+                       }
+               } else if (pipe->config.default_capture_config.mode ==
+-                          IA_CSS_CAPTURE_MODE_BAYER)
++                          IA_CSS_CAPTURE_MODE_BAYER) {
+                       binary = (struct ia_css_binary *)&pipe->pipe_settings.capture.pre_isp_binary;
+-              else if (pipe->config.default_capture_config.mode ==
++              } else if (pipe->config.default_capture_config.mode ==
+                           IA_CSS_CAPTURE_MODE_ADVANCED ||
+                           pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_LOW_LIGHT) {
+                       if (pipe->config.isp_pipe_version == IA_CSS_PIPE_VERSION_1)
+@@ -10145,7 +10018,8 @@ ia_css_pipe_get_s3a_binary(const struct
+ }
+ static struct ia_css_binary *
+-ia_css_pipe_get_sdis_binary(const struct ia_css_pipe *pipe) {
++ia_css_pipe_get_sdis_binary(const struct ia_css_pipe *pipe)
++{
+       struct ia_css_binary *binary = NULL;
+       assert(pipe);
+@@ -10165,14 +10039,16 @@ ia_css_pipe_get_sdis_binary(const struct
+ }
+ struct ia_css_pipeline *
+-ia_css_pipe_get_pipeline(const struct ia_css_pipe *pipe) {
++ia_css_pipe_get_pipeline(const struct ia_css_pipe *pipe)
++{
+       assert(pipe);
+       return (struct ia_css_pipeline *)&pipe->pipeline;
+ }
+ unsigned int
+-ia_css_pipe_get_pipe_num(const struct ia_css_pipe *pipe) {
++ia_css_pipe_get_pipe_num(const struct ia_css_pipe *pipe)
++{
+       assert(pipe);
+       /* KW was not sure this function was not returning a value
+@@ -10189,7 +10065,8 @@ ia_css_pipe_get_pipe_num(const struct ia
+ }
+ unsigned int
+-ia_css_pipe_get_isp_pipe_version(const struct ia_css_pipe *pipe) {
++ia_css_pipe_get_isp_pipe_version(const struct ia_css_pipe *pipe)
++{
+       assert(pipe);
+       return (unsigned int)pipe->config.isp_pipe_version;
+@@ -10198,7 +10075,8 @@ ia_css_pipe_get_isp_pipe_version(const s
+ #define SP_START_TIMEOUT_US 30000000
+ int
+-ia_css_start_sp(void) {
++ia_css_start_sp(void)
++{
+       unsigned long timeout;
+       int err = 0;
+@@ -10207,13 +10085,11 @@ ia_css_start_sp(void) {
+       /* waiting for the SP is completely started */
+       timeout = SP_START_TIMEOUT_US;
+-      while ((ia_css_spctrl_get_state(SP0_ID) != IA_CSS_SP_SW_INITIALIZED) && timeout)
+-      {
++      while ((ia_css_spctrl_get_state(SP0_ID) != IA_CSS_SP_SW_INITIALIZED) && timeout) {
+               timeout--;
+               udelay(1);
+       }
+-      if (timeout == 0)
+-      {
++      if (timeout == 0) {
+               IA_CSS_ERROR("timeout during SP initialization");
+               return -EINVAL;
+       }
+@@ -10241,14 +10117,14 @@ ia_css_start_sp(void) {
+ #define SP_SHUTDOWN_TIMEOUT_US 200000
+ int
+-ia_css_stop_sp(void) {
++ia_css_stop_sp(void)
++{
+       unsigned long timeout;
+       int err = 0;
+       IA_CSS_ENTER("void");
+-      if (!sh_css_sp_is_running())
+-      {
++      if (!sh_css_sp_is_running()) {
+               err = -EINVAL;
+               IA_CSS_LEAVE("SP already stopped : return_err=%d", err);
+@@ -10260,8 +10136,7 @@ ia_css_stop_sp(void) {
+       if (!IS_ISP2401) {
+               sh_css_write_host2sp_command(host2sp_cmd_terminate);
+       } else {
+-              if (!sh_css_write_host2sp_command(host2sp_cmd_terminate))
+-              {
++              if (!sh_css_write_host2sp_command(host2sp_cmd_terminate)) {
+                       IA_CSS_ERROR("Call to 'sh-css_write_host2sp_command()' failed");
+                       ia_css_debug_dump_sp_sw_debug_info();
+                       ia_css_debug_dump_debug_info(NULL);
+@@ -10271,27 +10146,23 @@ ia_css_stop_sp(void) {
+       sh_css_sp_set_sp_running(false);
+       timeout = SP_SHUTDOWN_TIMEOUT_US;
+-      while (!ia_css_spctrl_is_idle(SP0_ID) && timeout)
+-      {
++      while (!ia_css_spctrl_is_idle(SP0_ID) && timeout) {
+               timeout--;
+               udelay(1);
+       }
+       if ((ia_css_spctrl_get_state(SP0_ID) != IA_CSS_SP_SW_TERMINATED))
+               IA_CSS_WARNING("SP has not terminated (SW)");
+-      if (timeout == 0)
+-      {
++      if (timeout == 0) {
+               IA_CSS_WARNING("SP is not idle");
+               ia_css_debug_dump_sp_sw_debug_info();
+       }
+       timeout = SP_SHUTDOWN_TIMEOUT_US;
+-      while (!isp_ctrl_getbit(ISP0_ID, ISP_SC_REG, ISP_IDLE_BIT) && timeout)
+-      {
++      while (!isp_ctrl_getbit(ISP0_ID, ISP_SC_REG, ISP_IDLE_BIT) && timeout) {
+               timeout--;
+               udelay(1);
+       }
+-      if (timeout == 0)
+-      {
++      if (timeout == 0) {
+               IA_CSS_WARNING("ISP is not idle");
+               ia_css_debug_dump_sp_sw_debug_info();
+       }
+@@ -10306,7 +10177,8 @@ ia_css_stop_sp(void) {
+ }
+ int
+-ia_css_update_continuous_frames(struct ia_css_stream *stream) {
++ia_css_update_continuous_frames(struct ia_css_stream *stream)
++{
+       struct ia_css_pipe *pipe;
+       unsigned int i;
+@@ -10314,8 +10186,7 @@ ia_css_update_continuous_frames(struct i
+           IA_CSS_DEBUG_TRACE,
+           "sh_css_update_continuous_frames() enter:\n");
+-      if (!stream)
+-      {
++      if (!stream) {
+               ia_css_debug_dtrace(
+                   IA_CSS_DEBUG_TRACE,
+                   "sh_css_update_continuous_frames() leave: invalid stream, return_void\n");
+@@ -10326,10 +10197,9 @@ ia_css_update_continuous_frames(struct i
+       for (i = stream->config.init_num_cont_raw_buf;
+               i < stream->config.target_num_cont_raw_buf; i++)
+-      {
+               sh_css_update_host2sp_offline_frame(i,
+                                                   pipe->continuous_frames[i], pipe->cont_md_buffers[i]);
+-      }
++
+       sh_css_update_host2sp_cont_num_raw_frames
+       (stream->config.target_num_cont_raw_buf, true);
+       ia_css_debug_dtrace(
+@@ -10455,7 +10325,8 @@ void ia_css_pipe_map_queue(struct ia_css
+ #if CONFIG_ON_FRAME_ENQUEUE()
+ static int set_config_on_frame_enqueue(struct ia_css_frame_info
+-      *info, struct frame_data_wrapper *frame) {
++      *info, struct frame_data_wrapper *frame)
++{
+       frame->config_on_frame_enqueue.padded_width = 0;
+       /* currently we support configuration on frame enqueue only on YUV formats */
+@@ -10463,11 +10334,11 @@ static int set_config_on_frame_enqueue(s
+       switch (info->format) {
+       case IA_CSS_FRAME_FORMAT_YUV420:
+       case IA_CSS_FRAME_FORMAT_NV12:
+-              if (info->padded_width > info->res.width) {
++              if (info->padded_width > info->res.width)
+                       frame->config_on_frame_enqueue.padded_width = info->padded_width;
+-              } else if ((info->padded_width < info->res.width) && (info->padded_width > 0)) {
++              else if ((info->padded_width < info->res.width) && (info->padded_width > 0))
+                       return -EINVAL;
+-              }
++
+               /* nothing to do if width == padded width or padded width is zeroed (the same) */
+               break;
+       default:
+@@ -10479,22 +10350,21 @@ static int set_config_on_frame_enqueue(s
+ #endif
+ int
+-ia_css_unlock_raw_frame(struct ia_css_stream *stream, uint32_t exp_id) {
++ia_css_unlock_raw_frame(struct ia_css_stream *stream, uint32_t exp_id)
++{
+       int ret;
+       IA_CSS_ENTER("");
+       /* Only continuous streams have a tagger to which we can send the
+           * unlock message. */
+-      if (!stream || !stream->config.continuous)
+-      {
++      if (!stream || !stream->config.continuous) {
+               IA_CSS_ERROR("invalid stream pointer");
+               return -EINVAL;
+       }
+       if (exp_id > IA_CSS_ISYS_MAX_EXPOSURE_ID ||
+-          exp_id < IA_CSS_ISYS_MIN_EXPOSURE_ID)
+-      {
++          exp_id < IA_CSS_ISYS_MIN_EXPOSURE_ID) {
+               IA_CSS_ERROR("invalid exposure ID: %d\n", exp_id);
+               return -EINVAL;
+       }
+@@ -10513,7 +10383,8 @@ ia_css_unlock_raw_frame(struct ia_css_st
+     */
+ int
+ ia_css_pipe_set_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle,
+-                              bool enable) {
++                              bool enable)
++{
+       unsigned int thread_id;
+       struct ia_css_pipeline_stage *stage;
+       int err = 0;
+@@ -10521,20 +10392,16 @@ ia_css_pipe_set_qos_ext_state(struct ia_
+       IA_CSS_ENTER("");
+       /* Parameter Check */
+-      if (!pipe || !pipe->stream)
+-      {
++      if (!pipe || !pipe->stream) {
+               IA_CSS_ERROR("Invalid Pipe.");
+               err = -EINVAL;
+-      } else if (!(pipe->config.acc_extension))
+-      {
++      } else if (!(pipe->config.acc_extension)) {
+               IA_CSS_ERROR("Invalid Pipe(No Extension Firmware)");
+               err = -EINVAL;
+-      } else if (!sh_css_sp_is_running())
+-      {
++      } else if (!sh_css_sp_is_running()) {
+               IA_CSS_ERROR("Leaving: queue unavailable.");
+               err = -EBUSY;
+-      } else
+-      {
++      } else {
+               /* Query the threadid and stage_num for the Extension firmware*/
+               ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
+               err = ia_css_pipeline_get_stage_from_fw(&pipe->pipeline, fw_handle, &stage);
+@@ -10562,7 +10429,8 @@ ia_css_pipe_set_qos_ext_state(struct ia_
+     */
+ int
+ ia_css_pipe_get_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle,
+-                              bool *enable) {
++                              bool *enable)
++{
+       struct ia_css_pipeline_stage *stage;
+       unsigned int thread_id;
+       int err = 0;
+@@ -10570,20 +10438,16 @@ ia_css_pipe_get_qos_ext_state(struct ia_
+       IA_CSS_ENTER("");
+       /* Parameter Check */
+-      if (!pipe || !pipe->stream)
+-      {
++      if (!pipe || !pipe->stream) {
+               IA_CSS_ERROR("Invalid Pipe.");
+               err = -EINVAL;
+-      } else if (!(pipe->config.acc_extension))
+-      {
++      } else if (!(pipe->config.acc_extension)) {
+               IA_CSS_ERROR("Invalid Pipe (No Extension Firmware).");
+               err = -EINVAL;
+-      } else if (!sh_css_sp_is_running())
+-      {
++      } else if (!sh_css_sp_is_running()) {
+               IA_CSS_ERROR("Leaving: queue unavailable.");
+               err = -EBUSY;
+-      } else
+-      {
++      } else {
+               /* Query the threadid and stage_num corresponding to the Extension firmware*/
+               ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
+               err = ia_css_pipeline_get_stage_from_fw(&pipe->pipeline, fw_handle, &stage);
+@@ -10603,7 +10467,8 @@ int
+ ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe,
+                                       u32 fw_handle,
+                                       struct ia_css_isp_param_css_segments *css_seg,
+-                                      struct ia_css_isp_param_isp_segments *isp_seg) {
++                                      struct ia_css_isp_param_isp_segments *isp_seg)
++{
+       unsigned int HIVE_ADDR_sp_group;
+       static struct sh_css_sp_group sp_group;
+       static struct sh_css_sp_stage sp_stage;
+@@ -10621,20 +10486,16 @@ ia_css_pipe_update_qos_ext_mapped_arg(st
+       fw = &sh_css_sp_fw;
+       /* Parameter Check */
+-      if (!pipe || !pipe->stream)
+-      {
++      if (!pipe || !pipe->stream) {
+               IA_CSS_ERROR("Invalid Pipe.");
+               err = -EINVAL;
+-      } else if (!(pipe->config.acc_extension))
+-      {
++      } else if (!(pipe->config.acc_extension)) {
+               IA_CSS_ERROR("Invalid Pipe (No Extension Firmware).");
+               err = -EINVAL;
+-      } else if (!sh_css_sp_is_running())
+-      {
++      } else if (!sh_css_sp_is_running()) {
+               IA_CSS_ERROR("Leaving: queue unavailable.");
+               err = -EBUSY;
+-      } else
+-      {
++      } else {
+               /* Query the thread_id and stage_num corresponding to the Extension firmware */
+               ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
+               err = ia_css_pipeline_get_stage_from_fw(&pipe->pipeline, fw_handle, &stage);
+@@ -10685,7 +10546,8 @@ ia_css_pipe_update_qos_ext_mapped_arg(st
+ static int
+ aspect_ratio_crop_init(struct ia_css_stream *curr_stream,
+                       struct ia_css_pipe *pipes[],
+-                      bool *do_crop_status) {
++                      bool *do_crop_status)
++{
+       int err = 0;
+       int i;
+       struct ia_css_pipe *curr_pipe;
+@@ -10694,15 +10556,13 @@ aspect_ratio_crop_init(struct ia_css_str
+       if ((!curr_stream) ||
+           (curr_stream->num_pipes == 0) ||
+           (!pipes) ||
+-          (!do_crop_status))
+-      {
++          (!do_crop_status)) {
+               err = -EINVAL;
+               IA_CSS_LEAVE_ERR(err);
+               return err;
+       }
+-      for (i = 0; i < curr_stream->num_pipes; i++)
+-      {
++      for (i = 0; i < curr_stream->num_pipes; i++) {
+               curr_pipe = pipes[i];
+               pipe_mask |= (1 << curr_pipe->config.mode);
+       }
+@@ -10716,7 +10576,8 @@ aspect_ratio_crop_init(struct ia_css_str
+ }
+ static bool
+-aspect_ratio_crop_check(bool enabled, struct ia_css_pipe *curr_pipe) {
++aspect_ratio_crop_check(bool enabled, struct ia_css_pipe *curr_pipe)
++{
+       bool status = false;
+       if ((curr_pipe) && enabled) {
+@@ -10731,7 +10592,8 @@ aspect_ratio_crop_check(bool enabled, st
+ static int
+ aspect_ratio_crop(struct ia_css_pipe *curr_pipe,
+-                  struct ia_css_resolution *effective_res) {
++                  struct ia_css_resolution *effective_res)
++{
+       int err = 0;
+       struct ia_css_resolution crop_res;
+       struct ia_css_resolution *in_res = NULL;
+@@ -10741,8 +10603,7 @@ aspect_ratio_crop(struct ia_css_pipe *cu
+       bool use_capt_pp_in_res = false;
+       if ((!curr_pipe) ||
+-          (!effective_res))
+-      {
++          (!effective_res)) {
+               err = -EINVAL;
+               IA_CSS_LEAVE_ERR(err);
+               return err;
+@@ -10750,8 +10611,7 @@ aspect_ratio_crop(struct ia_css_pipe *cu
+       if ((curr_pipe->config.mode != IA_CSS_PIPE_MODE_PREVIEW) &&
+           (curr_pipe->config.mode != IA_CSS_PIPE_MODE_VIDEO) &&
+-          (curr_pipe->config.mode != IA_CSS_PIPE_MODE_CAPTURE))
+-      {
++          (curr_pipe->config.mode != IA_CSS_PIPE_MODE_CAPTURE)) {
+               err = -EINVAL;
+               IA_CSS_LEAVE_ERR(err);
+               return err;
+@@ -10772,8 +10632,7 @@ aspect_ratio_crop(struct ia_css_pipe *cu
+       in_res = &curr_pipe->stream->config.input_config.effective_res;
+       out_res = &curr_pipe->output_info[0].res;
+-      switch (curr_pipe->config.mode)
+-      {
++      switch (curr_pipe->config.mode) {
+       case IA_CSS_PIPE_MODE_PREVIEW:
+               if (use_bds_output_info)
+                       out_res = &curr_pipe->bds_output_info.res;
+@@ -10800,20 +10659,19 @@ aspect_ratio_crop(struct ia_css_pipe *cu
+       err = ia_css_frame_find_crop_resolution(in_res, out_res, &crop_res);
+       if (!err)
+-      {
+               *effective_res = crop_res;
+-      } else
+-      {
++      else
+               /* in case of error fallback to default
+                   * effective resolution from driver. */
+               IA_CSS_LOG("ia_css_frame_find_crop_resolution() failed with err(%d)", err);
+-      }
++
+       return err;
+ }
+ #endif
+ static void
+-sh_css_hmm_buffer_record_init(void) {
++sh_css_hmm_buffer_record_init(void)
++{
+       int i;
+       for (i = 0; i < MAX_HMM_BUFFER_NUM; i++)
+@@ -10821,7 +10679,8 @@ sh_css_hmm_buffer_record_init(void) {
+ }
+ static void
+-sh_css_hmm_buffer_record_uninit(void) {
++sh_css_hmm_buffer_record_uninit(void)
++{
+       int i;
+       struct sh_css_hmm_buffer_record *buffer_record = NULL;
+@@ -10837,7 +10696,8 @@ sh_css_hmm_buffer_record_uninit(void) {
+ }
+ static void
+-sh_css_hmm_buffer_record_reset(struct sh_css_hmm_buffer_record *buffer_record) {
++sh_css_hmm_buffer_record_reset(struct sh_css_hmm_buffer_record *buffer_record)
++{
+       assert(buffer_record);
+       buffer_record->in_use = false;
+       buffer_record->type = IA_CSS_BUFFER_TYPE_INVALID;
+@@ -10848,7 +10708,8 @@ sh_css_hmm_buffer_record_reset(struct sh
+ static struct sh_css_hmm_buffer_record
+ *sh_css_hmm_buffer_record_acquire(struct ia_css_rmgr_vbuf_handle *h_vbuf,
+                                   enum ia_css_buffer_type type,
+-                                  hrt_address kernel_ptr) {
++                                  hrt_address kernel_ptr)
++{
+       int i;
+       struct sh_css_hmm_buffer_record *buffer_record = NULL;
+       struct sh_css_hmm_buffer_record *out_buffer_record = NULL;
+@@ -10876,7 +10737,8 @@ static struct sh_css_hmm_buffer_record
+ static struct sh_css_hmm_buffer_record
+ *sh_css_hmm_buffer_record_validate(ia_css_ptr ddr_buffer_addr,
+-                                  enum ia_css_buffer_type type) {
++                                  enum ia_css_buffer_type type)
++{
+       int i;
+       struct sh_css_hmm_buffer_record *buffer_record = NULL;
+       bool found_record = false;
diff --git a/queue-5.10/media-staging-media-atomisp-replace-if-else-clause-with-a-ternary.patch b/queue-5.10/media-staging-media-atomisp-replace-if-else-clause-with-a-ternary.patch
new file mode 100644 (file)
index 0000000..1e61c08
--- /dev/null
@@ -0,0 +1,41 @@
+From stable+bounces-274528-greg=kroah.com@vger.kernel.org Tue Jul 14 22:02:18 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 16:01:56 -0400
+Subject: media: staging: media: atomisp: Replace if else clause with a ternary
+To: stable@vger.kernel.org
+Cc: Martiros Shakhzadyan <vrzh@vrzh.net>, Hans Verkuil <hverkuil-cisco@xs4all.nl>, Mauro Carvalho Chehab <mchehab+huawei@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714200158.3152137-4-sashal@kernel.org>
+
+From: Martiros Shakhzadyan <vrzh@vrzh.net>
+
+[ Upstream commit d4bc34d18201120b247506b4a6ed17af694dfcf7 ]
+
+Use the ternary operator for conditional variable assignment in
+create_host_video_pipeline().
+
+Signed-off-by: Martiros Shakhzadyan <vrzh@vrzh.net>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: f4d51e55dd47 ("staging: media: atomisp: reduce load_primary_binaries() stack usage")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/media/atomisp/pci/sh_css.c |    7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/drivers/staging/media/atomisp/pci/sh_css.c
++++ b/drivers/staging/media/atomisp/pci/sh_css.c
+@@ -3623,11 +3623,8 @@ static int create_host_video_pipeline(st
+               struct ia_css_frame *tmp_out_frame = NULL;
+               for (i = 0; i < num_yuv_scaler; i++) {
+-                      if (is_output_stage[i]) {
+-                              tmp_out_frame = out_frame;
+-                      } else {
+-                              tmp_out_frame = NULL;
+-                      }
++                      tmp_out_frame = is_output_stage[i] ? out_frame : NULL;
++
+                       err = add_yuv_scaler_stage(pipe, me, tmp_in_frame, tmp_out_frame,
+                                                  NULL,
+                                                  &yuv_scaler_binary[i],
diff --git a/queue-5.10/netfilter-ebtables-use-vmalloc_array-to-improve-code.patch b/queue-5.10/netfilter-ebtables-use-vmalloc_array-to-improve-code.patch
new file mode 100644 (file)
index 0000000..fad98f0
--- /dev/null
@@ -0,0 +1,77 @@
+From stable+bounces-275063-greg=kroah.com@vger.kernel.org Wed Jul 15 23:32:06 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 17:31:45 -0400
+Subject: netfilter: ebtables: Use vmalloc_array() to improve code
+To: stable@vger.kernel.org
+Cc: Qianfeng Rong <rongqianfeng@vivo.com>, Florian Westphal <fw@strlen.de>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260715213146.296837-1-sashal@kernel.org>
+
+From: Qianfeng Rong <rongqianfeng@vivo.com>
+
+[ Upstream commit 46015e6b3ea75297b28d4806564f3f692cf11861 ]
+
+Remove array_size() calls and replace vmalloc() with vmalloc_array() to
+simplify the code.  vmalloc_array() is also optimized better, uses fewer
+instructions, and handles overflow more concisely[1].
+
+[1]: https://lore.kernel.org/lkml/abc66ec5-85a4-47e1-9759-2f60ab111971@vivo.com/
+Signed-off-by: Qianfeng Rong <rongqianfeng@vivo.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Stable-dep-of: cbfe53599eeb ("netfilter: ebtables: zero chainstack array")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bridge/netfilter/ebtables.c |   14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -884,8 +884,8 @@ static int translate_table(struct net *n
+                * if an error occurs
+                */
+               newinfo->chainstack =
+-                      vmalloc(array_size(nr_cpu_ids,
+-                                         sizeof(*(newinfo->chainstack))));
++                      vmalloc_array(nr_cpu_ids,
++                                    sizeof(*(newinfo->chainstack)));
+               if (!newinfo->chainstack)
+                       return -ENOMEM;
+               for_each_possible_cpu(i) {
+@@ -900,7 +900,7 @@ static int translate_table(struct net *n
+                       }
+               }
+-              cl_s = vmalloc(array_size(udc_cnt, sizeof(*cl_s)));
++              cl_s = vmalloc_array(udc_cnt, sizeof(*cl_s));
+               if (!cl_s)
+                       return -ENOMEM;
+               i = 0; /* the i'th udc */
+@@ -980,8 +980,8 @@ static int do_replace_finish(struct net
+        * the check on the size is done later, when we have the lock
+        */
+       if (repl->num_counters) {
+-              unsigned long size = repl->num_counters * sizeof(*counterstmp);
+-              counterstmp = vmalloc(size);
++              counterstmp = vmalloc_array(repl->num_counters,
++                                          sizeof(*counterstmp));
+               if (!counterstmp)
+                       return -ENOMEM;
+       }
+@@ -1276,7 +1276,7 @@ static int do_update_counters(struct net
+       if (num_counters == 0)
+               return -EINVAL;
+-      tmp = vmalloc(array_size(num_counters, sizeof(*tmp)));
++      tmp = vmalloc_array(num_counters, sizeof(*tmp));
+       if (!tmp)
+               return -ENOMEM;
+@@ -1417,7 +1417,7 @@ static int copy_counters_to_user(struct
+       if (num_counters != nentries)
+               return -EINVAL;
+-      counterstmp = vmalloc(array_size(nentries, sizeof(*counterstmp)));
++      counterstmp = vmalloc_array(nentries, sizeof(*counterstmp));
+       if (!counterstmp)
+               return -ENOMEM;
diff --git a/queue-5.10/netfilter-ebtables-zero-chainstack-array.patch b/queue-5.10/netfilter-ebtables-zero-chainstack-array.patch
new file mode 100644 (file)
index 0000000..0b105fc
--- /dev/null
@@ -0,0 +1,46 @@
+From stable+bounces-275064-greg=kroah.com@vger.kernel.org Wed Jul 15 23:32:11 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 17:31:46 -0400
+Subject: netfilter: ebtables: zero chainstack array
+To: stable@vger.kernel.org
+Cc: Florian Westphal <fw@strlen.de>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260715213146.296837-2-sashal@kernel.org>
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit cbfe53599eebffd188938ab6774cc41794f6f9d5 ]
+
+sashiko reports:
+ looking at ebtables table
+ translation, could a sparse cpu_possible_mask lead to an uninitialized pointer
+ free?
+
+ If cpu_possible_mask is sparse (for example, CPU 0 and CPU 2 are possible,
+ but CPU 1 is not), the allocation loop skips CPU 1. If vmalloc_node() fails at
+ CPU 2, the cleanup loop will blindly decrement and call vfree() on
+ newinfo->chainstack[1].
+
+Not a real-world bug, such allocation isn't expected to fail
+in the first place.
+
+Cc: stable@vger.kernel.org
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bridge/netfilter/ebtables.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -884,8 +884,7 @@ static int translate_table(struct net *n
+                * if an error occurs
+                */
+               newinfo->chainstack =
+-                      vmalloc_array(nr_cpu_ids,
+-                                    sizeof(*(newinfo->chainstack)));
++                      vcalloc(nr_cpu_ids, sizeof(*(newinfo->chainstack)));
+               if (!newinfo->chainstack)
+                       return -ENOMEM;
+               for_each_possible_cpu(i) {
diff --git a/queue-5.10/pci-add-kerneldoc-for-pci_resize_resource.patch b/queue-5.10/pci-add-kerneldoc-for-pci_resize_resource.patch
new file mode 100644 (file)
index 0000000..3ddcee7
--- /dev/null
@@ -0,0 +1,55 @@
+From stable+bounces-274990-greg=kroah.com@vger.kernel.org Wed Jul 15 18:37:12 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 12:32:21 -0400
+Subject: PCI: Add kerneldoc for pci_resize_resource()
+To: stable@vger.kernel.org
+Cc: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>, "Bjorn Helgaas" <bhelgaas@google.com>, "Alex Bennée" <alex.bennee@linaro.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260715163223.952417-4-sashal@kernel.org>
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit d787018e2dfdc4c1331538e7a8717690d1b7c9b3 ]
+
+As pci_resize_resource() is meant to be used also outside of PCI core,
+document the interface with kerneldoc.
+
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Alex Bennée <alex.bennee@linaro.org> # AVA, AMD GPU
+Link: https://patch.msgid.link/20251113162628.5946-8-ilpo.jarvinen@linux.intel.com
+Stable-dep-of: ee7471fe968d ("PCI: Skip Resizable BAR restore on read error")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/setup-res.c |   20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+--- a/drivers/pci/setup-res.c
++++ b/drivers/pci/setup-res.c
+@@ -422,6 +422,26 @@ void pci_release_resource(struct pci_dev
+ }
+ EXPORT_SYMBOL(pci_release_resource);
++/**
++ * pci_resize_resource - reconfigure a Resizable BAR and resources
++ * @dev: the PCI device
++ * @resno: index of the BAR to be resized
++ * @size: new size as defined in the spec (0=1MB, 31=128TB)
++ * @exclude_bars: a mask of BARs that should not be released
++ *
++ * Reconfigure @resno to @size and re-run resource assignment algorithm
++ * with the new size.
++ *
++ * Prior to resize, release @dev resources that share a bridge window with
++ * @resno.  This unpins the bridge window resource to allow changing it.
++ *
++ * The caller may prevent releasing a particular BAR by providing
++ * @exclude_bars mask, but this may result in the resize operation failing
++ * due to insufficient space.
++ *
++ * Return: 0 on success, or negative on error. In case of an error, the
++ *         resources are restored to their original places.
++ */
+ int pci_resize_resource(struct pci_dev *dev, int resno, int size,
+                       int exclude_bars)
+ {
diff --git a/queue-5.10/pci-altera-fix-resource-leaks-on-probe-failure.patch b/queue-5.10/pci-altera-fix-resource-leaks-on-probe-failure.patch
new file mode 100644 (file)
index 0000000..6e9163f
--- /dev/null
@@ -0,0 +1,99 @@
+From stable+bounces-274492-greg=kroah.com@vger.kernel.org Tue Jul 14 19:50:57 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 13:49:16 -0400
+Subject: PCI: altera: Fix resource leaks on probe failure
+To: stable@vger.kernel.org
+Cc: Mahesh Vaidya <mahesh.vaidya@altera.com>, Manivannan Sadhasivam <mani@kernel.org>, "Subhransu S. Prusty" <subhransu.sekhar.prusty@altera.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714174916.3041625-1-sashal@kernel.org>
+
+From: Mahesh Vaidya <mahesh.vaidya@altera.com>
+
+[ Upstream commit 7a94138caeb27f3c49c1dbd93bf422098925bb28 ]
+
+The chained IRQ handler is set during probe, but is only removed during the
+driver remove(). If pci_host_probe() fails, the handler and INTx IRQ
+domain remain set even though the devm-managed host bridge storage
+containing struct altera_pcie will be released, leaving the handler with
+a stale data pointer.
+
+Interrupts are also enabled before pci_host_probe() is called. If probe
+fails after that point, the controller interrupt source should be disabled
+before the chained handler and INTx domain are removed.
+
+So set the chained handler only after the INTx domain has been created.
+Disable controller interrupts during IRQ teardown, and tear the IRQ setup
+down if pci_host_probe() fails.
+
+Fixes: c63aed7334c2 ("PCI: altera: Use pci_host_probe() to register host")
+Signed-off-by: Mahesh Vaidya <mahesh.vaidya@altera.com>
+[mani: commit log]
+Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
+Reviewed-by: Subhransu S. Prusty <subhransu.sekhar.prusty@altera.com>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260430204330.3121003-3-mahesh.vaidya@altera.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/pcie-altera.c |   28 ++++++++++++++++++++++++++--
+ 1 file changed, 26 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/controller/pcie-altera.c
++++ b/drivers/pci/controller/pcie-altera.c
+@@ -685,8 +685,18 @@ static int altera_pcie_init_irq_domain(s
+       return 0;
+ }
++static void altera_pcie_disable_irq(struct altera_pcie *pcie)
++{
++      if (pcie->pcie_data->version == ALTERA_PCIE_V1 ||
++          pcie->pcie_data->version == ALTERA_PCIE_V2) {
++              /* Disable all P2A interrupts */
++              cra_writel(pcie, 0, P2A_INT_ENABLE);
++      }
++}
++
+ static void altera_pcie_irq_teardown(struct altera_pcie *pcie)
+ {
++      altera_pcie_disable_irq(pcie);
+       irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);
+       irq_domain_remove(pcie->irq_domain);
+ }
+@@ -711,7 +721,6 @@ static int altera_pcie_parse_dt(struct a
+       if (pcie->irq < 0)
+               return pcie->irq;
+-      irq_set_chained_handler_and_data(pcie->irq, altera_pcie_isr, pcie);
+       return 0;
+ }
+@@ -796,6 +805,12 @@ static int altera_pcie_probe(struct plat
+               return ret;
+       }
++      /*
++       * The chained handler uses pcie->irq_domain, so set it only after the
++       * INTx domain has been created.
++       */
++      irq_set_chained_handler_and_data(pcie->irq, altera_pcie_isr, pcie);
++
+       /* clear all interrupts */
+       cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS);
+       /* enable all interrupts */
+@@ -806,7 +821,16 @@ static int altera_pcie_probe(struct plat
+       bridge->busnr = pcie->root_bus_nr;
+       bridge->ops = &altera_pcie_ops;
+-      return pci_host_probe(bridge);
++      ret = pci_host_probe(bridge);
++      if (ret)
++              goto err_teardown_irq;
++
++      return 0;
++
++err_teardown_irq:
++      altera_pcie_irq_teardown(pcie);
++
++      return ret;
+ }
+ static int altera_pcie_remove(struct platform_device *pdev)
diff --git a/queue-5.10/pci-controller-use-dev_fwnode-instead-of-of_fwnode_handle.patch b/queue-5.10/pci-controller-use-dev_fwnode-instead-of-of_fwnode_handle.patch
new file mode 100644 (file)
index 0000000..b1a84b0
--- /dev/null
@@ -0,0 +1,130 @@
+From stable+bounces-274659-greg=kroah.com@vger.kernel.org Wed Jul 15 03:23:01 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 21:22:53 -0400
+Subject: PCI: controller: Use dev_fwnode() instead of of_fwnode_handle()
+To: stable@vger.kernel.org
+Cc: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>, Arnd Bergmann <arnd@arndb.de>, Bjorn Helgaas <bhelgaas@google.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260715012255.4073217-1-sashal@kernel.org>
+
+From: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>
+
+[ Upstream commit a103d2dede5683dabbac2c3374bc24b6a9434478 ]
+
+All irq_domain functions now accept fwnode instead of of_node. But many
+PCI controllers still extract dev to of_node and then of_node to fwnode.
+
+Instead, clean this up and simply use the dev_fwnode() helper to extract
+fwnode directly from dev. Internally, it still does dev => of_node =>
+fwnode steps, but it's now hidden from the users.
+
+In the case of altera, this also removes an unused 'node' variable that is
+only used when CONFIG_OF is enabled:
+
+  drivers/pci/controller/pcie-altera.c: In function 'altera_pcie_init_irq_domain':
+  drivers/pci/controller/pcie-altera.c:855:29: error: unused variable 'node' [-Werror=unused-variable]
+    855 |         struct device_node *node = dev->of_node;
+
+Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>   # altera
+[bhelgaas: squash together, rebase to precede msi-parent]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Link: https://patch.msgid.link/20250521163329.2137973-1-arnd@kernel.org
+Link: https://patch.msgid.link/20250611104348.192092-16-jirislaby@kernel.org
+Link: https://patch.msgid.link/20250723065907.1841758-1-jirislaby@kernel.org
+Stable-dep-of: f865a57896bd ("PCI: mediatek: Fix IRQ domain leak when port fails to enable")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/dwc/pcie-designware-host.c    |    2 +-
+ drivers/pci/controller/mobiveil/pcie-mobiveil-host.c |    8 +++-----
+ drivers/pci/controller/pcie-altera-msi.c             |    2 +-
+ drivers/pci/controller/pcie-altera.c                 |    3 +--
+ drivers/pci/controller/pcie-mediatek.c               |    2 +-
+ drivers/pci/controller/pcie-xilinx-nwl.c             |    2 +-
+ 6 files changed, 8 insertions(+), 11 deletions(-)
+
+--- a/drivers/pci/controller/dwc/pcie-designware-host.c
++++ b/drivers/pci/controller/dwc/pcie-designware-host.c
+@@ -233,7 +233,7 @@ static const struct irq_domain_ops dw_pc
+ int dw_pcie_allocate_domains(struct pcie_port *pp)
+ {
+       struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+-      struct fwnode_handle *fwnode = of_node_to_fwnode(pci->dev->of_node);
++      struct fwnode_handle *fwnode = dev_fwnode(pci->dev);
+       pp->irq_domain = irq_domain_create_linear(fwnode, pp->num_vectors,
+                                              &dw_pcie_msi_domain_ops, pp);
+--- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
++++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
+@@ -452,7 +452,7 @@ static const struct irq_domain_ops msi_d
+ static int mobiveil_allocate_msi_domains(struct mobiveil_pcie *pcie)
+ {
+       struct device *dev = &pcie->pdev->dev;
+-      struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
++      struct fwnode_handle *fwnode = dev_fwnode(dev);
+       struct mobiveil_msi *msi = &pcie->rp.msi;
+       mutex_init(&msi->lock);
+@@ -478,13 +478,11 @@ static int mobiveil_allocate_msi_domains
+ static int mobiveil_pcie_init_irq_domain(struct mobiveil_pcie *pcie)
+ {
+       struct device *dev = &pcie->pdev->dev;
+-      struct device_node *node = dev->of_node;
+       struct mobiveil_root_port *rp = &pcie->rp;
+       /* setup INTx */
+-      rp->intx_domain = irq_domain_add_linear(node, PCI_NUM_INTX,
+-                                              &intx_domain_ops, pcie);
+-
++      rp->intx_domain = irq_domain_create_linear(dev_fwnode(dev), PCI_NUM_INTX, &intx_domain_ops,
++                                                 pcie);
+       if (!rp->intx_domain) {
+               dev_err(dev, "Failed to get a INTx IRQ domain\n");
+               return -ENOMEM;
+--- a/drivers/pci/controller/pcie-altera-msi.c
++++ b/drivers/pci/controller/pcie-altera-msi.c
+@@ -173,7 +173,7 @@ static const struct irq_domain_ops msi_d
+ static int altera_allocate_domains(struct altera_msi *msi)
+ {
+-      struct fwnode_handle *fwnode = of_node_to_fwnode(msi->pdev->dev.of_node);
++      struct fwnode_handle *fwnode = dev_fwnode(&msi->pdev->dev);
+       msi->inner_domain = irq_domain_add_linear(NULL, msi->num_of_vectors,
+                                            &msi_domain_ops, msi);
+--- a/drivers/pci/controller/pcie-altera.c
++++ b/drivers/pci/controller/pcie-altera.c
+@@ -672,10 +672,9 @@ static void altera_pcie_isr(struct irq_d
+ static int altera_pcie_init_irq_domain(struct altera_pcie *pcie)
+ {
+       struct device *dev = &pcie->pdev->dev;
+-      struct device_node *node = dev->of_node;
+       /* Setup INTx */
+-      pcie->irq_domain = irq_domain_add_linear(node, PCI_NUM_INTX,
++      pcie->irq_domain = irq_domain_create_linear(dev_fwnode(dev), PCI_NUM_INTX,
+                                       &intx_domain_ops, pcie);
+       if (!pcie->irq_domain) {
+               dev_err(dev, "Failed to get a INTx IRQ domain\n");
+--- a/drivers/pci/controller/pcie-mediatek.c
++++ b/drivers/pci/controller/pcie-mediatek.c
+@@ -497,7 +497,7 @@ static struct msi_domain_info mtk_msi_do
+ static int mtk_pcie_allocate_msi_domains(struct mtk_pcie_port *port)
+ {
+-      struct fwnode_handle *fwnode = of_node_to_fwnode(port->pcie->dev->of_node);
++      struct fwnode_handle *fwnode = dev_fwnode(port->pcie->dev);
+       mutex_init(&port->lock);
+--- a/drivers/pci/controller/pcie-xilinx-nwl.c
++++ b/drivers/pci/controller/pcie-xilinx-nwl.c
+@@ -515,7 +515,7 @@ static int nwl_pcie_init_msi_irq_domain(
+ {
+ #ifdef CONFIG_PCI_MSI
+       struct device *dev = pcie->dev;
+-      struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
++      struct fwnode_handle *fwnode = dev_fwnode(dev);
+       struct nwl_msi *msi = &pcie->msi;
+       msi->dev_domain = irq_domain_add_linear(NULL, INT_PCI_MSI_NR,
diff --git a/queue-5.10/pci-fix-restoring-bars-on-bar-resize-rollback-path.patch b/queue-5.10/pci-fix-restoring-bars-on-bar-resize-rollback-path.patch
new file mode 100644 (file)
index 0000000..daeae6f
--- /dev/null
@@ -0,0 +1,335 @@
+From stable+bounces-274989-greg=kroah.com@vger.kernel.org Wed Jul 15 18:37:09 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 12:32:20 -0400
+Subject: PCI: Fix restoring BARs on BAR resize rollback path
+To: stable@vger.kernel.org
+Cc: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>, "Simon Richter" <Simon.Richter@hogyros.de>, "Alex Bennée" <alex.bennee@linaro.org>, "Bjorn Helgaas" <bhelgaas@google.com>, "Christian König" <christian.koenig@amd.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260715163223.952417-3-sashal@kernel.org>
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 337b1b566db087347194e4543ddfdfa5645275cc ]
+
+BAR resize operation is implemented in the pci_resize_resource() and
+pbus_reassign_bridge_resources() functions. pci_resize_resource() can be
+called either from __resource_resize_store() from sysfs or directly by the
+driver for the Endpoint Device.
+
+The pci_resize_resource() requires that caller has released the device
+resources that share the bridge window with the BAR to be resized as
+otherwise the bridge window is pinned in place and cannot be changed.
+
+pbus_reassign_bridge_resources() rolls back resources if the resize
+operation fails, but rollback is performed only for the bridge windows.
+Because releasing the device resources are done by the caller of the BAR
+resize interface, these functions performing the BAR resize do not have
+access to the device resources as they were before the resize.
+
+pbus_reassign_bridge_resources() could try __pci_bridge_assign_resources()
+after rolling back the bridge windows as they were, however, it will not
+guarantee the resource are assigned due to differences in how FW and the
+kernel assign the resources (alignment of the start address and tail).
+
+To perform rollback robustly, the BAR resize interface has to be altered to
+also release the device resources that share the bridge window with the BAR
+to be resized.
+
+Also, remove restoring from the entries failed list as saved list should
+now contain both the bridge windows and device resources so the extra
+restore is duplicated work.
+
+Some drivers (currently only amdgpu) want to prevent releasing some
+resources. Add exclude_bars param to pci_resize_resource() and make amdgpu
+pass its register BAR (BAR 2 or 5), which should never be released during
+resize operation. Normally 64-bit prefetchable resources do not share a
+bridge window with the 32-bit only register BAR, but there are various
+fallbacks in the resource assignment logic which may make the resources
+share the bridge window in rare cases.
+
+This change (together with the driver side changes) is to counter the
+resource releases that had to be done to prevent resource tree corruption
+in the ("PCI: Release assigned resource before restoring them") change. As
+such, it likely restores functionality in cases where device resources were
+released to avoid resource tree conflicts which appeared to be "working"
+when such conflicts were not correctly detected by the kernel.
+
+Reported-by: Simon Richter <Simon.Richter@hogyros.de>
+Link: https://lore.kernel.org/linux-pci/f9a8c975-f5d3-4dd2-988e-4371a1433a60@hogyros.de/
+Reported-by: Alex Bennée <alex.bennee@linaro.org>
+Link: https://lore.kernel.org/linux-pci/874irqop6b.fsf@draig.linaro.org/
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+[bhelgaas: squash amdgpu BAR selection from
+https: //lore.kernel.org/r/20251114103053.13778-1-ilpo.jarvinen@linux.intel.com]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Alex Bennée <alex.bennee@linaro.org> # AVA, AMD GPU
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Link: https://patch.msgid.link/20251113162628.5946-7-ilpo.jarvinen@linux.intel.com
+Stable-dep-of: ee7471fe968d ("PCI: Skip Resizable BAR restore on read error")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |    4 -
+ drivers/pci/pci.h                          |    3 
+ drivers/pci/setup-bus.c                    |   97 +++++++++++++++++++----------
+ drivers/pci/setup-res.c                    |   19 +----
+ include/linux/pci.h                        |    4 -
+ 5 files changed, 79 insertions(+), 48 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -1141,7 +1141,9 @@ int amdgpu_device_resize_fb_bar(struct a
+       pci_release_resource(adev->pdev, 0);
+-      r = pci_resize_resource(adev->pdev, 0, rbar_size);
++      r = pci_resize_resource(adev->pdev, 0, rbar_size,
++                              (adev->asic_type >= CHIP_BONAIRE) ? 1 << 5
++                                                                : 1 << 2);
+       if (r == -ENOSPC)
+               DRM_INFO("Not enough PCI address space for a large BAR.");
+       else if (r && r != -ENOTSUPP)
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -284,6 +284,9 @@ enum pci_bar_type {
+ struct device *pci_get_host_bridge_device(struct pci_dev *dev);
+ void pci_put_host_bridge_device(struct device *dev);
++int pci_do_resource_release_and_resize(struct pci_dev *dev, int resno, int size,
++                                     int exclude_bars);
++
+ int pci_configure_extended_tags(struct pci_dev *dev, void *ign);
+ bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl,
+                               int crs_timeout);
+--- a/drivers/pci/setup-bus.c
++++ b/drivers/pci/setup-bus.c
+@@ -2166,18 +2166,16 @@ enable_all:
+ }
+ EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);
+-int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type)
++static int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type,
++                                       struct list_head *saved)
+ {
+       struct pci_dev_resource *dev_res;
+       struct pci_dev *next;
+-      LIST_HEAD(saved);
+       LIST_HEAD(added);
+       LIST_HEAD(failed);
+       unsigned int i;
+       int ret;
+-      down_read(&pci_bus_sem);
+-
+       /* Walk to the root hub, releasing bridge BARs when possible */
+       next = bridge;
+       do {
+@@ -2193,9 +2191,9 @@ int pci_reassign_bridge_resources(struct
+                       if (res->child)
+                               continue;
+-                      ret = add_to_list(&saved, bridge, res, 0, 0);
++                      ret = add_to_list(saved, bridge, res, 0, 0);
+                       if (ret)
+-                              goto cleanup;
++                              return ret;
+                       pci_info(bridge, "BAR %d: releasing %pR\n",
+                                i, res);
+@@ -2212,67 +2210,104 @@ int pci_reassign_bridge_resources(struct
+               next = bridge->bus ? bridge->bus->self : NULL;
+       } while (next);
+-      if (list_empty(&saved)) {
+-              up_read(&pci_bus_sem);
++      if (list_empty(saved))
+               return -ENOENT;
+-      }
+       __pci_bus_size_bridges(bridge->subordinate, &added);
+       __pci_bridge_assign_resources(bridge, &added, &failed);
+       BUG_ON(!list_empty(&added));
+       if (!list_empty(&failed)) {
+-              ret = -ENOSPC;
+-              goto cleanup;
++              free_list(&failed);
++              return -ENOSPC;
+       }
+-      list_for_each_entry(dev_res, &saved, list) {
++      list_for_each_entry(dev_res, saved, list) {
+               /* Skip the bridge we just assigned resources for */
+               if (bridge == dev_res->dev)
+                       continue;
++              if (!dev_res->dev->subordinate)
++                      continue;
++
+               bridge = dev_res->dev;
+               pci_setup_bridge(bridge->subordinate);
+       }
+-      free_list(&saved);
+-      up_read(&pci_bus_sem);
+       return 0;
++}
+-cleanup:
+-      /* Restore size and flags */
+-      list_for_each_entry(dev_res, &failed, list) {
+-              struct resource *res = dev_res->res;
++int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size,
++                                     int exclude_bars)
++{
++      struct resource *res = pdev->resource + resno;
++      unsigned long flags = res->flags;
++      struct pci_dev_resource *dev_res;
++      struct pci_bus *bus = pdev->bus;
++      LIST_HEAD(saved);
++      unsigned int i;
++      int ret = 0;
+-              res->start = dev_res->start;
+-              res->end = dev_res->end;
+-              res->flags = dev_res->flags;
++      down_read(&pci_bus_sem);
++
++      for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) {
++              struct resource *r = &pdev->resource[i];
++
++              if (exclude_bars & BIT(i))
++                      continue;
++
++              if (!pci_resource_len(pdev, i) || r->flags != flags)
++                      continue;
++
++              ret = add_to_list(&saved, pdev, r, 0, 0);
++              if (ret)
++                      goto restore;
++              pci_release_resource(pdev, i);
+       }
+-      free_list(&failed);
++      res->end = res->start + pci_rebar_size_to_bytes(size) - 1;
++
++      if (!bus->self)
++              goto out;
++
++      ret = pci_reassign_bridge_resources(bus->self, res->flags, &saved);
++      if (ret)
++              goto restore;
++
++out:
++      up_read(&pci_bus_sem);
++      free_list(&saved);
++      return ret;
++
++restore:
+       /* Revert to the old configuration */
+       list_for_each_entry(dev_res, &saved, list) {
+               struct resource *res = dev_res->res;
++              struct pci_dev *dev = dev_res->dev;
+-              bridge = dev_res->dev;
+-              i = res - bridge->resource;
++              i = res - dev->resource;
+               if (res->parent) {
+                       release_child_resources(res);
+-                      pci_release_resource(bridge, i);
++                      pci_release_resource(dev, i);
+               }
+               res->start = dev_res->start;
+               res->end = dev_res->end;
+               res->flags = dev_res->flags;
+-              pci_claim_resource(bridge, i);
+-              pci_setup_bridge(bridge->subordinate);
+-      }
+-      up_read(&pci_bus_sem);
+-      free_list(&saved);
++              if (pci_claim_resource(dev, i))
++                      continue;
+-      return ret;
++              if (i < PCI_BRIDGE_RESOURCES) {
++                      pci_update_resource(dev, i);
++                      pci_info(dev, "BAR %d: old value restored %pR\n",
++                               i, res);
++              }
++              if (dev->subordinate)
++                      pci_setup_bridge(dev->subordinate);
++      }
++      goto out;
+ }
+ void pci_assign_unassigned_bus_resources(struct pci_bus *bus)
+--- a/drivers/pci/setup-res.c
++++ b/drivers/pci/setup-res.c
+@@ -422,9 +422,9 @@ void pci_release_resource(struct pci_dev
+ }
+ EXPORT_SYMBOL(pci_release_resource);
+-int pci_resize_resource(struct pci_dev *dev, int resno, int size)
++int pci_resize_resource(struct pci_dev *dev, int resno, int size,
++                      int exclude_bars)
+ {
+-      struct resource *res = dev->resource + resno;
+       struct pci_host_bridge *host;
+       int old, ret;
+       u32 sizes;
+@@ -435,10 +435,6 @@ int pci_resize_resource(struct pci_dev *
+       if (host->preserve_config)
+               return -ENOTSUPP;
+-      /* Make sure the resource isn't assigned before resizing it. */
+-      if (!(res->flags & IORESOURCE_UNSET))
+-              return -EBUSY;
+-
+       pci_read_config_word(dev, PCI_COMMAND, &cmd);
+       if (cmd & PCI_COMMAND_MEMORY)
+               return -EBUSY;
+@@ -458,19 +454,14 @@ int pci_resize_resource(struct pci_dev *
+       if (ret)
+               return ret;
+-      res->end = res->start + pci_rebar_size_to_bytes(size) - 1;
++      ret = pci_do_resource_release_and_resize(dev, resno, size, exclude_bars);
++      if (ret)
++              goto error_resize;
+-      /* Check if the new config works by trying to assign everything. */
+-      if (dev->bus->self) {
+-              ret = pci_reassign_bridge_resources(dev->bus->self, res->flags);
+-              if (ret)
+-                      goto error_resize;
+-      }
+       return 0;
+ error_resize:
+       pci_rebar_set_size(dev, resno, old);
+-      res->end = res->start + pci_rebar_size_to_bytes(old) - 1;
+       return ret;
+ }
+ EXPORT_SYMBOL(pci_resize_resource);
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -1257,7 +1257,8 @@ void pci_update_resource(struct pci_dev
+ int __must_check pci_assign_resource(struct pci_dev *dev, int i);
+ int __must_check pci_reassign_resource(struct pci_dev *dev, int i, resource_size_t add_size, resource_size_t align);
+ void pci_release_resource(struct pci_dev *dev, int resno);
+-int __must_check pci_resize_resource(struct pci_dev *dev, int i, int size);
++int __must_check pci_resize_resource(struct pci_dev *dev, int i, int size,
++                                   int exclude_bars);
+ int pci_select_bars(struct pci_dev *dev, unsigned long flags);
+ bool pci_device_is_present(struct pci_dev *pdev);
+ void pci_ignore_hotplug(struct pci_dev *dev);
+@@ -1332,7 +1333,6 @@ void pci_assign_unassigned_resources(voi
+ void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge);
+ void pci_assign_unassigned_bus_resources(struct pci_bus *bus);
+ void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus);
+-int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type);
+ void pdev_enable_device(struct pci_dev *);
+ int pci_enable_resources(struct pci_dev *, int mask);
+ void pci_assign_irq(struct pci_dev *dev);
diff --git a/queue-5.10/pci-free-saved-list-without-holding-pci_bus_sem.patch b/queue-5.10/pci-free-saved-list-without-holding-pci_bus_sem.patch
new file mode 100644 (file)
index 0000000..a0ae8ee
--- /dev/null
@@ -0,0 +1,38 @@
+From stable+bounces-274988-greg=kroah.com@vger.kernel.org Wed Jul 15 18:32:33 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 12:32:19 -0400
+Subject: PCI: Free saved list without holding pci_bus_sem
+To: stable@vger.kernel.org
+Cc: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>, "Bjorn Helgaas" <bhelgaas@google.com>, "Alex Bennée" <alex.bennee@linaro.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260715163223.952417-2-sashal@kernel.org>
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 1d8a0506f69895b7cfd9d5c4546761c508231a8a ]
+
+Freeing the saved list does not require holding pci_bus_sem, so the
+critical section can be made shorter.
+
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Alex Bennée <alex.bennee@linaro.org> # AVA, AMD GPU
+Link: https://patch.msgid.link/20251113162628.5946-6-ilpo.jarvinen@linux.intel.com
+Stable-dep-of: ee7471fe968d ("PCI: Skip Resizable BAR restore on read error")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/setup-bus.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/pci/setup-bus.c
++++ b/drivers/pci/setup-bus.c
+@@ -2269,8 +2269,8 @@ cleanup:
+               pci_claim_resource(bridge, i);
+               pci_setup_bridge(bridge->subordinate);
+       }
+-      free_list(&saved);
+       up_read(&pci_bus_sem);
++      free_list(&saved);
+       return ret;
+ }
diff --git a/queue-5.10/pci-imx6-fix-imx6sx_gpr12_pcie_test_powerdown-handling.patch b/queue-5.10/pci-imx6-fix-imx6sx_gpr12_pcie_test_powerdown-handling.patch
new file mode 100644 (file)
index 0000000..658fe13
--- /dev/null
@@ -0,0 +1,55 @@
+From stable+bounces-274572-greg=kroah.com@vger.kernel.org Wed Jul 15 00:04:21 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 18:04:08 -0400
+Subject: PCI: imx6: Fix IMX6SX_GPR12_PCIE_TEST_POWERDOWN handling
+To: stable@vger.kernel.org
+Cc: Richard Zhu <hongxing.zhu@nxp.com>, Manivannan Sadhasivam <mani@kernel.org>, Bjorn Helgaas <bhelgaas@google.com>, Frank Li <Frank.Li@nxp.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714220408.3333635-1-sashal@kernel.org>
+
+From: Richard Zhu <hongxing.zhu@nxp.com>
+
+[ Upstream commit aad953fb4eed0df5486cd54ccad80ac197678e01 ]
+
+The IMX6SX_GPR12_PCIE_TEST_POWERDOWN bit does not control the PCIe
+reference clock on i.MX6SX. Instead, it is part of i.MX6SX PCIe core
+reset sequence.
+
+Move the IMX6SX_GPR12_PCIE_TEST_POWERDOWN assertion/deassertion into
+the core reset functions to properly reflect its purpose. Remove the
+.enable_ref_clk() callback for i.MX6SX since it was incorrectly
+manipulating this bit.
+
+Fixes: e3c06cd063d6 ("PCI: imx6: Add initial imx6sx support")
+Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
+Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260319090844.444987-1-hongxing.zhu@nxp.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/dwc/pci-imx6.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/pci/controller/dwc/pci-imx6.c
++++ b/drivers/pci/controller/dwc/pci-imx6.c
+@@ -428,9 +428,6 @@ static int imx6_pcie_enable_ref_clk(stru
+                       dev_err(dev, "unable to enable pcie_axi clock\n");
+                       break;
+               }
+-
+-              regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+-                                 IMX6SX_GPR12_PCIE_TEST_POWERDOWN, 0);
+               break;
+       case IMX6QP:
+       case IMX6Q:
+@@ -557,6 +554,8 @@ static void imx6_pcie_deassert_core_rese
+               imx7d_pcie_wait_for_phy_pll_lock(imx6_pcie);
+               break;
+       case IMX6SX:
++              regmap_clear_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
++                                IMX6SX_GPR12_PCIE_TEST_POWERDOWN);
+               regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5,
+                                  IMX6SX_GPR5_PCIE_BTNRST_RESET, 0);
+               break;
diff --git a/queue-5.10/pci-mediatek-convert-bool-to-single-quirks-entry-and-bitmap.patch b/queue-5.10/pci-mediatek-convert-bool-to-single-quirks-entry-and-bitmap.patch
new file mode 100644 (file)
index 0000000..8268d37
--- /dev/null
@@ -0,0 +1,103 @@
+From stable+bounces-274660-greg=kroah.com@vger.kernel.org Wed Jul 15 03:23:31 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 21:22:54 -0400
+Subject: PCI: mediatek: Convert bool to single quirks entry and bitmap
+To: stable@vger.kernel.org
+Cc: Christian Marangi <ansuelsmth@gmail.com>, Manivannan Sadhasivam <mani@kernel.org>, AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260715012255.4073217-2-sashal@kernel.org>
+
+From: Christian Marangi <ansuelsmth@gmail.com>
+
+[ Upstream commit 04305367fab7ec9c98eeba315ad09c8b20abce93 ]
+
+To clean Mediatek SoC PCIe struct, convert all the bool to a bitmap and
+use a single quirks to reference all the values. This permits cleaner
+addition of new quirk without having to define a new bool in the struct.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patch.msgid.link/20251020111121.31779-4-ansuelsmth@gmail.com
+Stable-dep-of: f865a57896bd ("PCI: mediatek: Fix IRQ domain leak when port fails to enable")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/pcie-mediatek.c |   25 ++++++++++++++++---------
+ 1 file changed, 16 insertions(+), 9 deletions(-)
+
+--- a/drivers/pci/controller/pcie-mediatek.c
++++ b/drivers/pci/controller/pcie-mediatek.c
+@@ -141,21 +141,29 @@
+ struct mtk_pcie_port;
+ /**
++ * enum mtk_pcie_quirks - MTK PCIe quirks
++ * @MTK_PCIE_FIX_CLASS_ID: host's class ID needed to be fixed
++ * @MTK_PCIE_FIX_DEVICE_ID: host's device ID needed to be fixed
++ */
++enum mtk_pcie_quirks {
++      MTK_PCIE_FIX_CLASS_ID = BIT(0),
++      MTK_PCIE_FIX_DEVICE_ID = BIT(1),
++};
++
++/**
+  * struct mtk_pcie_soc - differentiate between host generations
+- * @need_fix_class_id: whether this host's class ID needed to be fixed or not
+- * @need_fix_device_id: whether this host's device ID needed to be fixed or not
+  * @device_id: device ID which this host need to be fixed
+  * @ops: pointer to configuration access functions
+  * @startup: pointer to controller setting functions
+  * @setup_irq: pointer to initialize IRQ functions
++ * @quirks: PCIe device quirks.
+  */
+ struct mtk_pcie_soc {
+-      bool need_fix_class_id;
+-      bool need_fix_device_id;
+       unsigned int device_id;
+       struct pci_ops *ops;
+       int (*startup)(struct mtk_pcie_port *port);
+       int (*setup_irq)(struct mtk_pcie_port *port, struct device_node *node);
++      enum mtk_pcie_quirks quirks;
+ };
+ /**
+@@ -710,7 +718,7 @@ static int mtk_pcie_startup_port_v2(stru
+       writel(val, port->base + PCIE_RST_CTRL);
+       /* Set up vendor ID and class code */
+-      if (soc->need_fix_class_id) {
++      if (soc->quirks & MTK_PCIE_FIX_CLASS_ID) {
+               val = PCI_VENDOR_ID_MEDIATEK;
+               writew(val, port->base + PCIE_CONF_VEND_ID);
+@@ -718,7 +726,7 @@ static int mtk_pcie_startup_port_v2(stru
+               writew(val, port->base + PCIE_CONF_CLASS_ID);
+       }
+-      if (soc->need_fix_device_id)
++      if (soc->quirks & MTK_PCIE_FIX_DEVICE_ID)
+               writew(soc->device_id, port->base + PCIE_CONF_DEVICE_ID);
+       /* 100ms timeout value should be enough for Gen1/2 training */
+@@ -1206,19 +1214,18 @@ static const struct mtk_pcie_soc mtk_pci
+ };
+ static const struct mtk_pcie_soc mtk_pcie_soc_mt7622 = {
+-      .need_fix_class_id = true,
+       .ops = &mtk_pcie_ops_v2,
+       .startup = mtk_pcie_startup_port_v2,
+       .setup_irq = mtk_pcie_setup_irq,
++      .quirks = MTK_PCIE_FIX_CLASS_ID,
+ };
+ static const struct mtk_pcie_soc mtk_pcie_soc_mt7629 = {
+-      .need_fix_class_id = true,
+-      .need_fix_device_id = true,
+       .device_id = PCI_DEVICE_ID_MEDIATEK_7629,
+       .ops = &mtk_pcie_ops_v2,
+       .startup = mtk_pcie_startup_port_v2,
+       .setup_irq = mtk_pcie_setup_irq,
++      .quirks = MTK_PCIE_FIX_CLASS_ID | MTK_PCIE_FIX_DEVICE_ID,
+ };
+ static const struct of_device_id mtk_pcie_ids[] = {
diff --git a/queue-5.10/pci-mediatek-fix-irq-domain-leak-when-port-fails-to-enable.patch b/queue-5.10/pci-mediatek-fix-irq-domain-leak-when-port-fails-to-enable.patch
new file mode 100644 (file)
index 0000000..efd9848
--- /dev/null
@@ -0,0 +1,170 @@
+From stable+bounces-274661-greg=kroah.com@vger.kernel.org Wed Jul 15 03:23:35 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 21:22:55 -0400
+Subject: PCI: mediatek: Fix IRQ domain leak when port fails to enable
+To: stable@vger.kernel.org
+Cc: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>, Manivannan Sadhasivam <mani@kernel.org>, Caleb James DeLisle <cjd@cjdns.fr>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260715012255.4073217-3-sashal@kernel.org>
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
+
+[ Upstream commit f865a57896bd92d7662eb2818d8f48872e2cbbc7 ]
+
+When mtk_pcie_enable_port() fails, mtk_pcie_port_free() removes the port
+from pcie->ports and frees the port structure. However, the IRQ domains set
+up earlier by mtk_pcie_init_irq_domain() are never freed.
+
+Fix this by refactoring mtk_pcie_irq_teardown() into a per-port helper,
+mtk_pcie_irq_teardown_port(), and calling it from mtk_pcie_setup() when
+mtk_pcie_enable_port() fails. Since the IRQ teardown must only happen in
+the probe error path (during resume, child devices may have active MSI
+mappings and the NOIRQ context prohibits sleeping locks),
+mtk_pcie_enable_port() is changed to return an error code so callers can
+distinguish the two paths and act accordingly.
+
+This issue was reported by Sashiko while reviewing the EcoNet EN7528 SoC
+support series.
+
+Fixes: b099631df160 ("PCI: mediatek: Add controller support for MT2712 and MT7622")
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
+Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
+Cc: stable@vger.kernel.org # 5.10
+Cc: Caleb James DeLisle <cjd@cjdns.fr>
+Link: https://patch.msgid.link/20260521174617.17692-1-mani@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/pcie-mediatek.c |   67 ++++++++++++++++++++-------------
+ 1 file changed, 42 insertions(+), 25 deletions(-)
+
+--- a/drivers/pci/controller/pcie-mediatek.c
++++ b/drivers/pci/controller/pcie-mediatek.c
+@@ -541,25 +541,29 @@ static void mtk_pcie_enable_msi(struct m
+       writel(val, port->base + PCIE_INT_MASK);
+ }
+-static void mtk_pcie_irq_teardown(struct mtk_pcie *pcie)
++static void mtk_pcie_irq_teardown_port(struct mtk_pcie_port *port)
+ {
+-      struct mtk_pcie_port *port, *tmp;
++      irq_set_chained_handler_and_data(port->irq, NULL, NULL);
+-      list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
+-              irq_set_chained_handler_and_data(port->irq, NULL, NULL);
++      if (port->irq_domain)
++              irq_domain_remove(port->irq_domain);
+-              if (port->irq_domain)
+-                      irq_domain_remove(port->irq_domain);
++      if (IS_ENABLED(CONFIG_PCI_MSI)) {
++              if (port->msi_domain)
++                      irq_domain_remove(port->msi_domain);
++              if (port->inner_domain)
++                      irq_domain_remove(port->inner_domain);
++      }
+-              if (IS_ENABLED(CONFIG_PCI_MSI)) {
+-                      if (port->msi_domain)
+-                              irq_domain_remove(port->msi_domain);
+-                      if (port->inner_domain)
+-                              irq_domain_remove(port->inner_domain);
+-              }
++      irq_dispose_mapping(port->irq);
++}
+-              irq_dispose_mapping(port->irq);
+-      }
++static void mtk_pcie_irq_teardown(struct mtk_pcie *pcie)
++{
++      struct mtk_pcie_port *port, *tmp;
++
++      list_for_each_entry_safe(port, tmp, &pcie->ports, list)
++              mtk_pcie_irq_teardown_port(port);
+ }
+ static int mtk_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
+@@ -836,7 +840,7 @@ static int mtk_pcie_startup_port(struct
+       return 0;
+ }
+-static void mtk_pcie_enable_port(struct mtk_pcie_port *port)
++static int mtk_pcie_enable_port(struct mtk_pcie_port *port)
+ {
+       struct mtk_pcie *pcie = port->pcie;
+       struct device *dev = pcie->dev;
+@@ -845,7 +849,7 @@ static void mtk_pcie_enable_port(struct
+       err = clk_prepare_enable(port->sys_ck);
+       if (err) {
+               dev_err(dev, "failed to enable sys_ck%d clock\n", port->slot);
+-              goto err_sys_clk;
++              return err;
+       }
+       err = clk_prepare_enable(port->ahb_ck);
+@@ -893,11 +897,15 @@ static void mtk_pcie_enable_port(struct
+               goto err_phy_on;
+       }
+-      if (!pcie->soc->startup(port))
+-              return;
++      err = pcie->soc->startup(port);
++      if (err) {
++              dev_info(dev, "Port%d link down\n", port->slot);
++              goto err_soc_startup;
++      }
+-      dev_info(dev, "Port%d link down\n", port->slot);
++      return 0;
++err_soc_startup:
+       phy_power_off(port->phy);
+ err_phy_on:
+       phy_exit(port->phy);
+@@ -913,8 +921,8 @@ err_aux_clk:
+       clk_disable_unprepare(port->ahb_ck);
+ err_ahb_clk:
+       clk_disable_unprepare(port->sys_ck);
+-err_sys_clk:
+-      mtk_pcie_port_free(port);
++
++      return err;
+ }
+ static int mtk_pcie_parse_port(struct mtk_pcie *pcie,
+@@ -1077,8 +1085,13 @@ static int mtk_pcie_setup(struct mtk_pci
+               return err;
+       /* enable each port, and then check link status */
+-      list_for_each_entry_safe(port, tmp, &pcie->ports, list)
+-              mtk_pcie_enable_port(port);
++      list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
++              err = mtk_pcie_enable_port(port);
++              if (err) {
++                      mtk_pcie_irq_teardown_port(port);
++                      mtk_pcie_port_free(port);
++              }
++      }
+       /* power down PCIe subsys if slots are all empty (link down) */
+       if (list_empty(&pcie->ports))
+@@ -1181,14 +1194,18 @@ static int __maybe_unused mtk_pcie_resum
+ {
+       struct mtk_pcie *pcie = dev_get_drvdata(dev);
+       struct mtk_pcie_port *port, *tmp;
++      int err;
+       if (list_empty(&pcie->ports))
+               return 0;
+       clk_prepare_enable(pcie->free_ck);
+-      list_for_each_entry_safe(port, tmp, &pcie->ports, list)
+-              mtk_pcie_enable_port(port);
++      list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
++              err = mtk_pcie_enable_port(port);
++              if (err)
++                      mtk_pcie_port_free(port);
++      }
+       /* In case of EP was removed while system suspend. */
+       if (list_empty(&pcie->ports))
diff --git a/queue-5.10/pci-move-resizable-bar-code-to-rebar.c.patch b/queue-5.10/pci-move-resizable-bar-code-to-rebar.c.patch
new file mode 100644 (file)
index 0000000..c68152d
--- /dev/null
@@ -0,0 +1,508 @@
+From stable+bounces-274991-greg=kroah.com@vger.kernel.org Wed Jul 15 18:37:16 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 12:32:22 -0400
+Subject: PCI: Move Resizable BAR code to rebar.c
+To: stable@vger.kernel.org
+Cc: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>, "Bjorn Helgaas" <bhelgaas@google.com>, "Christian König" <christian.koenig@amd.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260715163223.952417-5-sashal@kernel.org>
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 9f71938cd77f32a448f40a288e409eca60e55486 ]
+
+For lack of a better place to put it, Resizable BAR code has been placed
+inside pci.c and setup-res.c that do not use it for anything.  Upcoming
+changes are going to add more Resizable BAR related functions, increasing
+the code size.
+
+As pci.c is huge as is, move the Resizable BAR related code and the BAR
+resize code from setup-res.c to rebar.c.
+
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Link: https://patch.msgid.link/20251113180053.27944-2-ilpo.jarvinen@linux.intel.com
+Stable-dep-of: ee7471fe968d ("PCI: Skip Resizable BAR restore on read error")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/driver-api/pci/pci.rst |    3 
+ drivers/pci/Makefile                 |    2 
+ drivers/pci/pci.c                    |  135 ----------------------
+ drivers/pci/pci.h                    |    1 
+ drivers/pci/rebar.c                  |  211 +++++++++++++++++++++++++++++++++++
+ drivers/pci/setup-res.c              |   64 ----------
+ 6 files changed, 216 insertions(+), 200 deletions(-)
+ create mode 100644 drivers/pci/rebar.c
+
+--- a/Documentation/driver-api/pci/pci.rst
++++ b/Documentation/driver-api/pci/pci.rst
+@@ -31,6 +31,9 @@ PCI Support Library
+ .. kernel-doc:: drivers/pci/slot.c
+    :export:
++.. kernel-doc:: drivers/pci/rebar.c
++   :export:
++
+ .. kernel-doc:: drivers/pci/rom.c
+    :export:
+--- a/drivers/pci/Makefile
++++ b/drivers/pci/Makefile
+@@ -4,7 +4,7 @@
+ obj-$(CONFIG_PCI)             += access.o bus.o probe.o host-bridge.o \
+                                  remove.o pci.o pci-driver.o search.o \
+-                                 pci-sysfs.o rom.o setup-res.o irq.o vpd.o \
++                                 pci-sysfs.o rebar.o rom.o setup-res.o irq.o vpd.o \
+                                  setup-bus.o vc.o mmap.o setup-irq.o
+ obj-$(CONFIG_PCI)             += pcie/
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -1626,33 +1626,6 @@ static void pci_restore_config_space(str
+       }
+ }
+-static void pci_restore_rebar_state(struct pci_dev *pdev)
+-{
+-      unsigned int pos, nbars, i;
+-      u32 ctrl;
+-
+-      pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
+-      if (!pos)
+-              return;
+-
+-      pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
+-      nbars = (ctrl & PCI_REBAR_CTRL_NBAR_MASK) >>
+-                  PCI_REBAR_CTRL_NBAR_SHIFT;
+-
+-      for (i = 0; i < nbars; i++, pos += 8) {
+-              struct resource *res;
+-              int bar_idx, size;
+-
+-              pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
+-              bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX;
+-              res = pdev->resource + bar_idx;
+-              size = ilog2(resource_size(res)) - 20;
+-              ctrl &= ~PCI_REBAR_CTRL_BAR_SIZE;
+-              ctrl |= size << PCI_REBAR_CTRL_BAR_SHIFT;
+-              pci_write_config_dword(pdev, pos + PCI_REBAR_CTRL, ctrl);
+-      }
+-}
+-
+ /**
+  * pci_restore_state - Restore the saved state of a PCI device
+  * @dev: PCI device that we're dealing with
+@@ -3558,114 +3531,6 @@ void pci_acs_init(struct pci_dev *dev)
+ }
+ /**
+- * pci_rebar_find_pos - find position of resize ctrl reg for BAR
+- * @pdev: PCI device
+- * @bar: BAR to find
+- *
+- * Helper to find the position of the ctrl register for a BAR.
+- * Returns -ENOTSUPP if resizable BARs are not supported at all.
+- * Returns -ENOENT if no ctrl register for the BAR could be found.
+- */
+-static int pci_rebar_find_pos(struct pci_dev *pdev, int bar)
+-{
+-      unsigned int pos, nbars, i;
+-      u32 ctrl;
+-
+-      pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
+-      if (!pos)
+-              return -ENOTSUPP;
+-
+-      pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
+-      nbars = (ctrl & PCI_REBAR_CTRL_NBAR_MASK) >>
+-                  PCI_REBAR_CTRL_NBAR_SHIFT;
+-
+-      for (i = 0; i < nbars; i++, pos += 8) {
+-              int bar_idx;
+-
+-              pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
+-              bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX;
+-              if (bar_idx == bar)
+-                      return pos;
+-      }
+-
+-      return -ENOENT;
+-}
+-
+-/**
+- * pci_rebar_get_possible_sizes - get possible sizes for BAR
+- * @pdev: PCI device
+- * @bar: BAR to query
+- *
+- * Get the possible sizes of a resizable BAR as bitmask defined in the spec
+- * (bit 0=1MB, bit 19=512GB). Returns 0 if BAR isn't resizable.
+- */
+-u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar)
+-{
+-      int pos;
+-      u32 cap;
+-
+-      pos = pci_rebar_find_pos(pdev, bar);
+-      if (pos < 0)
+-              return 0;
+-
+-      pci_read_config_dword(pdev, pos + PCI_REBAR_CAP, &cap);
+-      cap &= PCI_REBAR_CAP_SIZES;
+-
+-      /* Sapphire RX 5600 XT Pulse has an invalid cap dword for BAR 0 */
+-      if (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x731f &&
+-          bar == 0 && cap == 0x7000)
+-              cap = 0x3f000;
+-
+-      return cap >> 4;
+-}
+-
+-/**
+- * pci_rebar_get_current_size - get the current size of a BAR
+- * @pdev: PCI device
+- * @bar: BAR to set size to
+- *
+- * Read the size of a BAR from the resizable BAR config.
+- * Returns size if found or negative error code.
+- */
+-int pci_rebar_get_current_size(struct pci_dev *pdev, int bar)
+-{
+-      int pos;
+-      u32 ctrl;
+-
+-      pos = pci_rebar_find_pos(pdev, bar);
+-      if (pos < 0)
+-              return pos;
+-
+-      pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
+-      return (ctrl & PCI_REBAR_CTRL_BAR_SIZE) >> PCI_REBAR_CTRL_BAR_SHIFT;
+-}
+-
+-/**
+- * pci_rebar_set_size - set a new size for a BAR
+- * @pdev: PCI device
+- * @bar: BAR to set size to
+- * @size: new size as defined in the spec (0=1MB, 19=512GB)
+- *
+- * Set the new size of a BAR as defined in the spec.
+- * Returns zero if resizing was successful, error code otherwise.
+- */
+-int pci_rebar_set_size(struct pci_dev *pdev, int bar, int size)
+-{
+-      int pos;
+-      u32 ctrl;
+-
+-      pos = pci_rebar_find_pos(pdev, bar);
+-      if (pos < 0)
+-              return pos;
+-
+-      pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
+-      ctrl &= ~PCI_REBAR_CTRL_BAR_SIZE;
+-      ctrl |= size << PCI_REBAR_CTRL_BAR_SHIFT;
+-      pci_write_config_dword(pdev, pos + PCI_REBAR_CTRL, ctrl);
+-      return 0;
+-}
+-
+-/**
+  * pci_enable_atomic_ops_to_root - enable AtomicOp requests to root port
+  * @dev: the PCI device
+  * @cap_mask: mask of desired AtomicOp sizes, including one or more of:
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -629,6 +629,7 @@ static inline int acpi_get_rc_resources(
+ #endif
+ u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar);
++void pci_restore_rebar_state(struct pci_dev *pdev);
+ int pci_rebar_get_current_size(struct pci_dev *pdev, int bar);
+ int pci_rebar_set_size(struct pci_dev *pdev, int bar, int size);
+ static inline u64 pci_rebar_size_to_bytes(int size)
+--- /dev/null
++++ b/drivers/pci/rebar.c
+@@ -0,0 +1,211 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * PCI Resizable BAR Extended Capability handling.
++ */
++
++#include <linux/bitfield.h>
++#include <linux/errno.h>
++#include <linux/export.h>
++#include <linux/ioport.h>
++#include <linux/pci.h>
++#include <linux/types.h>
++
++#include "pci.h"
++
++/**
++ * pci_rebar_find_pos - find position of resize ctrl reg for BAR
++ * @pdev: PCI device
++ * @bar: BAR to find
++ *
++ * Helper to find the position of the ctrl register for a BAR.
++ * Returns -ENOTSUPP if resizable BARs are not supported at all.
++ * Returns -ENOENT if no ctrl register for the BAR could be found.
++ */
++static int pci_rebar_find_pos(struct pci_dev *pdev, int bar)
++{
++      unsigned int pos, nbars, i;
++      u32 ctrl;
++
++      pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
++      if (!pos)
++              return -ENOTSUPP;
++
++      pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
++      nbars = (ctrl & PCI_REBAR_CTRL_NBAR_MASK) >>
++                  PCI_REBAR_CTRL_NBAR_SHIFT;
++
++      for (i = 0; i < nbars; i++, pos += 8) {
++              int bar_idx;
++
++              pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
++              bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX;
++              if (bar_idx == bar)
++                      return pos;
++      }
++
++      return -ENOENT;
++}
++
++/**
++ * pci_rebar_get_possible_sizes - get possible sizes for BAR
++ * @pdev: PCI device
++ * @bar: BAR to query
++ *
++ * Get the possible sizes of a resizable BAR as bitmask defined in the spec
++ * (bit 0=1MB, bit 19=512GB). Returns 0 if BAR isn't resizable.
++ */
++u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar)
++{
++      int pos;
++      u32 cap;
++
++      pos = pci_rebar_find_pos(pdev, bar);
++      if (pos < 0)
++              return 0;
++
++      pci_read_config_dword(pdev, pos + PCI_REBAR_CAP, &cap);
++      cap &= PCI_REBAR_CAP_SIZES;
++
++      /* Sapphire RX 5600 XT Pulse has an invalid cap dword for BAR 0 */
++      if (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x731f &&
++          bar == 0 && cap == 0x7000)
++              cap = 0x3f000;
++
++      return cap >> 4;
++}
++
++/**
++ * pci_rebar_get_current_size - get the current size of a BAR
++ * @pdev: PCI device
++ * @bar: BAR to set size to
++ *
++ * Read the size of a BAR from the resizable BAR config.
++ * Returns size if found or negative error code.
++ */
++int pci_rebar_get_current_size(struct pci_dev *pdev, int bar)
++{
++      int pos;
++      u32 ctrl;
++
++      pos = pci_rebar_find_pos(pdev, bar);
++      if (pos < 0)
++              return pos;
++
++      pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
++      return (ctrl & PCI_REBAR_CTRL_BAR_SIZE) >> PCI_REBAR_CTRL_BAR_SHIFT;
++}
++
++/**
++ * pci_rebar_set_size - set a new size for a BAR
++ * @pdev: PCI device
++ * @bar: BAR to set size to
++ * @size: new size as defined in the spec (0=1MB, 19=512GB)
++ *
++ * Set the new size of a BAR as defined in the spec.
++ * Returns zero if resizing was successful, error code otherwise.
++ */
++int pci_rebar_set_size(struct pci_dev *pdev, int bar, int size)
++{
++      int pos;
++      u32 ctrl;
++
++      pos = pci_rebar_find_pos(pdev, bar);
++      if (pos < 0)
++              return pos;
++
++      pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
++      ctrl &= ~PCI_REBAR_CTRL_BAR_SIZE;
++      ctrl |= size << PCI_REBAR_CTRL_BAR_SHIFT;
++      pci_write_config_dword(pdev, pos + PCI_REBAR_CTRL, ctrl);
++      return 0;
++}
++
++void pci_restore_rebar_state(struct pci_dev *pdev)
++{
++      unsigned int pos, nbars, i;
++      u32 ctrl;
++
++      pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
++      if (!pos)
++              return;
++
++      pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
++      nbars = FIELD_GET(PCI_REBAR_CTRL_NBAR_MASK, ctrl);
++
++      for (i = 0; i < nbars; i++, pos += 8) {
++              struct resource *res;
++              int bar_idx, size;
++
++              pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
++              bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX;
++              res = pdev->resource + bar_idx;
++              size = ilog2(resource_size(res)) - 20;
++              ctrl &= ~PCI_REBAR_CTRL_BAR_SIZE;
++              ctrl |= size << PCI_REBAR_CTRL_BAR_SHIFT;
++              pci_write_config_dword(pdev, pos + PCI_REBAR_CTRL, ctrl);
++      }
++}
++
++/**
++ * pci_resize_resource - reconfigure a Resizable BAR and resources
++ * @dev: the PCI device
++ * @resno: index of the BAR to be resized
++ * @size: new size as defined in the spec (0=1MB, 31=128TB)
++ * @exclude_bars: a mask of BARs that should not be released
++ *
++ * Reconfigure @resno to @size and re-run resource assignment algorithm
++ * with the new size.
++ *
++ * Prior to resize, release @dev resources that share a bridge window with
++ * @resno.  This unpins the bridge window resource to allow changing it.
++ *
++ * The caller may prevent releasing a particular BAR by providing
++ * @exclude_bars mask, but this may result in the resize operation failing
++ * due to insufficient space.
++ *
++ * Return: 0 on success, or negative on error. In case of an error, the
++ *         resources are restored to their original places.
++ */
++int pci_resize_resource(struct pci_dev *dev, int resno, int size,
++                      int exclude_bars)
++{
++      struct pci_host_bridge *host;
++      int old, ret;
++      u32 sizes;
++      u16 cmd;
++
++      /* Check if we must preserve the firmware's resource assignment */
++      host = pci_find_host_bridge(dev->bus);
++      if (host->preserve_config)
++              return -ENOTSUPP;
++
++      pci_read_config_word(dev, PCI_COMMAND, &cmd);
++      if (cmd & PCI_COMMAND_MEMORY)
++              return -EBUSY;
++
++      sizes = pci_rebar_get_possible_sizes(dev, resno);
++      if (!sizes)
++              return -ENOTSUPP;
++
++      if (!(sizes & BIT(size)))
++              return -EINVAL;
++
++      old = pci_rebar_get_current_size(dev, resno);
++      if (old < 0)
++              return old;
++
++      ret = pci_rebar_set_size(dev, resno, size);
++      if (ret)
++              return ret;
++
++      ret = pci_do_resource_release_and_resize(dev, resno, size, exclude_bars);
++      if (ret)
++              goto error_resize;
++
++      return 0;
++
++error_resize:
++      pci_rebar_set_size(dev, resno, old);
++      return ret;
++}
++EXPORT_SYMBOL(pci_resize_resource);
+--- a/drivers/pci/setup-res.c
++++ b/drivers/pci/setup-res.c
+@@ -422,70 +422,6 @@ void pci_release_resource(struct pci_dev
+ }
+ EXPORT_SYMBOL(pci_release_resource);
+-/**
+- * pci_resize_resource - reconfigure a Resizable BAR and resources
+- * @dev: the PCI device
+- * @resno: index of the BAR to be resized
+- * @size: new size as defined in the spec (0=1MB, 31=128TB)
+- * @exclude_bars: a mask of BARs that should not be released
+- *
+- * Reconfigure @resno to @size and re-run resource assignment algorithm
+- * with the new size.
+- *
+- * Prior to resize, release @dev resources that share a bridge window with
+- * @resno.  This unpins the bridge window resource to allow changing it.
+- *
+- * The caller may prevent releasing a particular BAR by providing
+- * @exclude_bars mask, but this may result in the resize operation failing
+- * due to insufficient space.
+- *
+- * Return: 0 on success, or negative on error. In case of an error, the
+- *         resources are restored to their original places.
+- */
+-int pci_resize_resource(struct pci_dev *dev, int resno, int size,
+-                      int exclude_bars)
+-{
+-      struct pci_host_bridge *host;
+-      int old, ret;
+-      u32 sizes;
+-      u16 cmd;
+-
+-      /* Check if we must preserve the firmware's resource assignment */
+-      host = pci_find_host_bridge(dev->bus);
+-      if (host->preserve_config)
+-              return -ENOTSUPP;
+-
+-      pci_read_config_word(dev, PCI_COMMAND, &cmd);
+-      if (cmd & PCI_COMMAND_MEMORY)
+-              return -EBUSY;
+-
+-      sizes = pci_rebar_get_possible_sizes(dev, resno);
+-      if (!sizes)
+-              return -ENOTSUPP;
+-
+-      if (!(sizes & BIT(size)))
+-              return -EINVAL;
+-
+-      old = pci_rebar_get_current_size(dev, resno);
+-      if (old < 0)
+-              return old;
+-
+-      ret = pci_rebar_set_size(dev, resno, size);
+-      if (ret)
+-              return ret;
+-
+-      ret = pci_do_resource_release_and_resize(dev, resno, size, exclude_bars);
+-      if (ret)
+-              goto error_resize;
+-
+-      return 0;
+-
+-error_resize:
+-      pci_rebar_set_size(dev, resno, old);
+-      return ret;
+-}
+-EXPORT_SYMBOL(pci_resize_resource);
+-
+ int pci_enable_resources(struct pci_dev *dev, int mask)
+ {
+       u16 cmd, old_cmd;
diff --git a/queue-5.10/pci-prevent-resource-tree-corruption-when-bar-resize-fails.patch b/queue-5.10/pci-prevent-resource-tree-corruption-when-bar-resize-fails.patch
new file mode 100644 (file)
index 0000000..2bb5196
--- /dev/null
@@ -0,0 +1,71 @@
+From stable+bounces-274987-greg=kroah.com@vger.kernel.org Wed Jul 15 18:32:33 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 12:32:18 -0400
+Subject: PCI: Prevent resource tree corruption when BAR resize fails
+To: stable@vger.kernel.org
+Cc: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>, "Simon Richter" <Simon.Richter@hogyros.de>, "Alex Bennée" <alex.bennee@linaro.org>, "Bjorn Helgaas" <bhelgaas@google.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260715163223.952417-1-sashal@kernel.org>
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 91c4c89db41499eea1b29c56655f79c3bae66e93 ]
+
+pbus_reassign_bridge_resources() saves bridge windows into the saved
+list before attempting to adjust resource assignments to perform a BAR
+resize operation. If resource adjustments cannot be completed fully,
+rollback is attempted by restoring the resource from the saved list.
+
+The rollback, however, does not check whether the resources it restores were
+assigned by the partial resize attempt. If restore changes addresses of the
+resource, it can result in corrupting the resource tree.
+
+An example of a corrupted resource tree with overlapping addresses:
+
+  6200000000000-6203fbfffffff : pciex@620c3c0000000
+    6200000000000-6203fbff0ffff : PCI Bus 0030:01
+      6200020000000-62000207fffff : 0030:01:00.0
+      6200000000000-6203fbff0ffff : PCI Bus 0030:02
+
+A resource that are assigned into the resource tree must remain
+unchanged. Thus, release such a resource before attempting to restore
+and claim it back.
+
+For simplicity, always do the release and claim back for the resource
+even in the cases where it is restored to the same address range.
+
+Note: this fix may "break" some cases where devices "worked" because
+the resource tree corruption allowed address space double counting to
+fit more resource than what can now be assigned without double
+counting. The upcoming changes to BAR resizing should address those
+scenarios (to the extent possible).
+
+Fixes: 8bb705e3e79d ("PCI: Add pci_resize_resource() for resizing BARs")
+Reported-by: Simon Richter <Simon.Richter@hogyros.de>
+Link: https://lore.kernel.org/linux-pci/67840a16-99b4-4d8c-9b5c-4721ab0970a2@hogyros.de/
+Reported-by: Alex Bennée <alex.bennee@linaro.org>
+Link: https://lore.kernel.org/linux-pci/874irqop6b.fsf@draig.linaro.org/
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Alex Bennée <alex.bennee@linaro.org> # AVA, AMD GPU
+Link: https://patch.msgid.link/20251113162628.5946-2-ilpo.jarvinen@linux.intel.com
+Stable-dep-of: ee7471fe968d ("PCI: Skip Resizable BAR restore on read error")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/setup-bus.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/pci/setup-bus.c
++++ b/drivers/pci/setup-bus.c
+@@ -2257,6 +2257,11 @@ cleanup:
+               bridge = dev_res->dev;
+               i = res - bridge->resource;
++              if (res->parent) {
++                      release_child_resources(res);
++                      pci_release_resource(bridge, i);
++              }
++
+               res->start = dev_res->start;
+               res->end = dev_res->end;
+               res->flags = dev_res->flags;
diff --git a/queue-5.10/pci-skip-resizable-bar-restore-on-read-error.patch b/queue-5.10/pci-skip-resizable-bar-restore-on-read-error.patch
new file mode 100644 (file)
index 0000000..f0d1d34
--- /dev/null
@@ -0,0 +1,61 @@
+From stable+bounces-274992-greg=kroah.com@vger.kernel.org Wed Jul 15 18:37:21 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 12:32:23 -0400
+Subject: PCI: Skip Resizable BAR restore on read error
+To: stable@vger.kernel.org
+Cc: Marco Nenciarini <mnencia@kcore.it>, Bjorn Helgaas <bhelgaas@google.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260715163223.952417-6-sashal@kernel.org>
+
+From: Marco Nenciarini <mnencia@kcore.it>
+
+[ Upstream commit ee7471fe968d210939be9046089a924cd23c8c3b ]
+
+pci_restore_rebar_state() uses the Resizable BAR Control register to decide
+how many BARs to restore (nbars) and which BAR each iteration addresses
+(bar_idx).
+
+When a device does not respond, config reads typically return
+PCI_ERROR_RESPONSE (~0).  Both fields are 3 bits wide, so nbars and bar_idx
+both evaluate to 7, past the spec's valid ranges for both fields.
+pci_resource_n() then returns an unrelated resource slot, whose size is
+used to derive a nonsensical value written back to the Resizable BAR
+Control register.
+
+Bail out if any Resizable BAR Control read returns PCI_ERROR_RESPONSE. No
+further BARs are touched, which is safe because a config read that returns
+PCI_ERROR_RESPONSE indicates the device is unreachable and restoration is
+pointless.
+
+Fixes: d3252ace0bc6 ("PCI: Restore resized BAR state on resume")
+Signed-off-by: Marco Nenciarini <mnencia@kcore.it>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/666cac19b5daa0ab0e0ab64454e76b4d24465dbd.1776429882.git.mnencia@kcore.it
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/rebar.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/pci/rebar.c
++++ b/drivers/pci/rebar.c
+@@ -130,6 +130,9 @@ void pci_restore_rebar_state(struct pci_
+               return;
+       pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
++      if (PCI_POSSIBLE_ERROR(ctrl))
++              return;
++
+       nbars = FIELD_GET(PCI_REBAR_CTRL_NBAR_MASK, ctrl);
+       for (i = 0; i < nbars; i++, pos += 8) {
+@@ -137,6 +140,9 @@ void pci_restore_rebar_state(struct pci_
+               int bar_idx, size;
+               pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
++              if (PCI_POSSIBLE_ERROR(ctrl))
++                      return;
++
+               bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX;
+               res = pdev->resource + bar_idx;
+               size = ilog2(resource_size(res)) - 20;
diff --git a/queue-5.10/proc-protect-ptrace_may_access-with-exec_update_lock-fd-links.patch b/queue-5.10/proc-protect-ptrace_may_access-with-exec_update_lock-fd-links.patch
new file mode 100644 (file)
index 0000000..71beacf
--- /dev/null
@@ -0,0 +1,274 @@
+From stable+bounces-277135-greg=kroah.com@vger.kernel.org Fri Jul 17 18:38:31 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2026 12:38:21 -0400
+Subject: proc: protect ptrace_may_access() with exec_update_lock (FD links)
+To: stable@vger.kernel.org
+Cc: Jann Horn <jannh@google.com>, "Christian Brauner (Amutable)" <brauner@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260717163821.2035203-3-sashal@kernel.org>
+
+From: Jann Horn <jannh@google.com>
+
+[ Upstream commit 6255da28d4bb5349fe18e84cb043ccd394eba75d ]
+
+proc_pid_get_link() and proc_pid_readlink() currently look up the task from
+the pid once, then do the ptrace access check on that task, then look up
+the task from the pid a second time to do the actual access.
+That's racy in several ways.
+
+To fix it, pass the task to the ->proc_get_link() handler, and instead of
+proc_fd_access_allowed(), introduce a new helper call_proc_get_link() that
+looks up and locks the task, does the access check, and calls
+->proc_get_link().
+
+Fixes: 778c1144771f ("[PATCH] proc: Use sane permission checks on the /proc/<pid>/fd/ symlinks")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jann Horn <jannh@google.com>
+Link: https://patch.msgid.link/20260518-procfs-lockfix-part1-v1-2-5c3d20e0ac33@google.com
+Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/proc/base.c     |  119 ++++++++++++++++++++---------------------------------
+ fs/proc/fd.c       |   25 ++++-------
+ fs/proc/internal.h |    2 
+ 3 files changed, 58 insertions(+), 88 deletions(-)
+
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -217,33 +217,24 @@ static int get_task_root(struct task_str
+       return result;
+ }
+-static int proc_cwd_link(struct dentry *dentry, struct path *path)
++static int proc_cwd_link(struct dentry *dentry, struct path *path,
++                       struct task_struct *task)
+ {
+-      struct task_struct *task = get_proc_task(d_inode(dentry));
+       int result = -ENOENT;
+-      if (task) {
+-              task_lock(task);
+-              if (task->fs) {
+-                      get_fs_pwd(task->fs, path);
+-                      result = 0;
+-              }
+-              task_unlock(task);
+-              put_task_struct(task);
++      task_lock(task);
++      if (task->fs) {
++              get_fs_pwd(task->fs, path);
++              result = 0;
+       }
++      task_unlock(task);
+       return result;
+ }
+-static int proc_root_link(struct dentry *dentry, struct path *path)
++static int proc_root_link(struct dentry *dentry, struct path *path,
++                        struct task_struct *task)
+ {
+-      struct task_struct *task = get_proc_task(d_inode(dentry));
+-      int result = -ENOENT;
+-
+-      if (task) {
+-              result = get_task_root(task, path);
+-              put_task_struct(task);
+-      }
+-      return result;
++      return get_task_root(task, path);
+ }
+ /*
+@@ -703,23 +694,6 @@ static int proc_pid_syscall(struct seq_f
+ /*                       Here the fs part begins                        */
+ /************************************************************************/
+-/* permission checks */
+-static int proc_fd_access_allowed(struct inode *inode)
+-{
+-      struct task_struct *task;
+-      int allowed = 0;
+-      /* Allow access to a task's file descriptors if it is us or we
+-       * may use ptrace attach to the process and find out that
+-       * information.
+-       */
+-      task = get_proc_task(inode);
+-      if (task) {
+-              allowed = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
+-              put_task_struct(task);
+-      }
+-      return allowed;
+-}
+-
+ int proc_nochmod_setattr(struct dentry *dentry, struct iattr *attr)
+ {
+       int error;
+@@ -1774,16 +1748,12 @@ static const struct file_operations proc
+       .release        = single_release,
+ };
+-static int proc_exe_link(struct dentry *dentry, struct path *exe_path)
++static int proc_exe_link(struct dentry *dentry, struct path *exe_path,
++                       struct task_struct *task)
+ {
+-      struct task_struct *task;
+       struct file *exe_file;
+-      task = get_proc_task(d_inode(dentry));
+-      if (!task)
+-              return -ENOENT;
+       exe_file = get_task_exe_file(task);
+-      put_task_struct(task);
+       if (exe_file) {
+               *exe_path = exe_file->f_path;
+               path_get(&exe_file->f_path);
+@@ -1793,26 +1763,42 @@ static int proc_exe_link(struct dentry *
+               return -ENOENT;
+ }
++static int call_proc_get_link(struct dentry *dentry, struct inode *inode, struct path *path_out)
++{
++      struct task_struct *task;
++      int ret;
++
++      task = get_proc_task(inode);
++      if (!task)
++              return -ENOENT;
++      ret = down_read_killable(&task->signal->exec_update_lock);
++      if (ret)
++              goto out_put_task;
++      if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
++              ret = -EACCES;
++              goto out;
++      }
++      ret = PROC_I(inode)->op.proc_get_link(dentry, path_out, task);
++
++out:
++      up_read(&task->signal->exec_update_lock);
++out_put_task:
++      put_task_struct(task);
++      return ret;
++}
++
+ static const char *proc_pid_get_link(struct dentry *dentry,
+                                    struct inode *inode,
+                                    struct delayed_call *done)
+ {
+       struct path path;
+-      int error = -EACCES;
++      int error;
+       if (!dentry)
+               return ERR_PTR(-ECHILD);
+-
+-      /* Are we allowed to snoop on the tasks file descriptors? */
+-      if (!proc_fd_access_allowed(inode))
+-              goto out;
+-
+-      error = PROC_I(inode)->op.proc_get_link(dentry, &path);
+-      if (error)
+-              goto out;
+-
+-      error = nd_jump_link(&path);
+-out:
++      error = call_proc_get_link(dentry, inode, &path);
++      if (!error)
++              error = nd_jump_link(&path);
+       return ERR_PTR(error);
+ }
+@@ -1846,17 +1832,11 @@ static int proc_pid_readlink(struct dent
+       struct inode *inode = d_inode(dentry);
+       struct path path;
+-      /* Are we allowed to snoop on the tasks file descriptors? */
+-      if (!proc_fd_access_allowed(inode))
+-              goto out;
+-
+-      error = PROC_I(inode)->op.proc_get_link(dentry, &path);
+-      if (error)
+-              goto out;
+-
+-      error = do_proc_readlink(&path, buffer, buflen);
+-      path_put(&path);
+-out:
++      error = call_proc_get_link(dentry, inode, &path);
++      if (!error) {
++              error = do_proc_readlink(&path, buffer, buflen);
++              path_put(&path);
++      }
+       return error;
+ }
+@@ -2242,21 +2222,16 @@ static const struct dentry_operations ti
+       .d_delete       = pid_delete_dentry,
+ };
+-static int map_files_get_link(struct dentry *dentry, struct path *path)
++static int map_files_get_link(struct dentry *dentry, struct path *path,
++                            struct task_struct *task)
+ {
+       unsigned long vm_start, vm_end;
+       struct vm_area_struct *vma;
+-      struct task_struct *task;
+       struct mm_struct *mm;
+       int rc;
+       rc = -ENOENT;
+-      task = get_proc_task(d_inode(dentry));
+-      if (!task)
+-              goto out;
+-
+       mm = get_task_mm(task);
+-      put_task_struct(task);
+       if (!mm)
+               goto out;
+--- a/fs/proc/fd.c
++++ b/fs/proc/fd.c
+@@ -140,24 +140,19 @@ static const struct dentry_operations ti
+       .d_delete       = pid_delete_dentry,
+ };
+-static int proc_fd_link(struct dentry *dentry, struct path *path)
++static int proc_fd_link(struct dentry *dentry, struct path *path,
++                      struct task_struct *task)
+ {
+-      struct task_struct *task;
+       int ret = -ENOENT;
++      unsigned int fd = proc_fd(d_inode(dentry));
++      struct file *fd_file;
+-      task = get_proc_task(d_inode(dentry));
+-      if (task) {
+-              unsigned int fd = proc_fd(d_inode(dentry));
+-              struct file *fd_file;
+-
+-              fd_file = fget_task(task, fd);
+-              if (fd_file) {
+-                      *path = fd_file->f_path;
+-                      path_get(&fd_file->f_path);
+-                      ret = 0;
+-                      fput(fd_file);
+-              }
+-              put_task_struct(task);
++      fd_file = fget_task(task, fd);
++      if (fd_file) {
++              *path = fd_file->f_path;
++              path_get(&fd_file->f_path);
++              ret = 0;
++              fput(fd_file);
+       }
+       return ret;
+--- a/fs/proc/internal.h
++++ b/fs/proc/internal.h
+@@ -97,7 +97,7 @@ extern struct kmem_cache *proc_dir_entry
+ void pde_free(struct proc_dir_entry *pde);
+ union proc_op {
+-      int (*proc_get_link)(struct dentry *, struct path *);
++      int (*proc_get_link)(struct dentry *, struct path *, struct task_struct *);
+       int (*proc_show)(struct seq_file *m,
+               struct pid_namespace *ns, struct pid *pid,
+               struct task_struct *task);
diff --git a/queue-5.10/proc-protect-ptrace_may_access-with-exec_update_lock-part-1.patch b/queue-5.10/proc-protect-ptrace_may_access-with-exec_update_lock-part-1.patch
new file mode 100644 (file)
index 0000000..e7b9070
--- /dev/null
@@ -0,0 +1,210 @@
+From stable+bounces-277189-greg=kroah.com@vger.kernel.org Fri Jul 17 21:24:09 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2026 15:23:58 -0400
+Subject: proc: protect ptrace_may_access() with exec_update_lock (part 1)
+To: stable@vger.kernel.org
+Cc: Jann Horn <jannh@google.com>, "Christian Brauner (Amutable)" <brauner@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260717192358.2131761-1-sashal@kernel.org>
+
+From: Jann Horn <jannh@google.com>
+
+[ Upstream commit 6650527444dadc63d84aa939d14ecba4fadb2f69 ]
+
+Fix the easy cases where procfs currently calls ptrace_may_access() without
+exec_update_lock protection, where the fix is to simply add the extra lock
+or use mm_access():
+
+ - do_task_stat(): grab exec_update_lock
+ - proc_pid_wchan(): grab exec_update_lock
+ - proc_map_files_lookup(): use mm_access() instead of get_task_mm()
+ - proc_map_files_readdir(): use mm_access() instead of get_task_mm()
+ - proc_ns_get_link(): grab exec_update_lock
+ - proc_ns_readlink(): grab exec_update_lock
+
+Fixes: f83ce3e6b02d ("proc: avoid information leaks to non-privileged processes")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jann Horn <jannh@google.com>
+Link: https://patch.msgid.link/20260518-procfs-lockfix-part1-v1-1-5c3d20e0ac33@google.com
+Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
+[ converted NULL return from mm_access() to ERR_PTR(-ESRCH) at call sites since 5.15's mm_access() returns NULL when the task has no mm ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/proc/array.c      |    6 ++++++
+ fs/proc/base.c       |   41 ++++++++++++++++++++++++-----------------
+ fs/proc/namespaces.c |   12 ++++++++++++
+ 3 files changed, 42 insertions(+), 17 deletions(-)
+
+--- a/fs/proc/array.c
++++ b/fs/proc/array.c
+@@ -449,6 +449,11 @@ static int do_task_stat(struct seq_file
+       unsigned long flags;
+       struct signal_struct *sig = task->signal;
+       unsigned int seq = 1;
++      int ret;
++
++      ret = down_read_killable(&task->signal->exec_update_lock);
++      if (ret)
++              return ret;
+       state = *get_task_state(task);
+       vsize = eip = esp = 0;
+@@ -626,6 +631,7 @@ static int do_task_stat(struct seq_file
+               seq_puts(m, " 0");
+       seq_putc(m, '\n');
++      up_read(&task->signal->exec_update_lock);
+       if (mm)
+               mmput(mm);
+       return 0;
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -413,18 +413,24 @@ static int proc_pid_wchan(struct seq_fil
+ {
+       unsigned long wchan;
+       char symname[KSYM_NAME_LEN];
++      int err;
++      err = down_read_killable(&task->signal->exec_update_lock);
++      if (err)
++              return err;
+       if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
+               goto print0;
+       wchan = get_wchan(task);
+       if (wchan && !lookup_symbol_name(wchan, symname)) {
+               seq_puts(m, symname);
++              up_read(&task->signal->exec_update_lock);
+               return 0;
+       }
+ print0:
+       seq_putc(m, '0');
++      up_read(&task->signal->exec_update_lock);
+       return 0;
+ }
+ #endif /* CONFIG_KALLSYMS */
+@@ -2327,17 +2333,17 @@ static struct dentry *proc_map_files_loo
+       if (!task)
+               goto out;
+-      result = ERR_PTR(-EACCES);
+-      if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
+-              goto out_put_task;
+-
+       result = ERR_PTR(-ENOENT);
+       if (dname_to_vma_addr(dentry, &vm_start, &vm_end))
+               goto out_put_task;
+-      mm = get_task_mm(task);
++      mm = mm_access(task, PTRACE_MODE_READ_FSCREDS);
+       if (!mm)
++              mm = ERR_PTR(-ESRCH);
++      if (IS_ERR(mm)) {
++              result = ERR_CAST(mm);
+               goto out_put_task;
++      }
+       result = ERR_PTR(-EINTR);
+       if (mmap_read_lock_killable(mm))
+@@ -2386,23 +2392,24 @@ proc_map_files_readdir(struct file *file
+       if (!task)
+               goto out;
+-      ret = -EACCES;
+-      if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
+-              goto out_put_task;
+-
+       ret = 0;
+       if (!dir_emit_dots(file, ctx))
+               goto out_put_task;
+-      mm = get_task_mm(task);
++      mm = mm_access(task, PTRACE_MODE_READ_FSCREDS);
+       if (!mm)
++              mm = ERR_PTR(-ESRCH);
++      if (IS_ERR(mm)) {
++              ret = PTR_ERR(mm);
++              /* if the task has no mm, the directory should just be empty */
++              if (ret == -ESRCH)
++                      ret = 0;
+               goto out_put_task;
++      }
+       ret = mmap_read_lock_killable(mm);
+-      if (ret) {
+-              mmput(mm);
+-              goto out_put_task;
+-      }
++      if (ret)
++              goto out_put_mm;
+       nr_files = 0;
+@@ -2426,8 +2433,7 @@ proc_map_files_readdir(struct file *file
+               if (!p) {
+                       ret = -ENOMEM;
+                       mmap_read_unlock(mm);
+-                      mmput(mm);
+-                      goto out_put_task;
++                      goto out_put_mm;
+               }
+               p->start = vma->vm_start;
+@@ -2435,7 +2441,6 @@ proc_map_files_readdir(struct file *file
+               p->mode = vma->vm_file->f_mode;
+       }
+       mmap_read_unlock(mm);
+-      mmput(mm);
+       for (i = 0; i < nr_files; i++) {
+               char buf[4 * sizeof(long) + 2]; /* max: %lx-%lx\0 */
+@@ -2452,6 +2457,8 @@ proc_map_files_readdir(struct file *file
+               ctx->pos++;
+       }
++out_put_mm:
++      mmput(mm);
+ out_put_task:
+       put_task_struct(task);
+ out:
+--- a/fs/proc/namespaces.c
++++ b/fs/proc/namespaces.c
+@@ -55,6 +55,10 @@ static const char *proc_ns_get_link(stru
+       if (!task)
+               return ERR_PTR(-EACCES);
++      error = down_read_killable(&task->signal->exec_update_lock);
++      if (error)
++              goto out_put_task;
++
+       if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
+               goto out;
+@@ -64,6 +68,8 @@ static const char *proc_ns_get_link(stru
+       error = nd_jump_link(&ns_path);
+ out:
++      up_read(&task->signal->exec_update_lock);
++out_put_task:
+       put_task_struct(task);
+       return ERR_PTR(error);
+ }
+@@ -80,11 +86,17 @@ static int proc_ns_readlink(struct dentr
+       if (!task)
+               return res;
++      res = down_read_killable(&task->signal->exec_update_lock);
++      if (res)
++              goto out_put_task;
++
+       if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
+               res = ns_get_name(name, sizeof(name), task, ns_ops);
+               if (res >= 0)
+                       res = readlink_copy(buffer, buflen, name);
+       }
++      up_read(&task->signal->exec_update_lock);
++out_put_task:
+       put_task_struct(task);
+       return res;
+ }
diff --git a/queue-5.10/proc-rename-proc_setattr-to-proc_nochmod_setattr.patch b/queue-5.10/proc-rename-proc_setattr-to-proc_nochmod_setattr.patch
new file mode 100644 (file)
index 0000000..e75f859
--- /dev/null
@@ -0,0 +1,193 @@
+From stable+bounces-277134-greg=kroah.com@vger.kernel.org Fri Jul 17 18:38:30 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2026 12:38:20 -0400
+Subject: proc: rename proc_setattr to proc_nochmod_setattr
+To: stable@vger.kernel.org
+Cc: Christoph Hellwig <hch@lst.de>, Jan Kara <jack@suse.cz>, Christian Brauner <brauner@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260717163821.2035203-2-sashal@kernel.org>
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 690005b0b1e6b567c88b7790e6d90d4d6c9e09cc ]
+
+What is currently proc_setattr is a special version added after the more
+general procfs ->seattr in commit 6d76fa58b050 ("Don't allow chmod() on
+the /proc/<pid>/ files").  Give it a name that reflects that to free the
+proc_setattr name and better describe what is doing.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Link: https://patch.msgid.link/20260325063711.3298685-5-hch@lst.de
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Stable-dep-of: 6255da28d4bb ("proc: protect ptrace_may_access() with exec_update_lock (FD links)")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/proc/base.c       |   22 +++++++++++-----------
+ fs/proc/fd.c         |    4 ++--
+ fs/proc/internal.h   |    2 +-
+ fs/proc/namespaces.c |    4 ++--
+ fs/proc/proc_net.c   |    2 +-
+ 5 files changed, 17 insertions(+), 17 deletions(-)
+
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -720,7 +720,7 @@ static int proc_fd_access_allowed(struct
+       return allowed;
+ }
+-int proc_setattr(struct dentry *dentry, struct iattr *attr)
++int proc_nochmod_setattr(struct dentry *dentry, struct iattr *attr)
+ {
+       int error;
+       struct inode *inode = d_inode(dentry);
+@@ -792,7 +792,7 @@ static int proc_pid_permission(struct in
+ static const struct inode_operations proc_def_inode_operations = {
+-      .setattr        = proc_setattr,
++      .setattr        = proc_nochmod_setattr,
+ };
+ static int proc_single_show(struct seq_file *m, void *v)
+@@ -1863,7 +1863,7 @@ out:
+ const struct inode_operations proc_pid_link_inode_operations = {
+       .readlink       = proc_pid_readlink,
+       .get_link       = proc_pid_get_link,
+-      .setattr        = proc_setattr,
++      .setattr        = proc_nochmod_setattr,
+ };
+@@ -2311,7 +2311,7 @@ proc_map_files_get_link(struct dentry *d
+ static const struct inode_operations proc_map_files_link_inode_operations = {
+       .readlink       = proc_pid_readlink,
+       .get_link       = proc_map_files_get_link,
+-      .setattr        = proc_setattr,
++      .setattr        = proc_nochmod_setattr,
+ };
+ static struct dentry *
+@@ -2390,7 +2390,7 @@ out:
+ static const struct inode_operations proc_map_files_inode_operations = {
+       .lookup         = proc_map_files_lookup,
+       .permission     = proc_fd_permission,
+-      .setattr        = proc_setattr,
++      .setattr        = proc_nochmod_setattr,
+ };
+ static int
+@@ -2882,7 +2882,7 @@ static struct dentry *proc_##LSM##_attr_
+ static const struct inode_operations proc_##LSM##_attr_dir_inode_ops = { \
+       .lookup         = proc_##LSM##_attr_dir_lookup, \
+       .getattr        = pid_getattr, \
+-      .setattr        = proc_setattr, \
++      .setattr        = proc_nochmod_setattr, \
+ }
+ #ifdef CONFIG_SECURITY_SMACK
+@@ -2941,7 +2941,7 @@ static struct dentry *proc_attr_dir_look
+ static const struct inode_operations proc_attr_dir_inode_operations = {
+       .lookup         = proc_attr_dir_lookup,
+       .getattr        = pid_getattr,
+-      .setattr        = proc_setattr,
++      .setattr        = proc_nochmod_setattr,
+ };
+ #endif
+@@ -3395,7 +3395,7 @@ static struct dentry *proc_tgid_base_loo
+ static const struct inode_operations proc_tgid_base_inode_operations = {
+       .lookup         = proc_tgid_base_lookup,
+       .getattr        = pid_getattr,
+-      .setattr        = proc_setattr,
++      .setattr        = proc_nochmod_setattr,
+       .permission     = proc_pid_permission,
+ };
+@@ -3594,7 +3594,7 @@ static int proc_tid_comm_permission(stru
+ }
+ static const struct inode_operations proc_tid_comm_inode_operations = {
+-              .setattr        = proc_setattr,
++              .setattr        = proc_nochmod_setattr,
+               .permission     = proc_tid_comm_permission,
+ };
+@@ -3718,7 +3718,7 @@ static const struct file_operations proc
+ static const struct inode_operations proc_tid_base_inode_operations = {
+       .lookup         = proc_tid_base_lookup,
+       .getattr        = pid_getattr,
+-      .setattr        = proc_setattr,
++      .setattr        = proc_nochmod_setattr,
+ };
+ static struct dentry *proc_task_instantiate(struct dentry *dentry,
+@@ -3913,7 +3913,7 @@ static int proc_task_getattr(const struc
+ static const struct inode_operations proc_task_inode_operations = {
+       .lookup         = proc_task_lookup,
+       .getattr        = proc_task_getattr,
+-      .setattr        = proc_setattr,
++      .setattr        = proc_nochmod_setattr,
+       .permission     = proc_pid_permission,
+ };
+--- a/fs/proc/fd.c
++++ b/fs/proc/fd.c
+@@ -297,7 +297,7 @@ int proc_fd_permission(struct inode *ino
+ const struct inode_operations proc_fd_inode_operations = {
+       .lookup         = proc_lookupfd,
+       .permission     = proc_fd_permission,
+-      .setattr        = proc_setattr,
++      .setattr        = proc_nochmod_setattr,
+ };
+ static struct dentry *proc_fdinfo_instantiate(struct dentry *dentry,
+@@ -335,7 +335,7 @@ static int proc_readfdinfo(struct file *
+ const struct inode_operations proc_fdinfo_inode_operations = {
+       .lookup         = proc_lookupfdinfo,
+-      .setattr        = proc_setattr,
++      .setattr        = proc_nochmod_setattr,
+ };
+ const struct file_operations proc_fdinfo_operations = {
+--- a/fs/proc/internal.h
++++ b/fs/proc/internal.h
+@@ -177,7 +177,7 @@ extern int proc_pid_statm(struct seq_fil
+  */
+ extern const struct dentry_operations pid_dentry_operations;
+ extern int pid_getattr(const struct path *, struct kstat *, u32, unsigned int);
+-extern int proc_setattr(struct dentry *, struct iattr *);
++int proc_nochmod_setattr(struct dentry *dentry, struct iattr *attr);
+ extern void proc_pid_evict_inode(struct proc_inode *);
+ extern struct inode *proc_pid_make_inode(struct super_block *, struct task_struct *, umode_t);
+ extern void pid_update_inode(struct task_struct *, struct inode *);
+--- a/fs/proc/namespaces.c
++++ b/fs/proc/namespaces.c
+@@ -92,7 +92,7 @@ static int proc_ns_readlink(struct dentr
+ static const struct inode_operations proc_ns_link_inode_operations = {
+       .readlink       = proc_ns_readlink,
+       .get_link       = proc_ns_get_link,
+-      .setattr        = proc_setattr,
++      .setattr        = proc_nochmod_setattr,
+ };
+ static struct dentry *proc_ns_instantiate(struct dentry *dentry,
+@@ -179,5 +179,5 @@ out_no_task:
+ const struct inode_operations proc_ns_dir_inode_operations = {
+       .lookup         = proc_ns_dir_lookup,
+       .getattr        = pid_getattr,
+-      .setattr        = proc_setattr,
++      .setattr        = proc_nochmod_setattr,
+ };
+--- a/fs/proc/proc_net.c
++++ b/fs/proc/proc_net.c
+@@ -310,7 +310,7 @@ static int proc_tgid_net_getattr(const s
+ const struct inode_operations proc_net_inode_operations = {
+       .lookup         = proc_tgid_net_lookup,
+       .getattr        = proc_tgid_net_getattr,
+-      .setattr        = proc_setattr,
++      .setattr        = proc_nochmod_setattr,
+ };
+ static int proc_tgid_net_readdir(struct file *file, struct dir_context *ctx)
diff --git a/queue-5.10/proc-use-generic-setattr-for-proc-pid-net.patch b/queue-5.10/proc-use-generic-setattr-for-proc-pid-net.patch
new file mode 100644 (file)
index 0000000..5c6c41d
--- /dev/null
@@ -0,0 +1,46 @@
+From stable+bounces-277133-greg=kroah.com@vger.kernel.org Fri Jul 17 18:38:28 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2026 12:38:19 -0400
+Subject: proc: use generic setattr() for /proc/$PID/net
+To: stable@vger.kernel.org
+Cc: "Thomas Weißschuh" <linux@weissschuh.net>, "Zhangjin Wu" <falcon@tinylab.org>, "Willy Tarreau" <w@1wt.eu>, "Christian Brauner" <brauner@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260717163821.2035203-1-sashal@kernel.org>
+
+From: Thomas Weißschuh <linux@weissschuh.net>
+
+[ Upstream commit 18e66ae67673f2c8df6f02428798b1355691f2a9 ]
+
+All other files in /proc/$PID/ use proc_setattr().
+
+Not using it allows the usage of chmod() on /proc/$PID/net, even on
+other processes owned by the same user.
+The same would probably also be true for other attributes to be changed.
+
+As this technically represents an ABI change it is not marked for
+stable so any unlikely regressions are caught during a full release cycle.
+
+Fixes: e9720acd728a ("[NET]: Make /proc/net a symlink on /proc/self/net (v3)")
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Link: https://lore.kernel.org/lkml/d0d111ef-edae-4760-83fb-36db84278da1@t-8ch.de/
+Fixes: b4844fa0bdb4 ("selftests/nolibc: implement a few tests for various syscalls")
+Tested-by: Zhangjin Wu <falcon@tinylab.org>
+Signed-off-by: Willy Tarreau <w@1wt.eu>
+Message-Id: <20230624-proc-net-setattr-v1-2-73176812adee@weissschuh.net>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Stable-dep-of: 6255da28d4bb ("proc: protect ptrace_may_access() with exec_update_lock (FD links)")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/proc/proc_net.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/proc/proc_net.c
++++ b/fs/proc/proc_net.c
+@@ -310,6 +310,7 @@ static int proc_tgid_net_getattr(const s
+ const struct inode_operations proc_net_inode_operations = {
+       .lookup         = proc_tgid_net_lookup,
+       .getattr        = proc_tgid_net_getattr,
++      .setattr        = proc_setattr,
+ };
+ static int proc_tgid_net_readdir(struct file *file, struct dir_context *ctx)
diff --git a/queue-5.10/serial-8250_mid-disable-dma-for-selected-platforms.patch b/queue-5.10/serial-8250_mid-disable-dma-for-selected-platforms.patch
new file mode 100644 (file)
index 0000000..4caeccf
--- /dev/null
@@ -0,0 +1,64 @@
+From stable+bounces-277239-greg=kroah.com@vger.kernel.org Sat Jul 18 03:33:53 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2026 21:33:38 -0400
+Subject: serial: 8250_mid: Disable DMA for selected platforms
+To: stable@vger.kernel.org
+Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>, micas-opensource <zjianan156@gmail.com>, stable <stable@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260718013338.2621443-2-sashal@kernel.org>
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit b1b4efea05a56c0995e4702a86d6624b4fdff32f ]
+
+In accordance with Errata (specification updates)
+HSUART May Stop Functioning when DMA is Active.
+
+- Denverton document #572409, rev 3.4, DNV60
+- Ice Lake Xeon D document #714070, ICXD65
+- Snowridge document #731931, SNR44
+
+For a quick fix just disable the respective callbacks during the device probe.
+Depending on the future development we might remove them completely.
+
+Reported-by: micas-opensource <zjianan156@gmail.com>
+Closes: https://lore.kernel.org/linux-serial/20250625031409.2404219-1-opensource@ruijie.com.cn/
+Fixes: 6ede6dcd87aa ("serial: 8250_mid: add support for DMA engine handling from UART MMIO")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://patch.msgid.link/20260626094937.561776-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/8250/8250_mid.c |   13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+--- a/drivers/tty/serial/8250/8250_mid.c
++++ b/drivers/tty/serial/8250/8250_mid.c
+@@ -10,6 +10,7 @@
+ #include <linux/module.h>
+ #include <linux/pci.h>
+ #include <linux/rational.h>
++#include <linux/util_macros.h>
+ #include <linux/dma/hsu.h>
+@@ -371,8 +372,16 @@ static const struct mid8250_board dnv_bo
+       .freq = 133333333,
+       .base_baud = 115200,
+       .bar = 1,
+-      .setup = dnv_setup,
+-      .exit = dnv_exit,
++      /*
++       * Errata:
++       * HSUART May Stop Functioning when DMA is Active.
++       *
++       * - Denverton document #572409, rev 3.4, DNV60
++       * - Ice Lake Xeon D document #714070, ICXD65
++       * - Snowridge document #731931, SNR44
++       */
++      .setup = PTR_IF(false, dnv_setup),
++      .exit = PTR_IF(false, dnv_exit),
+ };
+ #define MID_DEVICE(id, board) { PCI_VDEVICE(INTEL, id), (kernel_ulong_t)&board }
diff --git a/queue-5.10/serial-8250_mid-remove-8250_pci-usage.patch b/queue-5.10/serial-8250_mid-remove-8250_pci-usage.patch
new file mode 100644 (file)
index 0000000..1625fe5
--- /dev/null
@@ -0,0 +1,120 @@
+From stable+bounces-277238-greg=kroah.com@vger.kernel.org Sat Jul 18 03:33:50 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2026 21:33:37 -0400
+Subject: serial: 8250_mid: Remove 8250_pci usage
+To: stable@vger.kernel.org
+Cc: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>, "Greg Kroah-Hartman" <gregkh@linuxfoundation.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260718013338.2621443-1-sashal@kernel.org>
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit a136abd7e7abe0f1247f8ffde6cc7c8ab09f985b ]
+
+8250_mid uses FL_*BASE* from linux/8250_pci.h and nothing else. The
+code can be simplified by directly defining BARs within the driver
+instead.
+
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Link: https://lore.kernel.org/r/20230915094336.13278-1-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: b1b4efea05a5 ("serial: 8250_mid: Disable DMA for selected platforms")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/8250/8250_mid.c |   18 +++++++-----------
+ 1 file changed, 7 insertions(+), 11 deletions(-)
+
+--- a/drivers/tty/serial/8250/8250_mid.c
++++ b/drivers/tty/serial/8250/8250_mid.c
+@@ -12,7 +12,6 @@
+ #include <linux/rational.h>
+ #include <linux/dma/hsu.h>
+-#include <linux/8250_pci.h>
+ #include "8250.h"
+@@ -32,9 +31,9 @@
+ struct mid8250;
+ struct mid8250_board {
+-      unsigned int flags;
+       unsigned long freq;
+       unsigned int base_baud;
++      unsigned int bar;
+       int (*setup)(struct mid8250 *, struct uart_port *p);
+       void (*exit)(struct mid8250 *);
+ };
+@@ -169,7 +168,6 @@ static int dnv_setup(struct mid8250 *mid
+ {
+       struct hsu_dma_chip *chip = &mid->dma_chip;
+       struct pci_dev *pdev = to_pci_dev(p->dev);
+-      unsigned int bar = FL_GET_BASE(mid->board->flags);
+       int ret;
+       pci_set_master(pdev);
+@@ -183,7 +181,7 @@ static int dnv_setup(struct mid8250 *mid
+       chip->dev = &pdev->dev;
+       chip->irq = pci_irq_vector(pdev, 0);
+       chip->regs = p->membase;
+-      chip->length = pci_resource_len(pdev, bar);
++      chip->length = pci_resource_len(pdev, mid->board->bar);
+       chip->offset = DNV_DMA_CHAN_OFFSET;
+       /* Falling back to PIO mode if DMA probing fails */
+@@ -292,7 +290,6 @@ static int mid8250_probe(struct pci_dev
+ {
+       struct uart_8250_port uart;
+       struct mid8250 *mid;
+-      unsigned int bar;
+       int ret;
+       ret = pcim_enable_device(pdev);
+@@ -304,7 +301,6 @@ static int mid8250_probe(struct pci_dev
+               return -ENOMEM;
+       mid->board = (struct mid8250_board *)id->driver_data;
+-      bar = FL_GET_BASE(mid->board->flags);
+       memset(&uart, 0, sizeof(struct uart_8250_port));
+@@ -317,8 +313,8 @@ static int mid8250_probe(struct pci_dev
+       uart.port.flags = UPF_SHARE_IRQ | UPF_FIXED_PORT | UPF_FIXED_TYPE;
+       uart.port.set_termios = mid8250_set_termios;
+-      uart.port.mapbase = pci_resource_start(pdev, bar);
+-      uart.port.membase = pcim_iomap(pdev, bar, 0);
++      uart.port.mapbase = pci_resource_start(pdev, mid->board->bar);
++      uart.port.membase = pcim_iomap(pdev, mid->board->bar, 0);
+       if (!uart.port.membase)
+               return -ENOMEM;
+@@ -356,25 +352,25 @@ static void mid8250_remove(struct pci_de
+ }
+ static const struct mid8250_board pnw_board = {
+-      .flags = FL_BASE0,
+       .freq = 50000000,
+       .base_baud = 115200,
++      .bar = 0,
+       .setup = pnw_setup,
+       .exit = pnw_exit,
+ };
+ static const struct mid8250_board tng_board = {
+-      .flags = FL_BASE0,
+       .freq = 38400000,
+       .base_baud = 1843200,
++      .bar = 0,
+       .setup = tng_setup,
+       .exit = tng_exit,
+ };
+ static const struct mid8250_board dnv_board = {
+-      .flags = FL_BASE1,
+       .freq = 133333333,
+       .base_baud = 115200,
++      .bar = 1,
+       .setup = dnv_setup,
+       .exit = dnv_exit,
+ };
index 3c4d0925112a30f603d4c2d7823720b399cc2518..47b26c7a6c4816857986920c99a70894dab41b15 100644 (file)
@@ -578,3 +578,107 @@ crypto-amcc-fix-incorrect-kernel-doc-comment-syntax-in-files.patch
 crypto-crypto4xx-remove-ahash-related-code.patch
 crypto-crypto4xx-remove-insecure-and-unused-rng_alg.patch
 batman-adv-clean-untagged-vlan-on-netdev-registration-failure.patch
+acpi-nfit-core-fix-acpi_nfit_init-error-cleanup.patch
+iio-imu-adis-add-irqf_no_thread-to-non-fifo-trigger-irq.patch
+iio-hid-sensor-rotation-fix-stale-or-zero-output-when-reading-raw-values.patch
+iio-imu-inv_icm42600-make-timestamp-module-chip-independent.patch
+iio-move-inv_icm42600-timestamp-module-in-common.patch
+iio-make-invensense-timestamp-module-generic.patch
+iio-imu-inv_mpu6050-use-the-common-inv_sensors-timestamp-module.patch
+iio-invensense-remove-redundant-initialization-of-variable-period.patch
+iio-invensense-fix-timestamp-glitches-when-switching-frequency.patch
+iio-imu-inv_icm42600-stabilized-timestamp-in-interrupt.patch
+iio-imu-inv_icm42600-fix-timestamping-by-limiting-fifo-reading.patch
+bitops-make-bytes_to_bits-treewide-available.patch
+iio-common-st_sensors-honour-channel-endianness-in-read_axis_data.patch
+alsa-aoa-check-snd_ctl_new1-return-value.patch
+bluetooth-btintel-fix-offset-calculation-boot-address-parameter.patch
+bluetooth-btintel-check-firmware-version-before-download.patch
+bluetooth-btusb-fix-use-after-free-on-marvell-probe-failure.patch
+bluetooth-btusb-fix-wakeup-source-leak-on-probe-failure.patch
+vfio-pci-release-the-vga-arbiter-client-on-register_device-failure.patch
+binder-fix-uaf-in-binder_free_transaction.patch
+pci-altera-fix-resource-leaks-on-probe-failure.patch
+media-atomisp-replace-boolean-comparison-of-values-with-bool-variables.patch
+media-staging-media-atomisp-fix-sh_css.c-brace-coding-style-issues.patch
+media-staging-media-atomisp-fix-the-rest-of-sh_css.c-brace-issues.patch
+media-staging-media-atomisp-replace-if-else-clause-with-a-ternary.patch
+media-staging-media-atomisp-fix-alignment-and-line-length-issues.patch
+staging-media-atomisp-reduce-load_primary_binaries-stack-usage.patch
+cifs-create-a-new-shared-file-holding-smb2-pdu-definitions.patch
+cifs-remove-check-of-list-iterator-against-head-past-the-loop-body.patch
+smb2-small-refactor-in-smb2_check_message.patch
+cifs-remove-unused-server-parameter-from-calc_smb_size.patch
+smb-client-restrict-implied-bcc-exemption-to-responses-without-data-area.patch
+pci-imx6-fix-imx6sx_gpr12_pcie_test_powerdown-handling.patch
+staging-rtl8723bs-split-too-long-line.patch
+staging-rtl8723bs-remove-commented-out-rt_assert-occurrences.patch
+staging-rtl8723bs-remove-all-5ghz-network-types.patch
+staging-rtl8723bs-remove-5ghz-code-related-to-channel-plan-definition.patch
+staging-rtl8723bs-remove-5ghz-code-blocks.patch
+staging-rtl8723bs-remove-commented-out-condition.patch
+staging-rtl8723bs-clean-up-comparsions-to-null.patch
+staging-rtl8723bs-fix-wep-length-underflow-and-oob-read-in-onauth.patch
+staging-rtl8723bs-fix-space-issues.patch
+staging-rtl8723bs-fix-heap-buffer-overflow-in-rtw_cfg80211_set_wpa_ie.patch
+staging-rtl8723bs-fix-oob-reads-in-ie-loops-in-issue_assocreq-and-join_cmd_hdl.patch
+pci-controller-use-dev_fwnode-instead-of-of_fwnode_handle.patch
+pci-mediatek-convert-bool-to-single-quirks-entry-and-bitmap.patch
+pci-mediatek-fix-irq-domain-leak-when-port-fails-to-enable.patch
+staging-rtl8723bs-remove-dbg_871x-log-argument.patch
+crypto-qat-fix-vf2pf-work-teardown-race-in-adf_disable_sriov.patch
+pci-prevent-resource-tree-corruption-when-bar-resize-fails.patch
+pci-free-saved-list-without-holding-pci_bus_sem.patch
+pci-fix-restoring-bars-on-bar-resize-rollback-path.patch
+pci-add-kerneldoc-for-pci_resize_resource.patch
+pci-move-resizable-bar-code-to-rebar.c.patch
+pci-skip-resizable-bar-restore-on-read-error.patch
+coresight-etb10-restore-atomic_t-for-shared-reading-state.patch
+netfilter-ebtables-use-vmalloc_array-to-improve-code.patch
+netfilter-ebtables-zero-chainstack-array.patch
+bluetooth-l2cap-fix-not-tracking-outstanding-tx-ident.patch
+bluetooth-l2cap-fix-deadlock-in-l2cap_conn_del.patch
+bluetooth-l2cap-cancel-pending_rx_work-before-taking-conn-lock.patch
+smb-client-fix-next-buffer-leak-in-receive_encrypted_standard.patch
+smb-client-mask-server-provided-mode-to-07777-in-modefromsid.patch
+smb-client-use-unaligned-reads-in-parse_posix_ctxt.patch
+smb-client-harden-posix-sid-length-parsing.patch
+writeback-fix-race-between-cgroup_writeback_umount-and-inode_switch_wbs.patch
+x.509-fix-validation-of-asn.1-certificate-header.patch
+proc-use-generic-setattr-for-proc-pid-net.patch
+proc-rename-proc_setattr-to-proc_nochmod_setattr.patch
+proc-protect-ptrace_may_access-with-exec_update_lock-fd-links.patch
+hid-add-haptics-page-defines.patch
+hid-multitouch-fix-out-of-bounds-bit-access-on-mt_io_flags.patch
+cpufreq-intel_pstate-sync-policy-cur-during-cpu-offline.patch
+proc-protect-ptrace_may_access-with-exec_update_lock-part-1.patch
+hid-appleir-fix-uaf-on-pending-key_up_timer-in-remove.patch
+serial-8250_mid-remove-8250_pci-usage.patch
+serial-8250_mid-disable-dma-for-selected-platforms.patch
+xfs-reflect-sb-features-in-xfs_mount.patch
+xfs-fix-unreachable-bigtime-check-in-dquot-flush-validation.patch
+xfs-use-null-daddr-for-unset-first-bad-log-block.patch
+hfs-hfsplus-prevent-getting-negative-values-of-offset-length.patch
+hfs-hfsplus-fix-u32-overflow-in-check_and_correct_requested_length.patch
+usb-gadget-function-simplify-diagnostic-messaging-in-printer.patch
+usb-gadget-f_printer-take-kref-only-for-successful-open.patch
+usb-free-iso-schedules-on-failed-submit.patch
+usb-iowarrior-remove-inherent-race-with-minor-number.patch
+usb-serial-digi_acceleport-fix-write-buffer-corruption.patch
+drm-i2c-sil164-drop-no-op-remove-function.patch
+leds-lm3697-remove-duplicated-error-reporting-in-.remove.patch
+leds-lm3601x-improve-error-reporting-for-problems-during-.remove.patch
+gpio-pca953x-make-platform-teardown-callback-return-void.patch
+usb-typec-ucsi-ccg-fix-use-after-free-of-ucsi-on-remove.patch
+usb-atm-ueagle-atm-wait-for-pre-firmware-load-in-.disconnect.patch
+usb-typec-tcpm-fix-vdm-type-for-enter-mode-commands.patch
+usb-gadget-f_fs-initialize-reset_work-at-allocation-time.patch
+crypto-atmel-sha204a-mark-of-related-data-as-maybe-unused.patch
+crypto-atmel-drop-explicit-initialization-of-struct-i2c_device_id-driver_data-to-0.patch
+crypto-atmel-sha204a-drop-hwrng-quality-reduction-for-atsha204a.patch
+usb-gadget-f_fs-tie-read_buffer-lifetime-to-ffs_epfile.patch
+btrfs-do-not-trim-a-device-which-is-not-writeable.patch
+crypto-qat-fix-restarting-state-leak-on-allocation-failure.patch
+crypto-qat-validate-rsa-crt-component-lengths.patch
+audit-add-audit_log_nf_skb-helper-function.patch
+audit-fix-potential-integer-overflow-in-audit_log_n_hex.patch
diff --git a/queue-5.10/smb-client-fix-next-buffer-leak-in-receive_encrypted_standard.patch b/queue-5.10/smb-client-fix-next-buffer-leak-in-receive_encrypted_standard.patch
new file mode 100644 (file)
index 0000000..3a808ce
--- /dev/null
@@ -0,0 +1,56 @@
+From stable+bounces-276753-greg=kroah.com@vger.kernel.org Thu Jul 16 18:51:29 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jul 2026 11:36:57 -0400
+Subject: smb: client: Fix next buffer leak in receive_encrypted_standard()
+To: stable@vger.kernel.org
+Cc: Haoxiang Li <haoxiang_li2024@163.com>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260716153657.582978-2-sashal@kernel.org>
+
+From: Haoxiang Li <haoxiang_li2024@163.com>
+
+[ Upstream commit 1c6267a1d5cf4c73b656f8181b310cbbb3e4767b ]
+
+receive_encrypted_standard() allocates next_buffer before checking
+whether the number of compound PDUs already reached MAX_COMPOUND. If
+the limit check fails, the function returns immediately and the newly
+allocated next_buffer is not assigned to server->smallbuf/server->bigbuf,
+making it leaked.
+
+Move the MAX_COMPOUND check before allocating next_buffer.
+
+Fixes: b24df3e30cbf ("cifs: update receive_encrypted_standard to handle compounded responses")
+Cc: stable@vger.kernel.org
+Signed-off-by: Haoxiang Li <haoxiang_li2024@163.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/smb2ops.c |   10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -4961,6 +4961,12 @@ receive_encrypted_standard(struct TCP_Se
+ one_more:
+       shdr = (struct smb2_hdr *)buf;
+       next_cmd = le32_to_cpu(shdr->NextCommand);
++
++      if (*num_mids >= MAX_COMPOUND) {
++              cifs_server_dbg(VFS, "too many PDUs in compound\n");
++              return -1;
++      }
++
+       if (next_cmd) {
+               if (WARN_ON_ONCE(next_cmd > pdu_length))
+                       return -1;
+@@ -4984,10 +4990,6 @@ one_more:
+               mid_entry->resp_buf_size = server->pdu_size;
+       }
+-      if (*num_mids >= MAX_COMPOUND) {
+-              cifs_server_dbg(VFS, "too many PDUs in compound\n");
+-              return -1;
+-      }
+       bufs[*num_mids] = buf;
+       mids[(*num_mids)++] = mid_entry;
diff --git a/queue-5.10/smb-client-harden-posix-sid-length-parsing.patch b/queue-5.10/smb-client-harden-posix-sid-length-parsing.patch
new file mode 100644 (file)
index 0000000..0fccdda
--- /dev/null
@@ -0,0 +1,44 @@
+From stable+bounces-276773-greg=kroah.com@vger.kernel.org Thu Jul 16 18:32:41 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jul 2026 12:28:12 -0400
+Subject: smb: client: harden POSIX SID length parsing
+To: stable@vger.kernel.org
+Cc: Zihan Xi <xizh2024@lzu.edu.cn>, Yuan Tan <yuantan098@gmail.com>, Yifan Wu <yifanwucs@gmail.com>, Juefei Pu <tomapufckgml@gmail.com>, Xin Liu <bird@lzu.edu.cn>, Ren Wei <n05ec@lzu.edu.cn>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260716162812.635414-1-sashal@kernel.org>
+
+From: Zihan Xi <xizh2024@lzu.edu.cn>
+
+[ Upstream commit 7ad2bcf2441430bb2e918fb3ef9a90d775a6e422 ]
+
+posix_info_sid_size() reads sid[1] to obtain the subauthority count,
+but its existing boundary check still accepts buffers with only one
+remaining byte. Require two bytes before reading sid[1] so all client
+paths that reuse the helper reject truncated POSIX SIDs safely.
+
+Fixes: 349e13ad30b4 ("cifs: add smb2 POSIX info level")
+Cc: stable@vger.kernel.org
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Assisted-by: Codex:gpt-5.4
+Signed-off-by: Zihan Xi <xizh2024@lzu.edu.cn>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/smb2pdu.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -4518,7 +4518,7 @@ int posix_info_sid_size(const void *beg,
+       size_t subauth;
+       int total;
+-      if (beg + 1 > end)
++      if (beg + 2 > end)
+               return -1;
+       subauth = *(u8 *)(beg+1);
diff --git a/queue-5.10/smb-client-mask-server-provided-mode-to-07777-in-modefromsid.patch b/queue-5.10/smb-client-mask-server-provided-mode-to-07777-in-modefromsid.patch
new file mode 100644 (file)
index 0000000..4bc27f5
--- /dev/null
@@ -0,0 +1,38 @@
+From stable+bounces-276771-greg=kroah.com@vger.kernel.org Thu Jul 16 19:13:20 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jul 2026 12:28:08 -0400
+Subject: smb: client: mask server-provided mode to 07777 in modefromsid
+To: stable@vger.kernel.org
+Cc: Norbert Manthey <nmanthey@amazon.de>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260716162808.635328-1-sashal@kernel.org>
+
+From: Norbert Manthey <nmanthey@amazon.de>
+
+[ Upstream commit e3d9c7160d483fc8f9e225aafad8ecbbc43f3151 ]
+
+When modefromsid is active, parse_dacl() applies the server-provided
+sub_auth[2] value from the NFS mode SID to cf_mode without masking to
+07777. Apply the correct masking, same as in the read path.
+
+Fixes: e2f8fbfb8d09c ("cifs: get mode bits from special sid on stat")
+Signed-off-by: Norbert Manthey <nmanthey@amazon.de>
+Assisted-by: Kiro:claude-opus-4.6
+Cc: stable@vger.kernel.org
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/cifsacl.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/cifs/cifsacl.c
++++ b/fs/cifs/cifsacl.c
+@@ -767,7 +767,7 @@ static void parse_dacl(struct cifs_acl *
+                                */
+                               fattr->cf_mode &= ~07777;
+                               fattr->cf_mode |=
+-                                      le32_to_cpu(ppace[i]->sid.sub_auth[2]);
++                                      le32_to_cpu(ppace[i]->sid.sub_auth[2]) & 07777;
+                               break;
+                       } else if (compare_sids(&(ppace[i]->sid), pownersid) == 0)
+                               access_flags_to_mode(ppace[i]->access_req,
diff --git a/queue-5.10/smb-client-restrict-implied-bcc-exemption-to-responses-without-data-area.patch b/queue-5.10/smb-client-restrict-implied-bcc-exemption-to-responses-without-data-area.patch
new file mode 100644 (file)
index 0000000..02c68ac
--- /dev/null
@@ -0,0 +1,206 @@
+From stable+bounces-274573-greg=kroah.com@vger.kernel.org Wed Jul 15 00:04:23 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 18:04:05 -0400
+Subject: smb: client: restrict implied bcc[0] exemption to responses without data area
+To: stable@vger.kernel.org
+Cc: Shoichiro Miyamoto <shoichiro.miyamoto@gmail.com>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714220405.3333589-5-sashal@kernel.org>
+
+From: Shoichiro Miyamoto <shoichiro.miyamoto@gmail.com>
+
+[ Upstream commit 53b7c271f06be4dd5cfc8c6ef552a8355c891a7f ]
+
+smb2_check_message() has a long-standing quirk that accepts a response
+whose calculated length is one byte larger than the bytes actually
+received ("server can return one byte more due to implied bcc[0]").
+This was introduced to accommodate servers that omit the trailing bcc[0]
+overlap byte when no data area is present.
+
+However, the exemption is applied unconditionally, regardless of whether
+the command actually carries a data area (has_smb2_data_area[]).  When a
+response with a data area is subject to the +1 exemption, the reported
+data can extend one byte beyond the bytes actually received, yet
+smb2_check_message() still accepts it.  The subsequent decoder then reads
+past the end of the receive buffer.  This is reachable during NEGOTIATE
+and SESSION_SETUP, before the session is established.
+
+The resulting out-of-bounds reads are visible under KASAN when mounting
+against a non-conforming server; both the SPNEGO/negTokenInit and the
+NTLMSSP challenge decoders are affected:
+
+  BUG: KASAN: slab-out-of-bounds in asn1_ber_decoder+0x16a7/0x1b00
+  Read of size 1 at addr ffff8880084d67c0 by task mount.cifs/81
+  CPU: 1 UID: 0 PID: 81 Comm: mount.cifs Not tainted 7.1.0-rc6 #1
+  Call Trace:
+   <TASK>
+   dump_stack_lvl+0x4e/0x70
+   print_report+0x157/0x4c9
+   kasan_report+0xce/0x100
+   asn1_ber_decoder+0x16a7/0x1b00
+   decode_negTokenInit+0x19/0x30
+   SMB2_negotiate+0x31d9/0x4c90
+   cifs_negotiate_protocol+0x1f2/0x3f0
+   cifs_get_smb_ses+0x93f/0x17e0
+   cifs_mount_get_session+0x7f/0x3a0
+   cifs_mount+0xb4/0xcf0
+   cifs_smb3_do_mount+0x23a/0x1500
+   smb3_get_tree+0x3b0/0x630
+   vfs_get_tree+0x82/0x2d0
+   fc_mount+0x10/0x1b0
+   path_mount+0x50d/0x1de0
+   __x64_sys_mount+0x20b/0x270
+   do_syscall_64+0xee/0x590
+   entry_SYSCALL_64_after_hwframe+0x77/0x7f
+   </TASK>
+  Allocated by task 85:
+   kmem_cache_alloc_noprof+0x106/0x380
+   mempool_alloc_noprof+0x116/0x1e0
+   cifs_small_buf_get+0x31/0x80
+   allocate_buffers+0x10d/0x2b0
+   cifs_demultiplex_thread+0x1d5/0x1d50
+   kthread+0x2c6/0x390
+   ret_from_fork+0x36e/0x5a0
+   ret_from_fork_asm+0x1a/0x30
+  The buggy address is located 0 bytes to the right of
+   allocated 448-byte region [ffff8880084d6600, ffff8880084d67c0)
+   which belongs to the cache cifs_small_rq of size 448
+
+  BUG: KASAN: slab-out-of-bounds in kmemdup_noprof+0x36/0x50
+  Read of size 329 at addr ffff88800726c678 by task mount.cifs/89
+  CPU: 0 UID: 0 PID: 89 Comm: mount.cifs Tainted: G    B      7.1.0-rc6 #1
+  Call Trace:
+   <TASK>
+   dump_stack_lvl+0x4e/0x70
+   print_report+0x157/0x4c9
+   kasan_report+0xce/0x100
+   kasan_check_range+0x10f/0x1e0
+   __asan_memcpy+0x23/0x60
+   kmemdup_noprof+0x36/0x50
+   decode_ntlmssp_challenge+0x457/0x680
+   SMB2_sess_auth_rawntlmssp_negotiate+0x6f0/0xcb0
+   SMB2_sess_setup+0x219/0x4f0
+   cifs_setup_session+0x248/0xaf0
+   cifs_get_smb_ses+0xf79/0x17e0
+   cifs_mount_get_session+0x7f/0x3a0
+   cifs_mount+0xb4/0xcf0
+   cifs_smb3_do_mount+0x23a/0x1500
+   smb3_get_tree+0x3b0/0x630
+   vfs_get_tree+0x82/0x2d0
+   fc_mount+0x10/0x1b0
+   path_mount+0x50d/0x1de0
+   __x64_sys_mount+0x20b/0x270
+   do_syscall_64+0xee/0x590
+   entry_SYSCALL_64_after_hwframe+0x77/0x7f
+   </TASK>
+  Allocated by task 93:
+   kmem_cache_alloc_noprof+0x106/0x380
+   mempool_alloc_noprof+0x116/0x1e0
+   cifs_small_buf_get+0x31/0x80
+   allocate_buffers+0x10d/0x2b0
+   cifs_demultiplex_thread+0x1d5/0x1d50
+   kthread+0x2c6/0x390
+   ret_from_fork+0x36e/0x5a0
+   ret_from_fork_asm+0x1a/0x30
+  The buggy address is located 120 bytes inside of
+   allocated 448-byte region [ffff88800726c600, ffff88800726c7c0)
+   which belongs to the cache cifs_small_rq of size 448
+
+Restrict the +1 exemption to responses that have no data area, so that
+it still covers the bcc[0] omission it was meant for.  When a data area
+is present, the +1 discrepancy instead means the reported data length
+overruns the received buffer, so the response must be rejected.
+
+Fixes: 093b2bdad322 ("CIFS: Make demultiplex_thread work with SMB2 code")
+Cc: stable@vger.kernel.org
+Signed-off-by: Shoichiro Miyamoto <shoichiro.miyamoto@gmail.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/smb2misc.c |   32 ++++++++++++++++++++++++++------
+ 1 file changed, 26 insertions(+), 6 deletions(-)
+
+--- a/fs/cifs/smb2misc.c
++++ b/fs/cifs/smb2misc.c
+@@ -30,6 +30,8 @@
+ #include "smb2glob.h"
+ #include "nterr.h"
++static unsigned int __smb2_calc_size(void *buf, bool *have_data);
++
+ static int
+ check_smb2_hdr(struct smb2_hdr *shdr, __u64 mid)
+ {
+@@ -145,6 +147,7 @@ smb2_check_message(char *buf, unsigned i
+       int command;
+       __u32 calc_len; /* calculated length */
+       __u64 mid;
++      bool have_data;
+       /*
+        * Add function to do table lookup of StructureSize by command
+@@ -225,7 +228,8 @@ smb2_check_message(char *buf, unsigned i
+               }
+       }
+-      calc_len = smb2_calc_size(buf);
++      have_data = false;
++      calc_len = __smb2_calc_size(buf, &have_data);
+       /* For SMB2_IOCTL, OutputOffset and OutputLength are optional, so might
+        * be 0, and not a real miscalculation */
+@@ -243,8 +247,13 @@ smb2_check_message(char *buf, unsigned i
+               /* Windows 7 server returns 24 bytes more */
+               if (calc_len + 24 == len && command == SMB2_OPLOCK_BREAK_HE)
+                       return 0;
+-              /* server can return one byte more due to implied bcc[0] */
+-              if (calc_len == len + 1)
++              /*
++               * Server can return one byte more due to implied bcc[0].
++               * Allow it only when there is no data area; if data_length > 0
++               * the +1 gap indicates an overreported data length rather than
++               * the bcc[0] omission.
++               */
++              if (calc_len == len + 1 && !have_data)
+                       return 0;
+               /*
+@@ -405,14 +414,17 @@ smb2_get_data_area_len(int *off, int *le
+ /*
+  * Calculate the size of the SMB message based on the fixed header
+  * portion, the number of word parameters and the data portion of the message.
++ * If have_data is non-NULL, it is set to true when a non-empty data area was
++ * found (data_length > 0), allowing callers to distinguish the implied bcc[0]
++ * case (no data area) from an overreported data length.
+  */
+-unsigned int
+-smb2_calc_size(void *buf)
++static unsigned int
++__smb2_calc_size(void *buf, bool *have_data)
+ {
+       struct smb2_pdu *pdu = (struct smb2_pdu *)buf;
+       struct smb2_hdr *shdr = &pdu->hdr;
+       int offset; /* the offset from the beginning of SMB to data area */
+-      int data_length; /* the length of the variable length data area */
++      int data_length = 0; /* the length of the variable length data area */
+       /* Structure Size has already been checked to make sure it is 64 */
+       int len = le16_to_cpu(shdr->StructureSize);
+@@ -445,9 +457,17 @@ smb2_calc_size(void *buf)
+       }
+ calc_size_exit:
+       cifs_dbg(FYI, "SMB2 len %d\n", len);
++      if (have_data)
++              *have_data = (data_length > 0);
+       return len;
+ }
++unsigned int
++smb2_calc_size(void *buf)
++{
++      return __smb2_calc_size(buf, NULL);
++}
++
+ /* Note: caller must free return buffer */
+ __le16 *
+ cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb)
diff --git a/queue-5.10/smb-client-use-unaligned-reads-in-parse_posix_ctxt.patch b/queue-5.10/smb-client-use-unaligned-reads-in-parse_posix_ctxt.patch
new file mode 100644 (file)
index 0000000..806d130
--- /dev/null
@@ -0,0 +1,42 @@
+From stable+bounces-276772-greg=kroah.com@vger.kernel.org Thu Jul 16 18:33:52 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jul 2026 12:28:10 -0400
+Subject: smb: client: use unaligned reads in parse_posix_ctxt()
+To: stable@vger.kernel.org
+Cc: Zihan Xi <xizh2024@lzu.edu.cn>, Ren Wei <n05ec@lzu.edu.cn>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260716162810.635369-1-sashal@kernel.org>
+
+From: Zihan Xi <xizh2024@lzu.edu.cn>
+
+[ Upstream commit b86467cd2691192ad4809a5a6e922fc24b8e9839 ]
+
+The server controls create-context DataOffset, so the POSIX context data
+pointer may be misaligned on strict-alignment architectures. Use
+get_unaligned_le32() when reading nlink, reparse_tag, and mode.
+
+Fixes: 69dda3059e7a ("cifs: add SMB2_open() arg to return POSIX data")
+Cc: stable@vger.kernel.org
+Signed-off-by: Zihan Xi <xizh2024@lzu.edu.cn>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/smb2pdu.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -1973,9 +1973,9 @@ parse_posix_ctxt(struct create_context *
+       memset(posix, 0, sizeof(*posix));
+-      posix->nlink = le32_to_cpu(*(__le32 *)(beg + 0));
+-      posix->reparse_tag = le32_to_cpu(*(__le32 *)(beg + 4));
+-      posix->mode = le32_to_cpu(*(__le32 *)(beg + 8));
++      posix->nlink = get_unaligned_le32(beg);
++      posix->reparse_tag = get_unaligned_le32(beg + 4);
++      posix->mode = get_unaligned_le32(beg + 8);
+       sid = beg + 12;
+       sid_len = posix_info_sid_size(sid, end);
diff --git a/queue-5.10/smb2-small-refactor-in-smb2_check_message.patch b/queue-5.10/smb2-small-refactor-in-smb2_check_message.patch
new file mode 100644 (file)
index 0000000..06ffdb3
--- /dev/null
@@ -0,0 +1,168 @@
+From stable+bounces-274569-greg=kroah.com@vger.kernel.org Wed Jul 15 00:04:16 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 18:04:03 -0400
+Subject: smb2: small refactor in smb2_check_message()
+To: stable@vger.kernel.org
+Cc: Enzo Matsumiya <ematsumiya@suse.de>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714220405.3333589-3-sashal@kernel.org>
+
+From: Enzo Matsumiya <ematsumiya@suse.de>
+
+[ Upstream commit da3847894fddc27ca95d5ac0012f444a77a5e0c3 ]
+
+If the command is SMB2_IOCTL, OutputLength and OutputContext are
+optional and can be zero, so return early and skip calculated length
+check.
+
+Move the mismatched length message to the end of the check, to avoid
+unnecessary logs when the check was not a real miscalculation.
+
+Also change the pr_warn_once() to a pr_warn() so we're sure to get a
+log for the real mismatches.
+
+Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 53b7c271f06b ("smb: client: restrict implied bcc[0] exemption to responses without data area")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/connect.c  |   13 ++++++-------
+ fs/cifs/smb2misc.c |   47 ++++++++++++++++++++++++++++-------------------
+ 2 files changed, 34 insertions(+), 26 deletions(-)
+
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -1012,19 +1012,18 @@ int
+ cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
+ {
+       char *buf = server->large_buf ? server->bigbuf : server->smallbuf;
+-      int length;
++      int rc;
+       /*
+        * We know that we received enough to get to the MID as we
+        * checked the pdu_length earlier. Now check to see
+-       * if the rest of the header is OK. We borrow the length
+-       * var for the rest of the loop to avoid a new stack var.
++       * if the rest of the header is OK.
+        *
+        * 48 bytes is enough to display the header and a little bit
+        * into the payload for debugging purposes.
+        */
+-      length = server->ops->check_message(buf, server->total_read, server);
+-      if (length != 0)
++      rc = server->ops->check_message(buf, server->total_read, server);
++      if (rc)
+               cifs_dump_mem("Bad SMB: ", buf,
+                       min_t(unsigned int, server->total_read, 48));
+@@ -1039,9 +1038,9 @@ cifs_handle_standard(struct TCP_Server_I
+               return -1;
+       if (!mid)
+-              return length;
++              return rc;
+-      handle_mid(mid, server, buf, length);
++      handle_mid(mid, server, buf, rc);
+       return 0;
+ }
+--- a/fs/cifs/smb2misc.c
++++ b/fs/cifs/smb2misc.c
+@@ -136,15 +136,15 @@ static __u32 get_neg_ctxt_len(struct smb
+ }
+ int
+-smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr)
++smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server)
+ {
+       struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
+       struct smb2_pdu *pdu = (struct smb2_pdu *)shdr;
+-      __u64 mid;
+-      __u32 clc_len;  /* calculated length */
+-      int command;
+-      int pdu_size = sizeof(struct smb2_pdu);
+       int hdr_size = sizeof(struct smb2_hdr);
++      int pdu_size = sizeof(struct smb2_pdu);
++      int command;
++      __u32 calc_len; /* calculated length */
++      __u64 mid;
+       /*
+        * Add function to do table lookup of StructureSize by command
+@@ -158,7 +158,7 @@ smb2_check_message(char *buf, unsigned i
+               /* decrypt frame now that it is completely read in */
+               spin_lock(&cifs_tcp_ses_lock);
+-              list_for_each_entry(iter, &srvr->smb_ses_list, smb_ses_list) {
++              list_for_each_entry(iter, &server->smb_ses_list, smb_ses_list) {
+                       if (iter->Suid == le64_to_cpu(thdr->SessionId)) {
+                               ses = iter;
+                               break;
+@@ -225,30 +225,33 @@ smb2_check_message(char *buf, unsigned i
+               }
+       }
+-      clc_len = smb2_calc_size(buf, srvr);
++      calc_len = smb2_calc_size(buf, server);
++
++      /* For SMB2_IOCTL, OutputOffset and OutputLength are optional, so might
++       * be 0, and not a real miscalculation */
++      if (command == SMB2_IOCTL_HE && calc_len == 0)
++              return 0;
+-      if (shdr->Command == SMB2_NEGOTIATE)
+-              clc_len += get_neg_ctxt_len(shdr, len, clc_len);
++      if (command == SMB2_NEGOTIATE_HE)
++              calc_len += get_neg_ctxt_len(shdr, len, calc_len);
+-      if (len != clc_len) {
+-              cifs_dbg(FYI, "Calculated size %u length %u mismatch mid %llu\n",
+-                       clc_len, len, mid);
++      if (len != calc_len) {
+               /* create failed on symlink */
+               if (command == SMB2_CREATE_HE &&
+                   shdr->Status == STATUS_STOPPED_ON_SYMLINK)
+                       return 0;
+               /* Windows 7 server returns 24 bytes more */
+-              if (clc_len + 24 == len && command == SMB2_OPLOCK_BREAK_HE)
++              if (calc_len + 24 == len && command == SMB2_OPLOCK_BREAK_HE)
+                       return 0;
+               /* server can return one byte more due to implied bcc[0] */
+-              if (clc_len == len + 1)
++              if (calc_len == len + 1)
+                       return 0;
+               /*
+                * Some windows servers (win2016) will pad also the final
+                * PDU in a compound to 8 bytes.
+                */
+-              if (((clc_len + 7) & ~7) == len)
++              if (((calc_len + 7) & ~7) == len)
+                       return 0;
+               /*
+@@ -257,12 +260,18 @@ smb2_check_message(char *buf, unsigned i
+                * SMB2/SMB3 frame length (header + smb2 response specific data)
+                * Some windows servers also pad up to 8 bytes when compounding.
+                */
+-              if (clc_len < len)
++              if (calc_len < len)
+                       return 0;
+-              pr_warn_once(
+-                      "srv rsp too short, len %d not %d. cmd:%d mid:%llu\n",
+-                      len, clc_len, command, mid);
++              /* Only log a message if len was really miscalculated */
++              if (unlikely(cifsFYI))
++                      cifs_dbg(FYI, "Server response too short: calculated "
++                               "length %u doesn't match read length %u (cmd=%d, mid=%llu)\n",
++                               calc_len, len, command, mid);
++              else
++                      pr_warn("Server response too short: calculated length "
++                              "%u doesn't match read length %u (cmd=%d, mid=%llu)\n",
++                              calc_len, len, command, mid);
+               return 1;
+       }
diff --git a/queue-5.10/staging-media-atomisp-reduce-load_primary_binaries-stack-usage.patch b/queue-5.10/staging-media-atomisp-reduce-load_primary_binaries-stack-usage.patch
new file mode 100644 (file)
index 0000000..b5c5a99
--- /dev/null
@@ -0,0 +1,64 @@
+From stable+bounces-274529-greg=kroah.com@vger.kernel.org Tue Jul 14 22:02:23 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 16:01:58 -0400
+Subject: staging: media: atomisp: reduce load_primary_binaries() stack usage
+To: stable@vger.kernel.org
+Cc: Arnd Bergmann <arnd@arndb.de>, Andy Shevchenko <andriy.shevchenko@intel.com>, Sakari Ailus <sakari.ailus@linux.intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714200158.3152137-6-sashal@kernel.org>
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit f4d51e55dd47ef467fbe37d8575e20eee41b092d ]
+
+The load_primary_binaries() function is overly complex and has som large
+variables on the stack, which can cause warnings depending on CONFIG_FRAME_WARN
+setting:
+
+drivers/staging/media/atomisp/pci/sh_css.c: In function 'load_primary_binaries':
+drivers/staging/media/atomisp/pci/sh_css.c:5260:1: error: the frame size of 1560 bytes is larger than 1536 bytes [-Werror=frame-larger-than=]
+
+Half of the stack usage is for the prim_descr[] array, but only one
+member of the array is used at any given time.
+
+Reduce the stack usage by turning the array into a single structure.
+
+Fixes: a49d25364dfb ("staging/atomisp: Add support for the Intel IPU v2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/media/atomisp/pci/sh_css.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/staging/media/atomisp/pci/sh_css.c
++++ b/drivers/staging/media/atomisp/pci/sh_css.c
+@@ -5870,7 +5870,6 @@ static int load_primary_binaries(
+       struct ia_css_capture_settings *mycs;
+       unsigned int i;
+       bool need_extra_yuv_scaler = false;
+-      struct ia_css_binary_descr prim_descr[MAX_NUM_PRIMARY_STAGES];
+       IA_CSS_ENTER_PRIVATE("");
+       assert(pipe);
+@@ -6058,15 +6057,16 @@ static int load_primary_binaries(
+       /* Primary */
+       for (i = 0; i < mycs->num_primary_stage; i++) {
++              struct ia_css_binary_descr prim_descr;
+               struct ia_css_frame_info *local_vf_info = NULL;
+               if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0] &&
+                   (i == mycs->num_primary_stage - 1))
+                       local_vf_info = &vf_info;
+-              ia_css_pipe_get_primary_binarydesc(pipe, &prim_descr[i],
++              ia_css_pipe_get_primary_binarydesc(pipe, &prim_descr,
+                                                  &prim_in_info, &prim_out_info,
+                                                  local_vf_info, i);
+-              err = ia_css_binary_find(&prim_descr[i], &mycs->primary_binary[i]);
++              err = ia_css_binary_find(&prim_descr, &mycs->primary_binary[i]);
+               if (err) {
+                       IA_CSS_LEAVE_ERR_PRIVATE(err);
+                       return err;
diff --git a/queue-5.10/staging-rtl8723bs-clean-up-comparsions-to-null.patch b/queue-5.10/staging-rtl8723bs-clean-up-comparsions-to-null.patch
new file mode 100644 (file)
index 0000000..2a9f11a
--- /dev/null
@@ -0,0 +1,1042 @@
+From stable+bounces-274606-greg=kroah.com@vger.kernel.org Wed Jul 15 01:34:46 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 19:34:06 -0400
+Subject: staging: rtl8723bs: clean up comparsions to NULL
+To: stable@vger.kernel.org
+Cc: Michael Straube <straube.linux@gmail.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714233407.3591885-7-sashal@kernel.org>
+
+From: Michael Straube <straube.linux@gmail.com>
+
+[ Upstream commit cd1f1450092216b3e39516f8db58869b6fc20575 ]
+
+Clean up comparsions to NULL reported by checkpatch.
+
+x == NULL -> !x
+x != NULL -> x
+
+Signed-off-by: Michael Straube <straube.linux@gmail.com>
+Link: https://lore.kernel.org/r/20210829154533.11054-1-straube.linux@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a1fc19d61f66 ("staging: rtl8723bs: fix WEP length underflow and OOB read in OnAuth()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_ap.c           |   20 ++--
+ drivers/staging/rtl8723bs/core/rtw_cmd.c          |   96 +++++++++++-----------
+ drivers/staging/rtl8723bs/core/rtw_ioctl_set.c    |    4 
+ drivers/staging/rtl8723bs/core/rtw_mlme.c         |    6 -
+ drivers/staging/rtl8723bs/core/rtw_mlme_ext.c     |   56 ++++++------
+ drivers/staging/rtl8723bs/core/rtw_security.c     |    6 -
+ drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c |   24 ++---
+ drivers/staging/rtl8723bs/os_dep/ioctl_linux.c    |   18 ++--
+ drivers/staging/rtl8723bs/os_dep/os_intfs.c       |    4 
+ 9 files changed, 117 insertions(+), 117 deletions(-)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_ap.c
++++ b/drivers/staging/rtl8723bs/core/rtw_ap.c
+@@ -1033,7 +1033,7 @@ int rtw_check_beacon_data(struct adapter
+               &ie_len,
+               (pbss_network->IELength - _BEACON_IE_OFFSET_)
+       );
+-      if (p !=  NULL) {
++      if (p) {
+               memcpy(supportRate, p + 2, ie_len);
+               supportRateNum = ie_len;
+       }
+@@ -1045,7 +1045,7 @@ int rtw_check_beacon_data(struct adapter
+               &ie_len,
+               pbss_network->IELength - _BEACON_IE_OFFSET_
+       );
+-      if (p !=  NULL) {
++      if (p) {
+               memcpy(supportRate + supportRateNum, p + 2, ie_len);
+               supportRateNum += ie_len;
+       }
+@@ -1133,7 +1133,7 @@ int rtw_check_beacon_data(struct adapter
+                       break;
+               }
+-              if ((p == NULL) || (ie_len == 0))
++              if (!p || ie_len == 0)
+                               break;
+       }
+@@ -1162,7 +1162,7 @@ int rtw_check_beacon_data(struct adapter
+                               break;
+                       }
+-                      if ((p == NULL) || (ie_len == 0))
++                      if (!p || ie_len == 0)
+                               break;
+               }
+       }
+@@ -1290,7 +1290,7 @@ int rtw_check_beacon_data(struct adapter
+       psta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress);
+       if (!psta) {
+               psta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress);
+-              if (psta == NULL)
++              if (!psta)
+                       return _FAIL;
+       }
+@@ -1447,7 +1447,7 @@ u8 rtw_ap_set_pairwise_key(struct adapte
+       }
+       psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm));
+-      if (psetstakey_para == NULL) {
++      if (!psetstakey_para) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -1485,12 +1485,12 @@ static int rtw_ap_set_key(
+       /* DBG_871X("%s\n", __func__); */
+       pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (pcmd == NULL) {
++      if (!pcmd) {
+               res = _FAIL;
+               goto exit;
+       }
+       psetkeyparm = rtw_zmalloc(sizeof(struct setkey_parm));
+-      if (psetkeyparm == NULL) {
++      if (!psetkeyparm) {
+               kfree(pcmd);
+               res = _FAIL;
+               goto exit;
+@@ -1662,11 +1662,11 @@ static void update_bcn_wps_ie(struct ada
+               &wps_ielen
+       );
+-      if (pwps_ie == NULL || wps_ielen == 0)
++      if (!pwps_ie || wps_ielen == 0)
+               return;
+       pwps_ie_src = pmlmepriv->wps_beacon_ie;
+-      if (pwps_ie_src == NULL)
++      if (!pwps_ie_src)
+               return;
+       wps_offset = (uint)(pwps_ie - ie);
+--- a/drivers/staging/rtl8723bs/core/rtw_cmd.c
++++ b/drivers/staging/rtl8723bs/core/rtw_cmd.c
+@@ -259,7 +259,7 @@ int _rtw_enqueue_cmd(struct __queue *que
+ {
+       _irqL irqL;
+-      if (obj == NULL)
++      if (!obj)
+               goto exit;
+       /* spin_lock_bh(&queue->lock); */
+@@ -335,7 +335,7 @@ int rtw_enqueue_cmd(struct cmd_priv *pcm
+       int res = _FAIL;
+       struct adapter *padapter = pcmdpriv->padapter;
+-      if (cmd_obj == NULL) {
++      if (!cmd_obj) {
+               goto exit;
+       }
+@@ -509,7 +509,7 @@ post_process:
+               /* call callback function for post-processed */
+               if (pcmd->cmdcode < ARRAY_SIZE(rtw_cmd_callback)) {
+                       pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback;
+-                      if (pcmd_callback == NULL) {
++                      if (!pcmd_callback) {
+                               RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("mlme_cmd_hdl(): pcmd_callback = 0x%p, cmdcode = 0x%x\n", pcmd_callback, pcmd->cmdcode));
+                               rtw_free_cmd_obj(pcmd);
+                       } else {
+@@ -530,7 +530,7 @@ post_process:
+       /*  free all cmd_obj resources */
+       do {
+               pcmd = rtw_dequeue_cmd(pcmdpriv);
+-              if (pcmd == NULL) {
++              if (!pcmd) {
+                       rtw_unregister_cmd_alive(padapter);
+                       break;
+               }
+@@ -572,11 +572,11 @@ u8 rtw_sitesurvey_cmd(struct adapter  *p
+       }
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL)
++      if (!ph2c)
+               return _FAIL;
+       psurveyPara = rtw_zmalloc(sizeof(struct sitesurvey_parm));
+-      if (psurveyPara == NULL) {
++      if (!psurveyPara) {
+               kfree(ph2c);
+               return _FAIL;
+       }
+@@ -640,13 +640,13 @@ u8 rtw_setdatarate_cmd(struct adapter *p
+       u8 res = _SUCCESS;
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       pbsetdataratepara = rtw_zmalloc(sizeof(struct setdatarate_parm));
+-      if (pbsetdataratepara == NULL) {
++      if (!pbsetdataratepara) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -683,7 +683,7 @@ u8 rtw_createbss_cmd(struct adapter  *pa
+       }
+       pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (pcmd == NULL) {
++      if (!pcmd) {
+               res = _FAIL;
+               goto exit;
+       }
+@@ -716,7 +716,7 @@ int rtw_startbss_cmd(struct adapter  *pa
+       } else {
+               /* need enqueue, prepare cmd_obj and enqueue */
+               pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
+-              if (pcmd == NULL) {
++              if (!pcmd) {
+                       res = _FAIL;
+                       goto exit;
+               }
+@@ -774,7 +774,7 @@ u8 rtw_joinbss_cmd(struct adapter  *pada
+       }
+       pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (pcmd == NULL) {
++      if (!pcmd) {
+               res = _FAIL;
+               RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd: memory allocate for cmd_obj fail!!!\n"));
+               goto exit;
+@@ -891,7 +891,7 @@ u8 rtw_disassoc_cmd(struct adapter *pada
+       /* prepare cmd parameter */
+       param = rtw_zmalloc(sizeof(*param));
+-      if (param == NULL) {
++      if (!param) {
+               res = _FAIL;
+               goto exit;
+       }
+@@ -900,7 +900,7 @@ u8 rtw_disassoc_cmd(struct adapter *pada
+       if (enqueue) {
+               /* need enqueue, prepare cmd_obj and enqueue */
+               cmdobj = rtw_zmalloc(sizeof(*cmdobj));
+-              if (cmdobj == NULL) {
++              if (!cmdobj) {
+                       res = _FAIL;
+                       kfree(param);
+                       goto exit;
+@@ -928,7 +928,7 @@ u8 rtw_setopmode_cmd(struct adapter  *pa
+       psetop = rtw_zmalloc(sizeof(struct setopmode_parm));
+-      if (psetop == NULL) {
++      if (!psetop) {
+               res = _FAIL;
+               goto exit;
+       }
+@@ -936,7 +936,7 @@ u8 rtw_setopmode_cmd(struct adapter  *pa
+       if (enqueue) {
+               ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-              if (ph2c == NULL) {
++              if (!ph2c) {
+                       kfree(psetop);
+                       res = _FAIL;
+                       goto exit;
+@@ -964,7 +964,7 @@ u8 rtw_setstakey_cmd(struct adapter *pad
+       u8 res = _SUCCESS;
+       psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm));
+-      if (psetstakey_para == NULL) {
++      if (!psetstakey_para) {
+               res = _FAIL;
+               goto exit;
+       }
+@@ -988,14 +988,14 @@ u8 rtw_setstakey_cmd(struct adapter *pad
+       if (enqueue) {
+               ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-              if (ph2c == NULL) {
++              if (!ph2c) {
+                       kfree(psetstakey_para);
+                       res = _FAIL;
+                       goto exit;
+               }
+               psetstakey_rsp = rtw_zmalloc(sizeof(struct set_stakey_rsp));
+-              if (psetstakey_rsp == NULL) {
++              if (!psetstakey_rsp) {
+                       kfree(ph2c);
+                       kfree(psetstakey_para);
+                       res = _FAIL;
+@@ -1031,20 +1031,20 @@ u8 rtw_clearstakey_cmd(struct adapter *p
+               }
+       } else {
+               ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-              if (ph2c == NULL) {
++              if (!ph2c) {
+                       res = _FAIL;
+                       goto exit;
+               }
+               psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm));
+-              if (psetstakey_para == NULL) {
++              if (!psetstakey_para) {
+                       kfree(ph2c);
+                       res = _FAIL;
+                       goto exit;
+               }
+               psetstakey_rsp = rtw_zmalloc(sizeof(struct set_stakey_rsp));
+-              if (psetstakey_rsp == NULL) {
++              if (!psetstakey_rsp) {
+                       kfree(ph2c);
+                       kfree(psetstakey_para);
+                       res = _FAIL;
+@@ -1076,13 +1076,13 @@ u8 rtw_addbareq_cmd(struct adapter *pada
+       u8 res = _SUCCESS;
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       paddbareq_parm = rtw_zmalloc(sizeof(struct addBaReq_parm));
+-      if (paddbareq_parm == NULL) {
++      if (!paddbareq_parm) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -1110,13 +1110,13 @@ u8 rtw_reset_securitypriv_cmd(struct ada
+       u8 res = _SUCCESS;
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+-      if (pdrvextra_cmd_parm == NULL) {
++      if (!pdrvextra_cmd_parm) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -1145,13 +1145,13 @@ u8 rtw_free_assoc_resources_cmd(struct a
+       u8 res = _SUCCESS;
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+-      if (pdrvextra_cmd_parm == NULL) {
++      if (!pdrvextra_cmd_parm) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -1181,13 +1181,13 @@ u8 rtw_dynamic_chk_wk_cmd(struct adapter
+       /* only  primary padapter does this cmd */
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+-      if (pdrvextra_cmd_parm == NULL) {
++      if (!pdrvextra_cmd_parm) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -1231,7 +1231,7 @@ u8 rtw_set_chplan_cmd(struct adapter *pa
+       /* prepare cmd parameter */
+       setChannelPlan_param = rtw_zmalloc(sizeof(struct SetChannelPlan_param));
+-      if (setChannelPlan_param == NULL) {
++      if (!setChannelPlan_param) {
+               res = _FAIL;
+               goto exit;
+       }
+@@ -1240,7 +1240,7 @@ u8 rtw_set_chplan_cmd(struct adapter *pa
+       if (enqueue) {
+               /* need enqueue, prepare cmd_obj and enqueue */
+               pcmdobj = rtw_zmalloc(sizeof(struct cmd_obj));
+-              if (pcmdobj == NULL) {
++              if (!pcmdobj) {
+                       kfree(setChannelPlan_param);
+                       res = _FAIL;
+                       goto exit;
+@@ -1501,13 +1501,13 @@ u8 rtw_lps_ctrl_wk_cmd(struct adapter *p
+       if (enqueue) {
+               ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-              if (ph2c == NULL) {
++              if (!ph2c) {
+                       res = _FAIL;
+                       goto exit;
+               }
+               pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+-              if (pdrvextra_cmd_parm == NULL) {
++              if (!pdrvextra_cmd_parm) {
+                       kfree(ph2c);
+                       res = _FAIL;
+                       goto exit;
+@@ -1543,13 +1543,13 @@ u8 rtw_dm_in_lps_wk_cmd(struct adapter *
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+-      if (pdrvextra_cmd_parm == NULL) {
++      if (!pdrvextra_cmd_parm) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -1616,13 +1616,13 @@ u8 rtw_dm_ra_mask_wk_cmd(struct adapter
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+-      if (pdrvextra_cmd_parm == NULL) {
++      if (!pdrvextra_cmd_parm) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -1651,13 +1651,13 @@ u8 rtw_ps_cmd(struct adapter *padapter)
+       u8 res = _SUCCESS;
+       ppscmd = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ppscmd == NULL) {
++      if (!ppscmd) {
+               res = _FAIL;
+               goto exit;
+       }
+       pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+-      if (pdrvextra_cmd_parm == NULL) {
++      if (!pdrvextra_cmd_parm) {
+               kfree(ppscmd);
+               res = _FAIL;
+               goto exit;
+@@ -1723,13 +1723,13 @@ u8 rtw_chk_hi_queue_cmd(struct adapter *
+       u8 res = _SUCCESS;
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+-      if (pdrvextra_cmd_parm == NULL) {
++      if (!pdrvextra_cmd_parm) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -1817,13 +1817,13 @@ u8 rtw_c2h_packet_wk_cmd(struct adapter
+       u8 res = _SUCCESS;
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+-      if (pdrvextra_cmd_parm == NULL) {
++      if (!pdrvextra_cmd_parm) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -1852,13 +1852,13 @@ u8 rtw_c2h_wk_cmd(struct adapter *padapt
+       u8 res = _SUCCESS;
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+-      if (pdrvextra_cmd_parm == NULL) {
++      if (!pdrvextra_cmd_parm) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -2036,7 +2036,7 @@ void rtw_createbss_cmd_callback(struct a
+       struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)pcmd->parmbuf;
+       struct wlan_network *tgt_network = &(pmlmepriv->cur_network);
+-      if (pcmd->parmbuf == NULL)
++      if (!pcmd->parmbuf)
+               goto exit;
+       if ((pcmd->res != H2C_SUCCESS)) {
+@@ -2063,9 +2063,9 @@ void rtw_createbss_cmd_callback(struct a
+       } else {
+               pwlan = rtw_alloc_network(pmlmepriv);
+               spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
+-              if (pwlan == NULL) {
++              if (!pwlan) {
+                       pwlan = rtw_get_oldest_wlan_network(&pmlmepriv->scanned_queue);
+-                      if (pwlan == NULL) {
++                      if (!pwlan) {
+                               RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n Error:  can't get pwlan in rtw_joinbss_event_callback\n"));
+                               spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
+                               goto createbss_cmd_fail;
+--- a/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c
++++ b/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c
+@@ -508,7 +508,7 @@ u8 rtw_set_802_11_bssid_list_scan(struct
+       RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("+rtw_set_802_11_bssid_list_scan(), fw_state =%x\n", get_fwstate(pmlmepriv)));
+-      if (padapter == NULL) {
++      if (!padapter) {
+               res = false;
+               goto exit;
+       }
+@@ -649,7 +649,7 @@ u16 rtw_get_cur_max_rate(struct adapter
+               return 0;
+       psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
+-      if (psta == NULL)
++      if (!psta)
+               return 0;
+       short_GI = query_ra_short_GI(psta);
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c
+@@ -472,7 +472,7 @@ struct     wlan_network    *rtw_get_oldest_wlan
+               pwlan = LIST_CONTAINOR(plist, struct wlan_network, list);
+               if (!pwlan->fixed) {
+-                      if (oldest == NULL || time_after(oldest->last_scanned, pwlan->last_scanned))
++                      if (!oldest || time_after(oldest->last_scanned, pwlan->last_scanned))
+                               oldest = pwlan;
+               }
+@@ -603,7 +603,7 @@ void rtw_update_scanned_network(struct a
+                       /* TODO: don't  select netowrk in the same ess as oldest if it's new enough*/
+               }
+-              if (oldest == NULL || time_after(oldest->last_scanned, pnetwork->last_scanned))
++              if (!oldest || time_after(oldest->last_scanned, pnetwork->last_scanned))
+                       oldest = pnetwork;
+               plist = get_next(plist);
+@@ -2023,7 +2023,7 @@ static int rtw_check_join_candidate(stru
+                       goto exit;
+       }
+-      if (*candidate == NULL || (*candidate)->network.Rssi < competitor->network.Rssi) {
++      if (!*candidate || (*candidate)->network.Rssi < competitor->network.Rssi) {
+               *candidate = competitor;
+               updated = true;
+       }
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+@@ -934,12 +934,12 @@ unsigned int OnAuth(struct adapter *pada
+       }
+       pstat = rtw_get_stainfo(pstapriv, sa);
+-      if (pstat == NULL) {
++      if (!pstat) {
+               /*  allocate a new one */
+               DBG_871X("going to alloc stainfo for sa ="MAC_FMT"\n",  MAC_ARG(sa));
+               pstat = rtw_alloc_stainfo(pstapriv, sa);
+-              if (pstat == NULL) {
++              if (!pstat) {
+                       DBG_871X(" Exceed the upper limit of supported clients...\n");
+                       status = _STATS_UNABLE_HANDLE_STA_;
+                       goto auth_fail;
+@@ -1014,7 +1014,7 @@ unsigned int OnAuth(struct adapter *pada
+                       p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&ie_len,
+                                       len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
+-                      if ((p == NULL) || (ie_len <= 0)) {
++                      if (!p || ie_len <= 0) {
+                               DBG_871X("auth rejected because challenge failure!(1)\n");
+                               status = _STATS_CHALLENGE_FAIL_;
+                               goto auth_fail;
+@@ -1255,7 +1255,7 @@ unsigned int OnAssocReq(struct adapter *
+       /*  check if the supported rate is ok */
+       p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
+-      if (p == NULL) {
++      if (!p) {
+               DBG_871X("Rx a sta assoc-req which supported rate is empty!\n");
+               /*  use our own rate set as statoin used */
+               /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
+@@ -1272,7 +1272,7 @@ unsigned int OnAssocReq(struct adapter *
+               p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _EXT_SUPPORTEDRATES_IE_, &ie_len,
+                               pkt_len - WLAN_HDR_A3_LEN - ie_offset);
+-              if (p !=  NULL) {
++              if (p) {
+                       if (supportRateNum + ie_len <= sizeof(supportRate)) {
+                               memcpy(supportRate+supportRateNum, p+2, ie_len);
+@@ -1538,7 +1538,7 @@ unsigned int OnAssocReq(struct adapter *
+               DBG_871X("  old AID %d\n", pstat->aid);
+       } else {
+               for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
+-                      if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
++                      if (!pstapriv->sta_aid[pstat->aid - 1])
+                               break;
+               /* if (pstat->aid > NUM_STA) { */
+@@ -2226,7 +2226,7 @@ static struct xmit_frame *_alloc_mgtxmit
+       }
+       pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv);
+-      if (pxmitbuf == NULL) {
++      if (!pxmitbuf) {
+               DBG_871X(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter));
+               rtw_free_xmitframe(pxmitpriv, pmgntframe);
+               pmgntframe = NULL;
+@@ -2596,7 +2596,7 @@ void issue_probersp(struct adapter *pada
+       /* DBG_871X("%s\n", __func__); */
+-      if (da == NULL)
++      if (!da)
+               return;
+       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+@@ -2961,7 +2961,7 @@ void issue_auth(struct adapter *padapter
+       __le16 le_tmp;
+       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+-      if (pmgntframe == NULL)
++      if (!pmgntframe)
+               return;
+       /* update attribute */
+@@ -3097,7 +3097,7 @@ void issue_asocrsp(struct adapter *padap
+       DBG_871X("%s\n", __func__);
+       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+-      if (pmgntframe == NULL)
++      if (!pmgntframe)
+               return;
+       /* update attribute */
+@@ -3185,7 +3185,7 @@ void issue_asocrsp(struct adapter *padap
+                               break;
+                       }
+-                      if ((pbuf == NULL) || (ie_len == 0)) {
++                      if (!pbuf || ie_len == 0) {
+                               break;
+                       }
+               }
+@@ -3229,7 +3229,7 @@ void issue_assocreq(struct adapter *pada
+       u8 vs_ie_length = 0;
+       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+-      if (pmgntframe == NULL)
++      if (!pmgntframe)
+               goto exit;
+       /* update attribute */
+@@ -3420,7 +3420,7 @@ static int _issue_nulldata(struct adapte
+       pmlmeinfo = &(pmlmeext->mlmext_info);
+       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+-      if (pmgntframe == NULL)
++      if (!pmgntframe)
+               goto exit;
+       /* update attribute */
+@@ -3573,7 +3573,7 @@ static int _issue_qos_nulldata(struct ad
+       DBG_871X("%s\n", __func__);
+       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+-      if (pmgntframe == NULL)
++      if (!pmgntframe)
+               goto exit;
+       /* update attribute */
+@@ -3698,7 +3698,7 @@ static int _issue_deauth(struct adapter
+       /* DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */
+       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+-      if (pmgntframe == NULL) {
++      if (!pmgntframe) {
+               goto exit;
+       }
+@@ -4047,7 +4047,7 @@ static void issue_action_BSSCoexistPacke
+       action = ACT_PUBLIC_BSSCOEXIST;
+       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+-      if (pmgntframe == NULL) {
++      if (!pmgntframe) {
+               return;
+       }
+@@ -4114,7 +4114,7 @@ static void issue_action_BSSCoexistPacke
+                       pbss_network = (struct wlan_bssid_ex *)&pnetwork->network;
+                       p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
+-                      if ((p == NULL) || (len == 0)) {/* non-HT */
++                      if (!p || len == 0) {/* non-HT */
+                               if (pbss_network->Configuration.DSConfig <= 0)
+                                       continue;
+@@ -4177,7 +4177,7 @@ unsigned int send_delba(struct adapter *
+                       return _SUCCESS;
+       psta = rtw_get_stainfo(pstapriv, addr);
+-      if (psta == NULL)
++      if (!psta)
+               return _SUCCESS;
+       /* DBG_871X("%s:%s\n", __func__, (initiator == 0)?"RX_DIR":"TX_DIR"); */
+@@ -5153,13 +5153,13 @@ void report_del_sta_event(struct adapter
+       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+       pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (pcmd_obj == NULL) {
++      if (!pcmd_obj) {
+               return;
+       }
+       cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
+       pevtcmd = rtw_zmalloc(cmdsz);
+-      if (pevtcmd == NULL) {
++      if (!pevtcmd) {
+               kfree(pcmd_obj);
+               return;
+       }
+@@ -5207,12 +5207,12 @@ void report_add_sta_event(struct adapter
+       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+       pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (pcmd_obj == NULL)
++      if (!pcmd_obj)
+               return;
+       cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
+       pevtcmd = rtw_zmalloc(cmdsz);
+-      if (pevtcmd == NULL) {
++      if (!pevtcmd) {
+               kfree(pcmd_obj);
+               return;
+       }
+@@ -5732,12 +5732,12 @@ void survey_timer_hdl(struct timer_list
+               }
+               ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-              if (ph2c == NULL) {
++              if (!ph2c) {
+                       goto exit_survey_timer_hdl;
+               }
+               psurveyPara = rtw_zmalloc(sizeof(struct sitesurvey_parm));
+-              if (psurveyPara == NULL) {
++              if (!psurveyPara) {
+                       kfree(ph2c);
+                       goto exit_survey_timer_hdl;
+               }
+@@ -6467,7 +6467,7 @@ u8 chk_bmc_sleepq_cmd(struct adapter *pa
+       u8 res = _SUCCESS;
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+@@ -6491,13 +6491,13 @@ u8 set_tx_beacon_cmd(struct adapter *pad
+       int len_diff = 0;
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       ptxBeacon_parm = rtw_zmalloc(sizeof(struct Tx_Beacon_param));
+-      if (ptxBeacon_parm == NULL) {
++      if (!ptxBeacon_parm) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -6529,7 +6529,7 @@ u8 mlme_evt_hdl(struct adapter *padapter
+       void (*event_callback)(struct adapter *dev, u8 *pbuf);
+       struct evt_priv *pevt_priv = &(padapter->evtpriv);
+-      if (pbuf == NULL)
++      if (!pbuf)
+               goto _abort_event_;
+       peventbuf = (uint *)pbuf;
+--- a/drivers/staging/rtl8723bs/core/rtw_security.c
++++ b/drivers/staging/rtl8723bs/core/rtw_security.c
+@@ -226,7 +226,7 @@ void rtw_wep_encrypt(struct adapter *pad
+       struct  security_priv *psecuritypriv = &padapter->securitypriv;
+       struct  xmit_priv       *pxmitpriv = &padapter->xmitpriv;
+-      if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
++      if (!((struct xmit_frame *)pxmitframe)->buf_addr)
+               return;
+       hw_hdr_offset = TXDESC_OFFSET;
+@@ -669,7 +669,7 @@ u32 rtw_tkip_encrypt(struct adapter *pad
+       struct  xmit_priv       *pxmitpriv = &padapter->xmitpriv;
+       u32 res = _SUCCESS;
+-      if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
++      if (!((struct xmit_frame *)pxmitframe)->buf_addr)
+               return _FAIL;
+       hw_hdr_offset = TXDESC_OFFSET;
+@@ -1489,7 +1489,7 @@ u32 rtw_aes_encrypt(struct adapter *pada
+       u32 res = _SUCCESS;
+-      if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
++      if (!((struct xmit_frame *)pxmitframe)->buf_addr)
+               return _FAIL;
+       hw_hdr_offset = TXDESC_OFFSET;
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+@@ -418,7 +418,7 @@ void rtw_cfg80211_ibss_indicate_connect(
+               }
+               else
+               {
+-                      if (scanned == NULL) {
++                      if (!scanned) {
+                               rtw_warn_on(1);
+                               return;
+                       }
+@@ -466,7 +466,7 @@ void rtw_cfg80211_indicate_connect(struc
+               /* DBG_871X(FUNC_ADPT_FMT" BSS not found\n", FUNC_ADPT_ARG(padapter)); */
+-              if (scanned == NULL) {
++              if (!scanned) {
+                       rtw_warn_on(1);
+                       goto check_bss;
+               }
+@@ -597,7 +597,7 @@ static int rtw_cfg80211_ap_set_encryptio
+               }
+       }
+-      if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL))
++      if (strcmp(param->u.crypt.alg, "none") == 0 && !psta)
+       {
+               /* todo:clear default encryption keys */
+@@ -607,7 +607,7 @@ static int rtw_cfg80211_ap_set_encryptio
+       }
+-      if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL))
++      if (strcmp(param->u.crypt.alg, "WEP") == 0 && !psta)
+       {
+               DBG_8192C("r871x_set_encryption, crypt.alg = WEP\n");
+@@ -1001,7 +1001,7 @@ static int rtw_cfg80211_set_encryption(s
+                       }
+                       pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
+-                      if (pbcmc_sta == NULL)
++                      if (!pbcmc_sta)
+                       {
+                               /* DEBUG_ERR(("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */
+                       }
+@@ -1050,7 +1050,7 @@ static int cfg80211_rtw_add_key(struct w
+       param_len = sizeof(struct ieee_param) + params->key_len;
+       param = rtw_malloc(param_len);
+-      if (param == NULL)
++      if (!param)
+               return -1;
+       memset(param, 0, param_len);
+@@ -1214,7 +1214,7 @@ static int cfg80211_rtw_get_station(stru
+       }
+       psta = rtw_get_stainfo(pstapriv, (u8 *)mac);
+-      if (psta == NULL) {
++      if (!psta) {
+               DBG_8192C("%s, sta_info is null\n", __func__);
+               ret = -ENOENT;
+               goto exit;
+@@ -1495,7 +1495,7 @@ static int cfg80211_rtw_scan(struct wiph
+       struct rtw_wdev_priv *pwdev_priv;
+       struct mlme_priv *pmlmepriv;
+-      if (ndev == NULL) {
++      if (!ndev) {
+               ret = -EINVAL;
+               goto exit;
+       }
+@@ -1783,7 +1783,7 @@ static int rtw_cfg80211_set_wpa_ie(struc
+       u8 *pwpa, *pwpa2;
+       u8 null_addr[] = {0, 0, 0, 0, 0, 0};
+-      if (pie == NULL || !ielen) {
++      if (!pie || !ielen) {
+               /* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
+               _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
+               goto exit;
+@@ -1795,7 +1795,7 @@ static int rtw_cfg80211_set_wpa_ie(struc
+       }
+       buf = rtw_zmalloc(ielen);
+-      if (buf == NULL) {
++      if (!buf) {
+               ret =  -ENOMEM;
+               goto exit;
+       }
+@@ -2138,7 +2138,7 @@ static int cfg80211_rtw_connect(struct w
+                       wep_key_len = wep_key_len <= 5 ? 5 : 13;
+                       wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
+                       pwep = rtw_malloc(wep_total_len);
+-                      if (pwep == NULL) {
++                      if (!pwep) {
+                               DBG_871X(" wpa_set_encryption: pwep allocate fail !!!\n");
+                               ret = -ENOMEM;
+                               goto exit;
+@@ -3073,7 +3073,7 @@ static int cfg80211_rtw_mgmt_tx(struct w
+       struct adapter *padapter;
+       struct rtw_wdev_priv *pwdev_priv;
+-      if (ndev == NULL) {
++      if (!ndev) {
+               ret = -EINVAL;
+               goto exit;
+       }
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
+@@ -519,7 +519,7 @@ static int wpa_set_encryption(struct net
+               if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == true) { /* sta mode */
+                       psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
+-                      if (psta == NULL) {
++                      if (!psta) {
+                               /* DEBUG_ERR(("Set wpa_set_encryption: Obtain Sta_info fail\n")); */
+                       } else {
+                               /* Jeff: don't disable ieee8021x_blocked while clearing key */
+@@ -578,7 +578,7 @@ static int wpa_set_encryption(struct net
+                       }
+                       pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
+-                      if (pbcmc_sta == NULL) {
++                      if (!pbcmc_sta) {
+                               /* DEBUG_ERR(("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */
+                       } else {
+                               /* Jeff: don't disable ieee8021x_blocked while clearing key */
+@@ -608,9 +608,9 @@ static int rtw_set_wpa_ie(struct adapter
+       int ret = 0;
+       u8 null_addr[] = {0, 0, 0, 0, 0, 0};
+-      if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL)) {
++      if (ielen > MAX_WPA_IE_LEN || !pie) {
+               _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
+-              if (pie == NULL)
++              if (!pie)
+                       return ret;
+               else
+                       return -EINVAL;
+@@ -618,7 +618,7 @@ static int rtw_set_wpa_ie(struct adapter
+       if (ielen) {
+               buf = rtw_zmalloc(ielen);
+-              if (buf == NULL) {
++              if (!buf) {
+                       ret =  -ENOMEM;
+                       goto exit;
+               }
+@@ -3366,7 +3366,7 @@ static int wpa_supplicant_ioctl(struct n
+               return -EINVAL;
+       param = rtw_malloc(p->length);
+-      if (param == NULL)
++      if (!param)
+               return -ENOMEM;
+       if (copy_from_user(param, p->pointer, p->length)) {
+@@ -3448,7 +3448,7 @@ static int rtw_set_encryption(struct net
+               }
+       }
+-      if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) {
++      if (strcmp(param->u.crypt.alg, "none") == 0 && !psta) {
+               /* todo:clear default encryption keys */
+               psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
+@@ -3462,7 +3462,7 @@ static int rtw_set_encryption(struct net
+       }
+-      if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) {
++      if (strcmp(param->u.crypt.alg, "WEP") == 0 && !psta) {
+               DBG_871X("r871x_set_encryption, crypt.alg = WEP\n");
+               wep_key_idx = param->u.crypt.idx;
+@@ -4187,7 +4187,7 @@ static int rtw_hostapd_ioctl(struct net_
+               return -EINVAL;
+       param = rtw_malloc(p->length);
+-      if (param == NULL)
++      if (!param)
+               return -ENOMEM;
+       if (copy_from_user(param, p->pointer, p->length)) {
+--- a/drivers/staging/rtl8723bs/os_dep/os_intfs.c
++++ b/drivers/staging/rtl8723bs/os_dep/os_intfs.c
+@@ -525,7 +525,7 @@ void rtw_unregister_netdevs(struct dvobj
+       padapter = dvobj->padapters;
+-      if (padapter == NULL)
++      if (!padapter)
+               return;
+       pnetdev = padapter->pnetdev;
+@@ -638,7 +638,7 @@ struct dvobj_priv *devobj_init(void)
+       struct dvobj_priv *pdvobj = NULL;
+       pdvobj = rtw_zmalloc(sizeof(*pdvobj));
+-      if (pdvobj == NULL)
++      if (!pdvobj)
+               return NULL;
+       mutex_init(&pdvobj->hw_init_mutex);
diff --git a/queue-5.10/staging-rtl8723bs-fix-heap-buffer-overflow-in-rtw_cfg80211_set_wpa_ie.patch b/queue-5.10/staging-rtl8723bs-fix-heap-buffer-overflow-in-rtw_cfg80211_set_wpa_ie.patch
new file mode 100644 (file)
index 0000000..216d1ba
--- /dev/null
@@ -0,0 +1,66 @@
+From stable+bounces-274607-greg=kroah.com@vger.kernel.org Wed Jul 15 01:34:19 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 19:34:11 -0400
+Subject: staging: rtl8723bs: fix heap buffer overflow in rtw_cfg80211_set_wpa_ie()
+To: stable@vger.kernel.org
+Cc: Alexandru Hossu <hossu.alexandru@gmail.com>, stable <stable@kernel.org>, Luka Gejak <luka.gejak@linux.dev>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714233411.3592079-2-sashal@kernel.org>
+
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+
+[ Upstream commit 5a752a616e756844388a1a45404db9fc29fec655 ]
+
+supplicant_ie is a 256-byte array in struct security_priv. The WPA and
+WPA2 IE copy paths use:
+
+    memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen + 2);
+
+where wpa_ielen is the raw IE length field (u8, 0-255). When a local user
+supplies a connect request via nl80211 with a crafted WPA IE of length 255,
+wpa_ielen + 2 equals 257, overflowing the 256-byte buffer by one byte into
+the adjacent last_mic_err_time field.
+
+rtw_parse_wpa_ie() does not prevent this: its length consistency check
+compares *(wpa_ie+1) against (u8)(wpa_ie_len-2), which is (u8)(255) == 255
+when wpa_ie_len = 257, so the check passes silently.
+
+Add explicit bounds checks for both the WPA and WPA2 paths before the
+memcpy, rejecting any IE whose total size (wpa_ielen + 2) exceeds the
+supplicant_ie buffer.
+
+Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
+Cc: stable <stable@kernel.org>
+Reviewed-by: Luka Gejak <luka.gejak@linux.dev>
+Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
+Link: https://patch.msgid.link/20260522004531.1038924-4-hossu.alexandru@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+@@ -1818,6 +1818,10 @@ static int rtw_cfg80211_set_wpa_ie(struc
+       pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
+       if (pwpa && wpa_ielen > 0) {
++              if (wpa_ielen + 2 > sizeof(padapter->securitypriv.supplicant_ie)) {
++                      ret = -EINVAL;
++                      goto exit;
++              }
+               if (rtw_parse_wpa_ie(pwpa, wpa_ielen + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
+                       padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
+                       padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
+@@ -1829,6 +1833,10 @@ static int rtw_cfg80211_set_wpa_ie(struc
+       pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
+       if (pwpa2 && wpa2_ielen > 0) {
++              if (wpa2_ielen + 2 > sizeof(padapter->securitypriv.supplicant_ie)) {
++                      ret = -EINVAL;
++                      goto exit;
++              }
+               if (rtw_parse_wpa2_ie(pwpa2, wpa2_ielen + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
+                       padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
+                       padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
diff --git a/queue-5.10/staging-rtl8723bs-fix-oob-reads-in-ie-loops-in-issue_assocreq-and-join_cmd_hdl.patch b/queue-5.10/staging-rtl8723bs-fix-oob-reads-in-ie-loops-in-issue_assocreq-and-join_cmd_hdl.patch
new file mode 100644 (file)
index 0000000..c70c04b
--- /dev/null
@@ -0,0 +1,69 @@
+From stable+bounces-274633-greg=kroah.com@vger.kernel.org Wed Jul 15 02:18:15 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 20:17:26 -0400
+Subject: staging: rtl8723bs: fix OOB reads in IE loops in issue_assocreq() and join_cmd_hdl()
+To: stable@vger.kernel.org
+Cc: Alexandru Hossu <hossu.alexandru@gmail.com>, stable <stable@kernel.org>, Luka Gejak <luka.gejak@linux.dev>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260715001726.3782263-1-sashal@kernel.org>
+
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+
+[ Upstream commit ef61d628dfad38fead1fd2e08979ae9126d011d5 ]
+
+Two IE parsing loops are missing the header bounds checks before they
+dereference pIE->length:
+
+ - issue_assocreq() walks pmlmeinfo->network.ies to build the
+   association request. If the stored IE data ends with only an
+   element_id byte and no length byte, pIE->length is read one byte
+   past the end of the buffer.
+
+ - join_cmd_hdl() walks pnetwork->ies during station join and has
+   the same problem under the same conditions.
+
+Both buffers are filled from AP beacon and probe-response frames, so a
+malicious AP that sends a truncated final IE can trigger the issue.
+
+Apply the two-guard pattern established in update_beacon_info():
+  1. Break if fewer than sizeof(*pIE) bytes remain.
+  2. Break if the IE's declared data extends past the buffer end.
+
+Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
+Cc: stable <stable@kernel.org>
+Reviewed-by: Luka Gejak <luka.gejak@linux.dev>
+Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
+Link: https://patch.msgid.link/20260522004531.1038924-3-hossu.alexandru@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ replaced sizeof(*pIE) with literal 2 (5.10's ndis_80211_var_ie still has data[1]) and used pre-rename field names IELength/IEs/ElementID/Length ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_mlme_ext.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+@@ -3341,7 +3341,11 @@ void issue_assocreq(struct adapter *pada
+       /* vendor specific IE, such as WPA, WMM, WPS */
+       for (i = sizeof(struct ndis_802_11_fix_ie); i < pmlmeinfo->network.IELength;) {
++              if (i + 2 > pmlmeinfo->network.IELength)
++                      break;
+               pIE = (struct ndis_80211_var_ie *)(pmlmeinfo->network.IEs + i);
++              if (i + 2 + pIE->Length > pmlmeinfo->network.IELength)
++                      break;
+               switch (pIE->ElementID) {
+               case _VENDOR_SPECIFIC_IE_:
+@@ -6105,7 +6109,11 @@ u8 join_cmd_hdl(struct adapter *padapter
+       /* sizeof(struct ndis_802_11_fix_ie) */
+       for (i = _FIXED_IE_LENGTH_; i < pnetwork->IELength;) {
++              if (i + 2 > pnetwork->IELength)
++                      break;
+               pIE = (struct ndis_80211_var_ie *)(pnetwork->IEs + i);
++              if (i + 2 + pIE->Length > pnetwork->IELength)
++                      break;
+               switch (pIE->ElementID) {
+               case _VENDOR_SPECIFIC_IE_:/* Get WMM IE. */
diff --git a/queue-5.10/staging-rtl8723bs-fix-space-issues.patch b/queue-5.10/staging-rtl8723bs-fix-space-issues.patch
new file mode 100644 (file)
index 0000000..cd180f2
--- /dev/null
@@ -0,0 +1,266 @@
+From stable+bounces-274604-greg=kroah.com@vger.kernel.org Wed Jul 15 01:34:37 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 19:34:10 -0400
+Subject: staging: rtl8723bs: Fix space issues
+To: stable@vger.kernel.org
+Cc: Franziska Naepelt <franziska.naepelt@googlemail.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714233411.3592079-1-sashal@kernel.org>
+
+From: Franziska Naepelt <franziska.naepelt@googlemail.com>
+
+[ Upstream commit c4b811b9361b0d7ea167a79587f5ec0a13fd8863 ]
+
+Fix the following checkpatch space issues:
+- CHECK: spaces preferred around that '*' (ctx:VxV)
+- CHECK: spaces preferred around that '+' (ctx:VxV)
+- CHECK: spaces preferred around that '-' (ctx:VxV)
+- CHECK: spaces preferred around that '|' (ctx:VxV)
+- CHECK: No space is necessary after a cast
+- WARNING: please, no spaces at the start of a line
+
+Signed-off-by: Franziska Naepelt <franziska.naepelt@googlemail.com>
+Link: https://lore.kernel.org/r/20230701102538.5359-1-franziska.naepelt@googlemail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 5a752a616e75 ("staging: rtl8723bs: fix heap buffer overflow in rtw_cfg80211_set_wpa_ie()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c |   84 ++++++++++------------
+ 1 file changed, 40 insertions(+), 44 deletions(-)
+
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+@@ -98,14 +98,14 @@ static struct ieee80211_channel rtw_2ghz
+ static void rtw_2g_channels_init(struct ieee80211_channel *channels)
+ {
+       memcpy((void *)channels, (void *)rtw_2ghz_channels,
+-              sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
++              sizeof(struct ieee80211_channel) * RTW_2G_CHANNELS_NUM
+       );
+ }
+ static void rtw_2g_rates_init(struct ieee80211_rate *rates)
+ {
+       memcpy(rates, rtw_g_rates,
+-              sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM
++              sizeof(struct ieee80211_rate) * RTW_G_RATES_NUM
+       );
+ }
+@@ -132,8 +132,8 @@ static struct ieee80211_supported_band *
+       if (!spt_band)
+               goto exit;
+-      spt_band->channels = (struct ieee80211_channel *)(((u8 *)spt_band)+sizeof(struct ieee80211_supported_band));
+-      spt_band->bitrates = (struct ieee80211_rate *)(((u8 *)spt_band->channels)+sizeof(struct ieee80211_channel)*n_channels);
++      spt_band->channels = (struct ieee80211_channel *)(((u8 *)spt_band) + sizeof(struct ieee80211_supported_band));
++      spt_band->bitrates = (struct ieee80211_rate *)(((u8 *)spt_band->channels) + sizeof(struct ieee80211_channel) * n_channels);
+       spt_band->band = band;
+       spt_band->n_channels = n_channels;
+       spt_band->n_bitrates = n_bitrates;
+@@ -267,10 +267,10 @@ struct cfg80211_bss *rtw_cfg80211_inform
+               u32 wpsielen = 0;
+               u8 *wpsie = NULL;
+-              wpsie = rtw_get_wps_ie(pnetwork->network.IEs+_FIXED_IE_LENGTH_, pnetwork->network.IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
++              wpsie = rtw_get_wps_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, pnetwork->network.IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
+               if (wpsie && wpsielen > 0)
+-                      psr = rtw_get_wps_attr_content(wpsie,  wpsielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
++                      psr = rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
+               if (sr != 0)
+               {
+@@ -306,9 +306,9 @@ struct cfg80211_bss *rtw_cfg80211_inform
+       /* We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm) */
+       if (check_fwstate(pmlmepriv, _FW_LINKED) == true &&
+               is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) {
+-              notify_signal = 100*translate_percentage_to_dbm(padapter->recvpriv.signal_strength);/* dbm */
++              notify_signal = 100 * translate_percentage_to_dbm(padapter->recvpriv.signal_strength);/* dbm */
+       } else {
+-              notify_signal = 100*translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);/* dbm */
++              notify_signal = 100 * translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);/* dbm */
+       }
+       buf = kzalloc(MAX_BSSINFO_LEN, GFP_ATOMIC);
+@@ -507,22 +507,22 @@ check_bss:
+               roam_info.channel = notify_channel;
+               roam_info.bssid = cur_network->network.MacAddress;
+               roam_info.req_ie =
+-                      pmlmepriv->assoc_req+sizeof(struct ieee80211_hdr_3addr)+2;
++                      pmlmepriv->assoc_req + sizeof(struct ieee80211_hdr_3addr) + 2;
+               roam_info.req_ie_len =
+-                      pmlmepriv->assoc_req_len-sizeof(struct ieee80211_hdr_3addr)-2;
++                      pmlmepriv->assoc_req_len - sizeof(struct ieee80211_hdr_3addr) - 2;
+               roam_info.resp_ie =
+-                      pmlmepriv->assoc_rsp+sizeof(struct ieee80211_hdr_3addr)+6;
++                      pmlmepriv->assoc_rsp + sizeof(struct ieee80211_hdr_3addr) + 6;
+               roam_info.resp_ie_len =
+-                      pmlmepriv->assoc_rsp_len-sizeof(struct ieee80211_hdr_3addr)-6;
++                      pmlmepriv->assoc_rsp_len - sizeof(struct ieee80211_hdr_3addr) - 6;
+               cfg80211_roamed(padapter->pnetdev, &roam_info, GFP_ATOMIC);
+       }
+       else
+       {
+               cfg80211_connect_result(padapter->pnetdev, cur_network->network.MacAddress
+-                      , pmlmepriv->assoc_req+sizeof(struct ieee80211_hdr_3addr)+2
+-                      , pmlmepriv->assoc_req_len-sizeof(struct ieee80211_hdr_3addr)-2
+-                      , pmlmepriv->assoc_rsp+sizeof(struct ieee80211_hdr_3addr)+6
+-                      , pmlmepriv->assoc_rsp_len-sizeof(struct ieee80211_hdr_3addr)-6
++                      , pmlmepriv->assoc_req + sizeof(struct ieee80211_hdr_3addr) + 2
++                      , pmlmepriv->assoc_req_len - sizeof(struct ieee80211_hdr_3addr) - 2
++                      , pmlmepriv->assoc_rsp + sizeof(struct ieee80211_hdr_3addr) + 6
++                      , pmlmepriv->assoc_rsp_len - sizeof(struct ieee80211_hdr_3addr) - 6
+                       , WLAN_STATUS_SUCCESS, GFP_ATOMIC);
+       }
+ }
+@@ -855,7 +855,7 @@ static int rtw_cfg80211_set_encryption(s
+       param->u.crypt.err = 0;
+       param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
+-      if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
++      if (param_len < (u32)((u8 *)param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len)
+       {
+               ret =  -EINVAL;
+               goto exit;
+@@ -1252,10 +1252,10 @@ static int cfg80211_rtw_get_station(stru
+       }
+       /* for Ad-Hoc/AP mode */
+-      if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)
+- || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)
+- || check_fwstate(pmlmepriv, WIFI_AP_STATE))
+-              && check_fwstate(pmlmepriv, _FW_LINKED)
++      if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
++           check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
++           check_fwstate(pmlmepriv, WIFI_AP_STATE)) &&
++          check_fwstate(pmlmepriv, _FW_LINKED)
+       )
+       {
+               /* TODO: should acquire station info... */
+@@ -1518,7 +1518,7 @@ static int cfg80211_rtw_scan(struct wiph
+               DBG_871X("%s under WIFI_AP_STATE\n", __func__);
+ #endif
+-              if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS|_FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true)
++              if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS | _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == true)
+               {
+                       DBG_8192C("%s, fwstate = 0x%x\n", __func__, pmlmepriv->fw_state);
+@@ -1591,7 +1591,7 @@ static int cfg80211_rtw_scan(struct wiph
+       }
+       /* parsing channels, n_channels */
+-      memset(ch, 0, sizeof(struct rtw_ieee80211_channel)*RTW_CHANNEL_SCAN_AMOUNT);
++      memset(ch, 0, sizeof(struct rtw_ieee80211_channel) * RTW_CHANNEL_SCAN_AMOUNT);
+       for (i = 0; i < request->n_channels && i < RTW_CHANNEL_SCAN_AMOUNT; i++) {
+               #ifdef DEBUG_CFG80211
+               DBG_871X(FUNC_ADPT_FMT CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(request->channels[i]));
+@@ -1609,7 +1609,7 @@ static int cfg80211_rtw_scan(struct wiph
+               for (j = request->n_channels - 1; j >= 0; j--)
+                       for (i = 0; i < survey_times; i++)
+               {
+-                      memcpy(&ch[j*survey_times+i], &ch[j], sizeof(struct rtw_ieee80211_channel));
++                      memcpy(&ch[j * survey_times + i], &ch[j], sizeof(struct rtw_ieee80211_channel));
+               }
+               _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times * request->n_channels);
+       } else {
+@@ -1789,7 +1789,7 @@ static int rtw_cfg80211_set_wpa_ie(struc
+               goto exit;
+       }
+-      if (ielen > MAX_WPA_IE_LEN+MAX_WPS_IE_LEN+MAX_P2P_IE_LEN) {
++      if (ielen > MAX_WPA_IE_LEN + MAX_WPS_IE_LEN + MAX_P2P_IE_LEN) {
+               ret = -EINVAL;
+               goto exit;
+       }
+@@ -1817,26 +1817,22 @@ static int rtw_cfg80211_set_wpa_ie(struc
+       }
+       pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
+-      if (pwpa && wpa_ielen > 0)
+-      {
+-              if (rtw_parse_wpa_ie(pwpa, wpa_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
+-              {
++      if (pwpa && wpa_ielen > 0) {
++              if (rtw_parse_wpa_ie(pwpa, wpa_ielen + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
+                       padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
+                       padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
+-                      memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen+2);
++                      memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen + 2);
+                       DBG_8192C("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
+               }
+       }
+       pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
+-      if (pwpa2 && wpa2_ielen > 0)
+-      {
+-              if (rtw_parse_wpa2_ie(pwpa2, wpa2_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
+-              {
++      if (pwpa2 && wpa2_ielen > 0) {
++              if (rtw_parse_wpa2_ie(pwpa2, wpa2_ielen + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
+                       padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
+                       padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
+-                      memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen+2);
++                      memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen + 2);
+                       DBG_8192C("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
+               }
+@@ -2303,7 +2299,7 @@ static int cfg80211_rtw_set_pmksa(struct
+                       memcpy(psecuritypriv->PMKIDList[index].PMKID, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN);
+                       psecuritypriv->PMKIDList[index].bUsed = true;
+-                      psecuritypriv->PMKIDIndex = index+1;
++                      psecuritypriv->PMKIDIndex = index + 1;
+                       blInserted = true;
+                       break;
+               }
+@@ -2477,8 +2473,8 @@ static netdev_tx_t rtw_cfg80211_monitor_
+               return _rtw_xmit_entry(skb, padapter->pnetdev);
+       }
+-      else if ((frame_control & (IEEE80211_FCTL_FTYPE|IEEE80211_FCTL_STYPE))
+-              == (IEEE80211_FTYPE_MGMT|IEEE80211_STYPE_ACTION)
++      else if ((frame_control & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
++              == (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION)
+       )
+       {
+               /* only for action frames */
+@@ -2616,7 +2612,7 @@ static int rtw_cfg80211_add_monitor_if(s
+       }
+       *ndev = pwdev_priv->pmon_ndev = mon_ndev;
+-      memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ+1);
++      memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ + 1);
+ out:
+       if (ret && mon_wdev) {
+@@ -2719,14 +2715,14 @@ static int rtw_add_beacon(struct adapter
+       if (head_len < 24)
+               return -EINVAL;
+-      pbuf = rtw_zmalloc(head_len+tail_len);
++      pbuf = rtw_zmalloc(head_len + tail_len);
+       if (!pbuf)
+               return -ENOMEM;
+-      memcpy(pbuf, (void *)head+24, head_len-24);/*  24 =beacon header len. */
+-      memcpy(pbuf+head_len-24, (void *)tail, tail_len);
++      memcpy(pbuf, (void *)head + 24, head_len - 24);/*  24 =beacon header len. */
++      memcpy(pbuf + head_len - 24, (void *)tail, tail_len);
+-      len = head_len+tail_len-24;
++      len = head_len + tail_len - 24;
+       /* check wps ie if inclued */
+       if (rtw_get_wps_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &wps_ielen))
+@@ -3082,7 +3078,7 @@ static int cfg80211_rtw_mgmt_tx(struct w
+       pwdev_priv = adapter_wdev_data(padapter);
+       /* cookie generation */
+-      *cookie = (unsigned long) buf;
++      *cookie = (unsigned long)buf;
+ #ifdef DEBUG_CFG80211
+       DBG_871X(FUNC_ADPT_FMT" len =%zu, ch =%d"
diff --git a/queue-5.10/staging-rtl8723bs-fix-wep-length-underflow-and-oob-read-in-onauth.patch b/queue-5.10/staging-rtl8723bs-fix-wep-length-underflow-and-oob-read-in-onauth.patch
new file mode 100644 (file)
index 0000000..2ef14e9
--- /dev/null
@@ -0,0 +1,74 @@
+From stable+bounces-274605-greg=kroah.com@vger.kernel.org Wed Jul 15 01:34:41 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 19:34:07 -0400
+Subject: staging: rtl8723bs: fix WEP length underflow and OOB read in OnAuth()
+To: stable@vger.kernel.org
+Cc: Alexandru Hossu <hossu.alexandru@gmail.com>, stable <stable@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714233407.3591885-8-sashal@kernel.org>
+
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+
+[ Upstream commit a1fc19d61f661d47204f095b593de507884849f7 ]
+
+OnAuth() has two bugs in the shared-key authentication path.
+
+When the Privacy bit is set, rtw_wep_decrypt() is called without
+verifying that the frame is long enough to contain a valid WEP IV and
+ICV.  Inside rtw_wep_decrypt(), length is computed as:
+
+    length = len - WLAN_HDR_A3_LEN - iv_len
+
+and then passed as (length - 4) to crc32_le().  If len is less than
+WLAN_HDR_A3_LEN + iv_len + icv_len (32 bytes), length - 4 is negative
+and, after the implicit cast to size_t, causes crc32_le() to read far
+beyond the frame buffer.  Add a minimum length check before accessing
+the IV field and calling the decryption path.
+
+When processing a seq=3 response, rtw_get_ie() stores the Challenge
+Text IE length in ie_len, but the subsequent memcmp() always reads 128
+bytes regardless of ie_len.  IEEE 802.11 mandates a challenge text of
+exactly 128 bytes; reject any IE whose length field differs, matching
+the check already applied to OnAuthClient().
+
+Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
+Link: https://patch.msgid.link/20260522004605.1039209-1-hossu.alexandru@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_mlme_ext.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+@@ -886,6 +886,9 @@ unsigned int OnAuth(struct adapter *pada
+       DBG_871X("+OnAuth\n");
++      if (len < WLAN_HDR_A3_LEN)
++              return _FAIL;
++
+       sa = GetAddr2Ptr(pframe);
+       auth_mode = psecuritypriv->dot11AuthAlgrthm;
+@@ -897,6 +900,9 @@ unsigned int OnAuth(struct adapter *pada
+               prxattrib->hdrlen = WLAN_HDR_A3_LEN;
+               prxattrib->encrypt = _WEP40_;
++              if (len < WLAN_HDR_A3_LEN + 8)
++                      return _FAIL;
++
+               iv = pframe+prxattrib->hdrlen;
+               prxattrib->key_index = ((iv[3]>>6)&0x3);
+@@ -1014,7 +1020,7 @@ unsigned int OnAuth(struct adapter *pada
+                       p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&ie_len,
+                                       len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
+-                      if (!p || ie_len <= 0) {
++                      if (!p || ie_len != 128) {
+                               DBG_871X("auth rejected because challenge failure!(1)\n");
+                               status = _STATS_CHALLENGE_FAIL_;
+                               goto auth_fail;
diff --git a/queue-5.10/staging-rtl8723bs-remove-5ghz-code-blocks.patch b/queue-5.10/staging-rtl8723bs-remove-5ghz-code-blocks.patch
new file mode 100644 (file)
index 0000000..f882cd7
--- /dev/null
@@ -0,0 +1,92 @@
+From stable+bounces-274601-greg=kroah.com@vger.kernel.org Wed Jul 15 01:34:18 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 19:34:04 -0400
+Subject: staging: rtl8723bs: remove 5Ghz code blocks
+To: stable@vger.kernel.org
+Cc: Fabio Aiuto <fabioaiuto83@gmail.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714233407.3591885-5-sashal@kernel.org>
+
+From: Fabio Aiuto <fabioaiuto83@gmail.com>
+
+[ Upstream commit ddd7c8b0033ba01a0ee605697f12a33fd31e6fca ]
+
+remove 5 Ghz code blocks, related to networks
+working over channel numbers above 14.
+
+Signed-off-by: Fabio Aiuto <fabioaiuto83@gmail.com>
+Link: https://lore.kernel.org/r/c64443b92ce1a60f568db153842a62e3244a8c3a.1626874164.git.fabioaiuto83@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a1fc19d61f66 ("staging: rtl8723bs: fix WEP length underflow and OOB read in OnAuth()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_mlme_ext.c  |    7 ++-----
+ drivers/staging/rtl8723bs/os_dep/ioctl_linux.c |   20 +++-----------------
+ 2 files changed, 5 insertions(+), 22 deletions(-)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+@@ -4116,7 +4116,7 @@ static void issue_action_BSSCoexistPacke
+                       p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
+                       if ((p == NULL) || (len == 0)) {/* non-HT */
+-                              if ((pbss_network->Configuration.DSConfig <= 0) || (pbss_network->Configuration.DSConfig > 14))
++                              if (pbss_network->Configuration.DSConfig <= 0)
+                                       continue;
+                               ICS[0][pbss_network->Configuration.DSConfig] = 1;
+@@ -6118,10 +6118,7 @@ u8 join_cmd_hdl(struct adapter *padapter
+                       {
+                               struct HT_info_element *pht_info = (struct HT_info_element *)(pIE->data);
+-                              if (pnetwork->Configuration.DSConfig > 14) {
+-                                      if ((pregpriv->bw_mode >> 4) > CHANNEL_WIDTH_20)
+-                                              cbw40_enable = 1;
+-                              } else {
++                              if (pnetwork->Configuration.DSConfig <= 14) {
+                                       if ((pregpriv->bw_mode & 0x0f) > CHANNEL_WIDTH_20)
+                                               cbw40_enable = 1;
+                               }
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
+@@ -135,14 +135,7 @@ static char *translate_scan(struct adapt
+               else
+                       snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
+       } else {
+-              if (pnetwork->network.Configuration.DSConfig > 14) {
+-                      if (vht_cap)
+-                              snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11AC");
+-                      else if (ht_cap)
+-                              snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11an");
+-                      else
+-                              snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11a");
+-              } else {
++              if (pnetwork->network.Configuration.DSConfig <= 14) {
+                       if (ht_cap)
+                               snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
+                       else
+@@ -762,7 +755,7 @@ static int rtw_wx_get_name(struct net_de
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+       u32 ht_ielen = 0;
+       char *p;
+-      u8 ht_cap = false, vht_cap = false;
++      u8 ht_cap = false;
+       struct  mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+       struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
+       NDIS_802_11_RATES_EX* prates = NULL;
+@@ -788,14 +781,7 @@ static int rtw_wx_get_name(struct net_de
+                       else
+                               snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");
+               } else {
+-                      if (pcur_bss->Configuration.DSConfig > 14) {
+-                              if (vht_cap)
+-                                      snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11AC");
+-                              else if (ht_cap)
+-                                      snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an");
+-                              else
+-                                      snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a");
+-                      } else {
++                      if (pcur_bss->Configuration.DSConfig <= 14) {
+                               if (ht_cap)
+                                       snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");
+                               else
diff --git a/queue-5.10/staging-rtl8723bs-remove-5ghz-code-related-to-channel-plan-definition.patch b/queue-5.10/staging-rtl8723bs-remove-5ghz-code-related-to-channel-plan-definition.patch
new file mode 100644 (file)
index 0000000..a473eeb
--- /dev/null
@@ -0,0 +1,494 @@
+From stable+bounces-274602-greg=kroah.com@vger.kernel.org Wed Jul 15 01:34:29 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 19:34:03 -0400
+Subject: staging: rtl8723bs: remove 5Ghz code related to channel plan definition
+To: stable@vger.kernel.org
+Cc: Fabio Aiuto <fabioaiuto83@gmail.com>, Hans de Goede <hdegoede@redhat.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714233407.3591885-4-sashal@kernel.org>
+
+From: Fabio Aiuto <fabioaiuto83@gmail.com>
+
+[ Upstream commit ec84d0ae54a6774091b3b7d1e9da32589f48b2f9 ]
+
+remove 5Ghz code related to channel plan definition.
+
+Acked-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Fabio Aiuto <fabioaiuto83@gmail.com>
+Link: https://lore.kernel.org/r/17a707952cec951893748d2cb59d02a294cdd1be.1624367071.git.fabioaiuto83@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a1fc19d61f66 ("staging: rtl8723bs: fix WEP length underflow and OOB read in OnAuth()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_mlme_ext.c     |  210 +++++++++-------------
+ drivers/staging/rtl8723bs/hal/hal_com_phycfg.c    |   34 ---
+ drivers/staging/rtl8723bs/include/rtw_mlme_ext.h  |    6 
+ drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c |    2 
+ drivers/staging/rtl8723bs/os_dep/ioctl_linux.c    |    1 
+ 5 files changed, 94 insertions(+), 159 deletions(-)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+@@ -123,93 +123,93 @@ static RT_CHANNEL_PLAN_5G        RTW_ChannelPla
+ static RT_CHANNEL_PLAN_MAP    RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
+       /*  0x00 ~ 0x1F , Old Define ===== */
+-      {0x02, 0x20},   /* 0x00, RT_CHANNEL_DOMAIN_FCC */
+-      {0x02, 0x0A},   /* 0x01, RT_CHANNEL_DOMAIN_IC */
+-      {0x01, 0x01},   /* 0x02, RT_CHANNEL_DOMAIN_ETSI */
+-      {0x01, 0x00},   /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
+-      {0x01, 0x00},   /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
+-      {0x03, 0x00},   /* 0x05, RT_CHANNEL_DOMAIN_MKK */
+-      {0x03, 0x00},   /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
+-      {0x01, 0x09},   /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
+-      {0x03, 0x09},   /* 0x08, RT_CHANNEL_DOMAIN_TELEC */
+-      {0x03, 0x00},   /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
+-      {0x00, 0x00},   /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
+-      {0x02, 0x0F},   /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
+-      {0x01, 0x08},   /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
+-      {0x02, 0x06},   /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
+-      {0x02, 0x0B},   /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
+-      {0x02, 0x09},   /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
+-      {0x01, 0x01},   /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
+-      {0x02, 0x05},   /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
+-      {0x01, 0x21},   /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
+-      {0x00, 0x04},   /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */
+-      {0x02, 0x10},   /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
+-      {0x00, 0x21},   /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
+-      {0x00, 0x22},   /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
+-      {0x03, 0x21},   /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
+-      {0x06, 0x08},   /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
+-      {0x02, 0x08},   /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
+-      {0x00, 0x00},   /* 0x1A, */
+-      {0x00, 0x00},   /* 0x1B, */
+-      {0x00, 0x00},   /* 0x1C, */
+-      {0x00, 0x00},   /* 0x1D, */
+-      {0x00, 0x00},   /* 0x1E, */
+-      {0x06, 0x04},   /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */
++      {0x02}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */
++      {0x02}, /* 0x01, RT_CHANNEL_DOMAIN_IC */
++      {0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */
++      {0x01}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
++      {0x01}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
++      {0x03}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */
++      {0x03}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
++      {0x01}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
++      {0x03}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */
++      {0x03}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
++      {0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
++      {0x02}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
++      {0x01}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
++      {0x02}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
++      {0x02}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
++      {0x02}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
++      {0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
++      {0x02}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
++      {0x01}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
++      {0x00}, /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */
++      {0x02}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
++      {0x00}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
++      {0x00}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
++      {0x03}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
++      {0x06}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
++      {0x02}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
++      {0x00}, /* 0x1A, */
++      {0x00}, /* 0x1B, */
++      {0x00}, /* 0x1C, */
++      {0x00}, /* 0x1D, */
++      {0x00}, /* 0x1E, */
++      {0x06}, /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */
+       /*  0x20 ~ 0x7F , New Define ===== */
+-      {0x00, 0x00},   /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
+-      {0x01, 0x00},   /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
+-      {0x02, 0x00},   /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
+-      {0x03, 0x00},   /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
+-      {0x04, 0x00},   /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
+-      {0x02, 0x04},   /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
+-      {0x00, 0x01},   /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
+-      {0x03, 0x0C},   /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
+-      {0x00, 0x0B},   /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
+-      {0x00, 0x05},   /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
+-      {0x00, 0x00},   /* 0x2A, */
+-      {0x00, 0x00},   /* 0x2B, */
+-      {0x00, 0x00},   /* 0x2C, */
+-      {0x00, 0x00},   /* 0x2D, */
+-      {0x00, 0x00},   /* 0x2E, */
+-      {0x00, 0x00},   /* 0x2F, */
+-      {0x00, 0x06},   /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
+-      {0x00, 0x07},   /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
+-      {0x00, 0x08},   /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
+-      {0x00, 0x09},   /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
+-      {0x02, 0x0A},   /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
+-      {0x00, 0x02},   /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
+-      {0x00, 0x03},   /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
+-      {0x03, 0x0D},   /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
+-      {0x03, 0x0E},   /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
+-      {0x02, 0x0F},   /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
+-      {0x00, 0x00},   /* 0x3A, */
+-      {0x00, 0x00},   /* 0x3B, */
+-      {0x00, 0x00},   /* 0x3C, */
+-      {0x00, 0x00},   /* 0x3D, */
+-      {0x00, 0x00},   /* 0x3E, */
+-      {0x00, 0x00},   /* 0x3F, */
+-      {0x02, 0x10},   /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
+-      {0x05, 0x00},   /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_NULL */
+-      {0x01, 0x12},   /* 0x42, RT_CHANNEL_DOMAIN_ETSI1_ETSI4 */
+-      {0x02, 0x05},   /* 0x43, RT_CHANNEL_DOMAIN_FCC1_FCC2 */
+-      {0x02, 0x11},   /* 0x44, RT_CHANNEL_DOMAIN_FCC1_NCC3 */
+-      {0x00, 0x13},   /* 0x45, RT_CHANNEL_DOMAIN_WORLD_ETSI5 */
+-      {0x02, 0x14},   /* 0x46, RT_CHANNEL_DOMAIN_FCC1_FCC8 */
+-      {0x00, 0x15},   /* 0x47, RT_CHANNEL_DOMAIN_WORLD_ETSI6 */
+-      {0x00, 0x16},   /* 0x48, RT_CHANNEL_DOMAIN_WORLD_ETSI7 */
+-      {0x00, 0x17},   /* 0x49, RT_CHANNEL_DOMAIN_WORLD_ETSI8 */
+-      {0x00, 0x18},   /* 0x50, RT_CHANNEL_DOMAIN_WORLD_ETSI9 */
+-      {0x00, 0x19},   /* 0x51, RT_CHANNEL_DOMAIN_WORLD_ETSI10 */
+-      {0x00, 0x1A},   /* 0x52, RT_CHANNEL_DOMAIN_WORLD_ETSI11 */
+-      {0x02, 0x1B},   /* 0x53, RT_CHANNEL_DOMAIN_FCC1_NCC4 */
+-      {0x00, 0x1C},   /* 0x54, RT_CHANNEL_DOMAIN_WORLD_ETSI12 */
+-      {0x02, 0x1D},   /* 0x55, RT_CHANNEL_DOMAIN_FCC1_FCC9 */
+-      {0x00, 0x1E},   /* 0x56, RT_CHANNEL_DOMAIN_WORLD_ETSI13 */
+-      {0x02, 0x1F},   /* 0x57, RT_CHANNEL_DOMAIN_FCC1_FCC10 */
++      {0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
++      {0x01}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
++      {0x02}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
++      {0x03}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
++      {0x04}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
++      {0x02}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
++      {0x00}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
++      {0x03}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
++      {0x00}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
++      {0x00}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
++      {0x00}, /* 0x2A, */
++      {0x00}, /* 0x2B, */
++      {0x00}, /* 0x2C, */
++      {0x00}, /* 0x2D, */
++      {0x00}, /* 0x2E, */
++      {0x00}, /* 0x2F, */
++      {0x00}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
++      {0x00}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
++      {0x00}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
++      {0x00}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
++      {0x02}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
++      {0x00}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
++      {0x00}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
++      {0x03}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
++      {0x03}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
++      {0x02}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
++      {0x00}, /* 0x3A, */
++      {0x00}, /* 0x3B, */
++      {0x00}, /* 0x3C, */
++      {0x00}, /* 0x3D, */
++      {0x00}, /* 0x3E, */
++      {0x00}, /* 0x3F, */
++      {0x02}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
++      {0x05}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_NULL */
++      {0x01}, /* 0x42, RT_CHANNEL_DOMAIN_ETSI1_ETSI4 */
++      {0x02}, /* 0x43, RT_CHANNEL_DOMAIN_FCC1_FCC2 */
++      {0x02}, /* 0x44, RT_CHANNEL_DOMAIN_FCC1_NCC3 */
++      {0x00}, /* 0x45, RT_CHANNEL_DOMAIN_WORLD_ETSI5 */
++      {0x02}, /* 0x46, RT_CHANNEL_DOMAIN_FCC1_FCC8 */
++      {0x00}, /* 0x47, RT_CHANNEL_DOMAIN_WORLD_ETSI6 */
++      {0x00}, /* 0x48, RT_CHANNEL_DOMAIN_WORLD_ETSI7 */
++      {0x00}, /* 0x49, RT_CHANNEL_DOMAIN_WORLD_ETSI8 */
++      {0x00}, /* 0x50, RT_CHANNEL_DOMAIN_WORLD_ETSI9 */
++      {0x00}, /* 0x51, RT_CHANNEL_DOMAIN_WORLD_ETSI10 */
++      {0x00}, /* 0x52, RT_CHANNEL_DOMAIN_WORLD_ETSI11 */
++      {0x02}, /* 0x53, RT_CHANNEL_DOMAIN_FCC1_NCC4 */
++      {0x00}, /* 0x54, RT_CHANNEL_DOMAIN_WORLD_ETSI12 */
++      {0x02}, /* 0x55, RT_CHANNEL_DOMAIN_FCC1_FCC9 */
++      {0x00}, /* 0x56, RT_CHANNEL_DOMAIN_WORLD_ETSI13 */
++      {0x02}, /* 0x57, RT_CHANNEL_DOMAIN_FCC1_FCC10 */
+ };
+  /* use the combination for max channel numbers */
+-static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03, 0x02};
++static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03};
+ /* Search the @param ch in given @param ch_set
+  * @ch_set: the given channel set
+@@ -231,23 +231,6 @@ int rtw_ch_set_search_ch(RT_CHANNEL_INFO
+       return i;
+ }
+-/* Check the @param ch is fit with setband setting of @param adapter
+- * @adapter: the given adapter
+- * @ch: the given channel number
+- *
+- * return true when check valid, false not valid
+- */
+-bool rtw_mlme_band_check(struct adapter *adapter, const u32 ch)
+-{
+-      if (adapter->setband == GHZ24_50 /* 2.4G and 5G */
+-              || (adapter->setband == GHZ_24 && ch < 35) /* 2.4G only */
+-              || (adapter->setband == GHZ_50 && ch > 35) /* 5G only */
+-      ) {
+-              return true;
+-      }
+-      return false;
+-}
+-
+ /****************************************************************************
+ Following are the initialization functions for WiFi MLME
+@@ -424,7 +407,6 @@ static u8 init_channel_set(struct adapte
+                               else if ((channel_set[chanset_size].ChannelNum  >= 12 && channel_set[chanset_size].ChannelNum  <= 14))
+                                       channel_set[chanset_size].ScanType  = SCAN_PASSIVE;
+                       } else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == ChannelPlan ||
+-                              RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan ||
+                               RT_CHANNEL_DOMAIN_2G_WORLD == Index2G) { /*  channel 12~13, passive scan */
+                               if (channel_set[chanset_size].ChannelNum <= 11)
+                                       channel_set[chanset_size].ScanType = SCAN_ACTIVE;
+@@ -4938,10 +4920,6 @@ static void process_80211d(struct adapte
+       while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0)) {
+               if (chplan_new[i].ChannelNum == channel) {
+                       if (chplan_new[i].ScanType == SCAN_PASSIVE) {
+-                              /* 5G Bnad 2, 3 (DFS) doesn't change to active scan */
+-                              if (channel >= 52 && channel <= 144)
+-                                      break;
+-
+                               chplan_new[i].ScanType = SCAN_ACTIVE;
+                               RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
+                                                ("%s: change channel %d scan type from passive to active\n",
+@@ -6250,7 +6228,6 @@ static int rtw_scan_ch_decision(struct a
+               set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value);
+               if (in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED)
+                       && set_idx >= 0
+-                      && rtw_mlme_band_check(padapter, in[i].hw_value)
+               ) {
+                       if (j >= out_num) {
+                               DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
+@@ -6275,21 +6252,18 @@ static int rtw_scan_ch_decision(struct a
+                       DBG_871X(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), pmlmeext->channel_set[i].ChannelNum);
+-                      if (rtw_mlme_band_check(padapter, pmlmeext->channel_set[i].ChannelNum)) {
+-
+-                              if (j >= out_num) {
+-                                      DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
+-                                              FUNC_ADPT_ARG(padapter), out_num);
+-                                      break;
+-                              }
++                      if (j >= out_num) {
++                              DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
++                                      FUNC_ADPT_ARG(padapter), out_num);
++                              break;
++                      }
+-                              out[j].hw_value = pmlmeext->channel_set[i].ChannelNum;
++                      out[j].hw_value = pmlmeext->channel_set[i].ChannelNum;
+-                              if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
+-                                      out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
++                      if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
++                              out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
+-                              j++;
+-                      }
++                      j++;
+               }
+       }
+--- a/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c
++++ b/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c
+@@ -2062,139 +2062,105 @@ void Hal_ChannelPlanToRegulation(struct
+               break;
+       case RT_CHANNEL_DOMAIN_FCC1_FCC1:
+               pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+-              pHalData->Regulation5G = TXPWR_LMT_FCC;
+               break;
+       case RT_CHANNEL_DOMAIN_WORLD_ETSI1:
+               pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+-              pHalData->Regulation5G = TXPWR_LMT_ETSI;
+               break;
+       case RT_CHANNEL_DOMAIN_MKK1_MKK1:
+               pHalData->Regulation2_4G = TXPWR_LMT_MKK;
+-              pHalData->Regulation5G = TXPWR_LMT_MKK;
+               break;
+       case RT_CHANNEL_DOMAIN_WORLD_KCC1:
+               pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+-              pHalData->Regulation5G = TXPWR_LMT_MKK;
+               break;
+       case RT_CHANNEL_DOMAIN_WORLD_FCC2:
+               pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+-              pHalData->Regulation5G = TXPWR_LMT_FCC;
+               break;
+       case RT_CHANNEL_DOMAIN_WORLD_FCC3:
+               pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+-              pHalData->Regulation5G = TXPWR_LMT_FCC;
+               break;
+       case RT_CHANNEL_DOMAIN_WORLD_FCC4:
+               pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+-              pHalData->Regulation5G = TXPWR_LMT_FCC;
+               break;
+       case RT_CHANNEL_DOMAIN_WORLD_FCC5:
+               pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+-              pHalData->Regulation5G = TXPWR_LMT_FCC;
+               break;
+       case RT_CHANNEL_DOMAIN_WORLD_FCC6:
+               pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+-              pHalData->Regulation5G = TXPWR_LMT_FCC;
+               break;
+       case RT_CHANNEL_DOMAIN_FCC1_FCC7:
+               pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+-              pHalData->Regulation5G = TXPWR_LMT_FCC;
+               break;
+       case RT_CHANNEL_DOMAIN_WORLD_ETSI2:
+               pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+-              pHalData->Regulation5G = TXPWR_LMT_FCC;
+               break;
+       case RT_CHANNEL_DOMAIN_WORLD_ETSI3:
+               pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+-              pHalData->Regulation5G = TXPWR_LMT_FCC;
+               break;
+       case RT_CHANNEL_DOMAIN_MKK1_MKK2:
+               pHalData->Regulation2_4G = TXPWR_LMT_MKK;
+-              pHalData->Regulation5G = TXPWR_LMT_FCC;
+               break;
+       case RT_CHANNEL_DOMAIN_MKK1_MKK3:
+               pHalData->Regulation2_4G = TXPWR_LMT_MKK;
+-              pHalData->Regulation5G = TXPWR_LMT_FCC;
+               break;
+       case RT_CHANNEL_DOMAIN_FCC1_NCC1:
+               pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+-              pHalData->Regulation5G = TXPWR_LMT_FCC;
+               break;
+       case RT_CHANNEL_DOMAIN_FCC1_NCC2:
+               pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+-              pHalData->Regulation5G = TXPWR_LMT_FCC;
+               break;
+       case RT_CHANNEL_DOMAIN_GLOBAL_NULL:
+               pHalData->Regulation2_4G = TXPWR_LMT_WW;
+-              pHalData->Regulation5G = TXPWR_LMT_WW;
+               break;
+       case RT_CHANNEL_DOMAIN_ETSI1_ETSI4:
+               pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
+-              pHalData->Regulation5G = TXPWR_LMT_ETSI;
+               break;
+       case RT_CHANNEL_DOMAIN_FCC1_FCC2:
+               pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+-              pHalData->Regulation5G = TXPWR_LMT_FCC;
+               break;
+       case RT_CHANNEL_DOMAIN_FCC1_NCC3:
+               pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+-              pHalData->Regulation5G = TXPWR_LMT_FCC;
+               break;
+       case RT_CHANNEL_DOMAIN_WORLD_ETSI5:
+               pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
+-              pHalData->Regulation5G = TXPWR_LMT_ETSI;
+               break;
+       case RT_CHANNEL_DOMAIN_FCC1_FCC8:
+               pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+-              pHalData->Regulation5G = TXPWR_LMT_FCC;
+               break;
+       case RT_CHANNEL_DOMAIN_WORLD_ETSI6:
+               pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
+-              pHalData->Regulation5G = TXPWR_LMT_ETSI;
+               break;
+       case RT_CHANNEL_DOMAIN_WORLD_ETSI7:
+               pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
+-              pHalData->Regulation5G = TXPWR_LMT_ETSI;
+               break;
+       case RT_CHANNEL_DOMAIN_WORLD_ETSI8:
+               pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
+-              pHalData->Regulation5G = TXPWR_LMT_ETSI;
+               break;
+       case RT_CHANNEL_DOMAIN_WORLD_ETSI9:
+               pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
+-              pHalData->Regulation5G = TXPWR_LMT_ETSI;
+               break;
+       case RT_CHANNEL_DOMAIN_WORLD_ETSI10:
+               pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
+-              pHalData->Regulation5G = TXPWR_LMT_ETSI;
+               break;
+       case RT_CHANNEL_DOMAIN_WORLD_ETSI11:
+               pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
+-              pHalData->Regulation5G = TXPWR_LMT_ETSI;
+               break;
+       case RT_CHANNEL_DOMAIN_FCC1_NCC4:
+               pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+-              pHalData->Regulation5G = TXPWR_LMT_FCC;
+               break;
+       case RT_CHANNEL_DOMAIN_WORLD_ETSI12:
+               pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
+-              pHalData->Regulation5G = TXPWR_LMT_ETSI;
+               break;
+       case RT_CHANNEL_DOMAIN_FCC1_FCC9:
+               pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+-              pHalData->Regulation5G = TXPWR_LMT_FCC;
+               break;
+       case RT_CHANNEL_DOMAIN_WORLD_ETSI13:
+               pHalData->Regulation2_4G = TXPWR_LMT_ETSI;
+-              pHalData->Regulation5G = TXPWR_LMT_ETSI;
+               break;
+       case RT_CHANNEL_DOMAIN_FCC1_FCC10:
+               pHalData->Regulation2_4G = TXPWR_LMT_FCC;
+-              pHalData->Regulation5G = TXPWR_LMT_FCC;
+               break;
+       case RT_CHANNEL_DOMAIN_REALTEK_DEFINE: /* Realtek Reserve */
+               pHalData->Regulation2_4G = TXPWR_LMT_WW;
+-              pHalData->Regulation5G = TXPWR_LMT_WW;
+               break;
+       default:
+               break;
+--- a/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h
++++ b/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h
+@@ -255,7 +255,6 @@ typedef struct _RT_CHANNEL_PLAN_5G {
+ typedef struct _RT_CHANNEL_PLAN_MAP {
+       unsigned char Index2G;
+-      unsigned char Index5G;
+ } RT_CHANNEL_PLAN_MAP, *PRT_CHANNEL_PLAN_MAP;
+ enum Associated_AP {
+@@ -360,13 +359,13 @@ struct FW_Sta_Info {
+  * When the driver scanned RTW_SCAN_NUM_OF_CH channels, it would switch back to AP's operating channel for
+  * RTW_STAY_AP_CH_MILLISECOND * SURVEY_TO milliseconds.
+  * Example:
+- * For chip supports 2.4G + 5GHz and AP mode is operating in channel 1,
++ * For chip supports 2.4G and AP mode is operating in channel 1,
+  * RTW_SCAN_NUM_OF_CH is 8, RTW_STAY_AP_CH_MILLISECOND is 3 and SURVEY_TO is 100.
+  * When it's STA mode gets set_scan command,
+  * it would
+  * 1. Doing the scan on channel 1.2.3.4.5.6.7.8
+  * 2. Back to channel 1 for 300 milliseconds
+- * 3. Go through doing site survey on channel 9.10.11.36.40.44.48.52
++ * 3. Go through doing site survey on channel 9.10.11
+  * 4. Back to channel 1 for 300 milliseconds
+  * 5. ... and so on, till survey done.
+  */
+@@ -423,7 +422,6 @@ typedef struct _RT_CHANNEL_INFO {
+ } RT_CHANNEL_INFO, *PRT_CHANNEL_INFO;
+ int rtw_ch_set_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch);
+-bool rtw_mlme_band_check(struct adapter *adapter, const u32 ch);
+ /*  P2P_MAX_REG_CLASSES - Maximum number of regulatory classes */
+ #define P2P_MAX_REG_CLASSES 10
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+@@ -77,7 +77,6 @@ static struct ieee80211_rate rtw_rates[]
+ #define RTW_G_RATES_NUM       12
+ #define RTW_2G_CHANNELS_NUM 14
+-#define RTW_5G_CHANNELS_NUM 37
+ static struct ieee80211_channel rtw_2ghz_channels[] = {
+       CHAN2G(1, 2412, 0),
+@@ -1422,7 +1421,6 @@ void rtw_cfg80211_surveydone_event_callb
+               /* report network only if the current channel set contains the channel to which this network belongs */
+               if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
+-                      && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == true
+                       && true == rtw_validate_ssid(&(pnetwork->network.Ssid))
+               )
+               {
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
+@@ -1462,7 +1462,6 @@ static int rtw_wx_get_scan(struct net_de
+               /* report network only if the current channel set contains the channel to which this network belongs */
+               if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
+-                      && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == true
+                       && true == rtw_validate_ssid(&(pnetwork->network.Ssid))) {
+                       ev = translate_scan(padapter, a, pnetwork, ev, stop);
diff --git a/queue-5.10/staging-rtl8723bs-remove-all-5ghz-network-types.patch b/queue-5.10/staging-rtl8723bs-remove-all-5ghz-network-types.patch
new file mode 100644 (file)
index 0000000..a88957e
--- /dev/null
@@ -0,0 +1,460 @@
+From stable+bounces-274600-greg=kroah.com@vger.kernel.org Wed Jul 15 01:34:21 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 19:34:02 -0400
+Subject: staging: rtl8723bs: remove all 5Ghz network types
+To: stable@vger.kernel.org
+Cc: Fabio Aiuto <fabioaiuto83@gmail.com>, Hans de Goede <hdegoede@redhat.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714233407.3591885-3-sashal@kernel.org>
+
+From: Fabio Aiuto <fabioaiuto83@gmail.com>
+
+[ Upstream commit 708180a92cd8bff18b3d2ac05172815bcc0b6b9a ]
+
+remove all 5Ghz network types. rtl8723bs works on
+802.11bgn standards and on 2.4Ghz band.
+
+So remove all code related to 802.11a and 802.11ac
+standards, which the device doesn't support.
+
+Acked-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Fabio Aiuto <fabioaiuto83@gmail.com>
+Link: https://lore.kernel.org/r/7e4644a71d0ba2819370171b3dc78bfc755f6313.1624367071.git.fabioaiuto83@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a1fc19d61f66 ("staging: rtl8723bs: fix WEP length underflow and OOB read in OnAuth()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_ap.c            |   11 ----
+ drivers/staging/rtl8723bs/core/rtw_ieee80211.c     |   22 +-------
+ drivers/staging/rtl8723bs/core/rtw_mlme.c          |   10 ---
+ drivers/staging/rtl8723bs/core/rtw_mlme_ext.c      |   55 ---------------------
+ drivers/staging/rtl8723bs/core/rtw_wlan_util.c     |   14 +----
+ drivers/staging/rtl8723bs/hal/odm.c                |   30 -----------
+ drivers/staging/rtl8723bs/hal/odm.h                |    3 -
+ drivers/staging/rtl8723bs/hal/odm_EdcaTurboCheck.c |    4 -
+ drivers/staging/rtl8723bs/hal/sdio_halinit.c       |    5 -
+ drivers/staging/rtl8723bs/include/hal_phy.h        |    3 -
+ drivers/staging/rtl8723bs/include/ieee80211.h      |   22 +-------
+ drivers/staging/rtl8723bs/include/wifi.h           |    1 
+ drivers/staging/rtl8723bs/os_dep/os_intfs.c        |    2 
+ 13 files changed, 14 insertions(+), 168 deletions(-)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_ap.c
++++ b/drivers/staging/rtl8723bs/core/rtw_ap.c
+@@ -427,11 +427,7 @@ void add_RATid(struct adapter *padapter,
+       shortGIrate = query_ra_short_GI(psta);
+       if (pcur_network->Configuration.DSConfig > 14) {
+-              if (tx_ra_bitmap & 0xffff000)
+-                      sta_band |= WIRELESS_11_5N;
+-
+-              if (tx_ra_bitmap & 0xff0)
+-                      sta_band |= WIRELESS_11A;
++              sta_band |= WIRELESS_INVALID;
+       } else {
+               if (tx_ra_bitmap & 0xffff000)
+                       sta_band |= WIRELESS_11_24N;
+@@ -503,7 +499,7 @@ void update_bmc_sta(struct adapter *pada
+               } else if (network_type == WIRELESS_INVALID) { /*  error handling */
+                       if (pcur_network->Configuration.DSConfig > 14)
+-                              network_type = WIRELESS_11A;
++                              network_type = WIRELESS_INVALID;
+                       else
+                               network_type = WIRELESS_11B;
+               }
+@@ -1254,9 +1250,6 @@ int rtw_check_beacon_data(struct adapter
+       case WIRELESS_11BG_24N:
+               pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
+               break;
+-      case WIRELESS_11A:
+-              pbss_network->NetworkTypeInUse = Ndis802_11OFDM5;
+-              break;
+       default:
+               pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
+               break;
+--- a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c
++++ b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c
+@@ -96,10 +96,7 @@ bool rtw_is_cckratesonly_included(u8 *ra
+ int rtw_check_network_type(unsigned char *rate, int ratelen, int channel)
+ {
+       if (channel > 14) {
+-              if (rtw_is_cckrates_included(rate))
+-                      return WIRELESS_INVALID;
+-              else
+-                      return WIRELESS_11A;
++              return WIRELESS_INVALID;
+       } else { /*  could be pure B, pure G, or B/G */
+               if (rtw_is_cckratesonly_included(rate))
+                       return WIRELESS_11B;
+@@ -275,10 +272,6 @@ void rtw_set_supported_rate(u8 *Supporte
+               break;
+       case WIRELESS_11G:
+-      case WIRELESS_11A:
+-      case WIRELESS_11_5N:
+-      case WIRELESS_11A_5N:/* Todo: no basic rate for ofdm ? */
+-      case WIRELESS_11_5AC:
+               memcpy(SupportedRates, WIFI_OFDMRATES, IEEE80211_NUM_OFDM_RATESLEN);
+               break;
+@@ -336,14 +329,7 @@ int rtw_generate_ie(struct registry_priv
+       ie = rtw_set_ie(ie, _SSID_IE_, pdev_network->Ssid.SsidLength, pdev_network->Ssid.Ssid, &sz);
+       /* supported rates */
+-      if (pregistrypriv->wireless_mode == WIRELESS_11ABGN) {
+-              if (pdev_network->Configuration.DSConfig > 14)
+-                      wireless_mode = WIRELESS_11A_5N;
+-              else
+-                      wireless_mode = WIRELESS_11BG_24N;
+-      } else {
+-              wireless_mode = pregistrypriv->wireless_mode;
+-      }
++      wireless_mode = pregistrypriv->wireless_mode;
+       rtw_set_supported_rate(pdev_network->SupportedRates, wireless_mode);
+@@ -368,8 +354,8 @@ int rtw_generate_ie(struct registry_priv
+       }
+       /* HT Cap. */
+-      if (((pregistrypriv->wireless_mode&WIRELESS_11_5N) || (pregistrypriv->wireless_mode&WIRELESS_11_24N))
+-              && (pregistrypriv->ht_enable == true)) {
++      if ((pregistrypriv->wireless_mode & WIRELESS_11_24N) &&
++          (pregistrypriv->ht_enable == true)) {
+               /* todo: */
+       }
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c
+@@ -2438,16 +2438,6 @@ void rtw_update_registrypriv_dev_network
+       case WIRELESS_11BG_24N:
+               pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24);
+               break;
+-      case WIRELESS_11A:
+-      case WIRELESS_11A_5N:
+-              pdev_network->NetworkTypeInUse = (Ndis802_11OFDM5);
+-              break;
+-      case WIRELESS_11ABGN:
+-              if (pregistrypriv->channel > 14)
+-                      pdev_network->NetworkTypeInUse = (Ndis802_11OFDM5);
+-              else
+-                      pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24);
+-              break;
+       default:
+               /*  TODO */
+               break;
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+@@ -4918,61 +4918,6 @@ static void process_80211d(struct adapte
+                       }
+               }
+-              if (pregistrypriv->wireless_mode & WIRELESS_11A) {
+-                      do {
+-                              if ((i == MAX_CHANNEL_NUM) ||
+-                                      (chplan_sta[i].ChannelNum == 0))
+-                                      break;
+-
+-                              if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
+-                                      break;
+-
+-                              if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) {
+-                                      chplan_new[k].ChannelNum = chplan_ap.Channel[j];
+-                                      chplan_new[k].ScanType = SCAN_ACTIVE;
+-                                      i++;
+-                                      j++;
+-                                      k++;
+-                              } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) {
+-                                      chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
+-/*                                    chplan_new[k].ScanType = chplan_sta[i].ScanType; */
+-                                      chplan_new[k].ScanType = SCAN_PASSIVE;
+-                                      i++;
+-                                      k++;
+-                              } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) {
+-                                      chplan_new[k].ChannelNum = chplan_ap.Channel[j];
+-                                      chplan_new[k].ScanType = SCAN_ACTIVE;
+-                                      j++;
+-                                      k++;
+-                              }
+-                      } while (1);
+-
+-                      /*  change AP not support channel to Passive scan */
+-                      while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
+-                              chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
+-/*                            chplan_new[k].ScanType = chplan_sta[i].ScanType; */
+-                              chplan_new[k].ScanType = SCAN_PASSIVE;
+-                              i++;
+-                              k++;
+-                      }
+-
+-                      /*  add channel AP supported */
+-                      while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0)) {
+-                              chplan_new[k].ChannelNum = chplan_ap.Channel[j];
+-                              chplan_new[k].ScanType = SCAN_ACTIVE;
+-                              j++;
+-                              k++;
+-                      }
+-              } else {
+-                      /*  keep original STA 5G channel plan */
+-                      while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
+-                              chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
+-                              chplan_new[k].ScanType = chplan_sta[i].ScanType;
+-                              i++;
+-                              k++;
+-                      }
+-              }
+-
+               pmlmeext->update_channel_plan_by_ap_done = 1;
+ #ifdef DEBUG_RTL871X
+--- a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
++++ b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
+@@ -62,9 +62,6 @@ u8 networktype_to_raid_ex(struct adapter
+       if (cur_rf_type == RF_1T1R) {
+               rf_type = RF_1T1R;
+-      } else if (IsSupportedVHT(psta->wireless_mode)) {
+-              if (psta->ra_mask & 0xffc00000)
+-                      rf_type = RF_2T2R;
+       } else if (IsSupportedHT(psta->wireless_mode)) {
+               if (psta->ra_mask & 0xfff00000)
+                       rf_type = RF_2T2R;
+@@ -74,7 +71,6 @@ u8 networktype_to_raid_ex(struct adapter
+       case WIRELESS_11B:
+               raid = RATEID_IDX_B;
+               break;
+-      case WIRELESS_11A:
+       case WIRELESS_11G:
+               raid = RATEID_IDX_G;
+               break;
+@@ -82,8 +78,6 @@ u8 networktype_to_raid_ex(struct adapter
+               raid = RATEID_IDX_BG;
+               break;
+       case WIRELESS_11_24N:
+-      case WIRELESS_11_5N:
+-      case WIRELESS_11A_5N:
+       case WIRELESS_11G_24N:
+               if (rf_type == RF_2T2R)
+                       raid = RATEID_IDX_GN_N2SS;
+@@ -810,7 +804,7 @@ void WMMOnAssocRsp(struct adapter *padap
+               AIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
+-              if (pmlmeext->cur_wireless_mode & (WIRELESS_11G | WIRELESS_11A)) {
++              if (pmlmeext->cur_wireless_mode & WIRELESS_11G) {
+                       ECWMin = 4;
+                       ECWMax = 10;
+               } else if (pmlmeext->cur_wireless_mode & WIRELESS_11B) {
+@@ -1695,7 +1689,7 @@ void update_capinfo(struct adapter *Adap
+               pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
+       else {
+               /* Filen: See 802.11-2007 p.90 */
+-              if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N | WIRELESS_11A | WIRELESS_11_5N | WIRELESS_11AC))
++              if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N))
+                       pmlmeinfo->slotTime = SHORT_SLOT_TIME;
+               else if (pmlmeext->cur_wireless_mode & (WIRELESS_11G)) {
+                       if ((updateCap & cShortSlotTime) /* && (!(pMgntInfo->pHTInfo->RT2RT_HT_Mode & RT_HT_CAP_USE_LONG_PREAMBLE)) */)
+@@ -1724,9 +1718,7 @@ void update_wireless_mode(struct adapter
+       if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable))
+               pmlmeinfo->HT_enable = 1;
+-      if (pmlmeinfo->VHT_enable)
+-              network_type = WIRELESS_11AC;
+-      else if (pmlmeinfo->HT_enable)
++      if (pmlmeinfo->HT_enable)
+               network_type = WIRELESS_11_24N;
+       if (rtw_is_cckratesonly_included(rate))
+--- a/drivers/staging/rtl8723bs/hal/odm.c
++++ b/drivers/staging/rtl8723bs/hal/odm.c
+@@ -975,7 +975,6 @@ u32 ODM_Get_Rate_Bitmap(
+               break;
+       case (ODM_WM_G):
+-      case (ODM_WM_A):
+               if (rssi_level == DM_RATR_STA_HIGH)
+                       rate_bitmap = 0x00000f00;
+               else
+@@ -994,7 +993,6 @@ u32 ODM_Get_Rate_Bitmap(
+       case (ODM_WM_B|ODM_WM_G|ODM_WM_N24G):
+       case (ODM_WM_B|ODM_WM_N24G):
+       case (ODM_WM_G|ODM_WM_N24G):
+-      case (ODM_WM_A|ODM_WM_N5G):
+               if (pDM_Odm->RFType == ODM_1T2R || pDM_Odm->RFType == ODM_1T1R) {
+                       if (rssi_level == DM_RATR_STA_HIGH)
+                               rate_bitmap = 0x000f0000;
+@@ -1020,34 +1018,6 @@ u32 ODM_Get_Rate_Bitmap(
+               }
+               break;
+-      case (ODM_WM_AC|ODM_WM_G):
+-              if (rssi_level == 1)
+-                      rate_bitmap = 0xfc3f0000;
+-              else if (rssi_level == 2)
+-                      rate_bitmap = 0xfffff000;
+-              else
+-                      rate_bitmap = 0xffffffff;
+-              break;
+-
+-      case (ODM_WM_AC|ODM_WM_A):
+-
+-              if (pDM_Odm->RFType == RF_1T1R) {
+-                      if (rssi_level == 1)                            /*  add by Gary for ac-series */
+-                              rate_bitmap = 0x003f8000;
+-                      else if (rssi_level == 2)
+-                              rate_bitmap = 0x003ff000;
+-                      else
+-                              rate_bitmap = 0x003ff010;
+-              } else {
+-                      if (rssi_level == 1)                            /*  add by Gary for ac-series */
+-                              rate_bitmap = 0xfe3f8000;       /*  VHT 2SS MCS3~9 */
+-                      else if (rssi_level == 2)
+-                              rate_bitmap = 0xfffff000;       /*  VHT 2SS MCS0~9 */
+-                      else
+-                              rate_bitmap = 0xfffff010;       /*  All */
+-              }
+-              break;
+-
+       default:
+               if (pDM_Odm->RFType == RF_1T2R)
+                       rate_bitmap = 0x000fffff;
+--- a/drivers/staging/rtl8723bs/hal/odm.h
++++ b/drivers/staging/rtl8723bs/hal/odm.h
+@@ -541,11 +541,8 @@ typedef enum tag_Wireless_Mode_Definitio
+       ODM_WM_UNKNOWN    = 0x0,
+       ODM_WM_B          = BIT0,
+       ODM_WM_G          = BIT1,
+-      ODM_WM_A          = BIT2,
+       ODM_WM_N24G       = BIT3,
+-      ODM_WM_N5G        = BIT4,
+       ODM_WM_AUTO       = BIT5,
+-      ODM_WM_AC         = BIT6,
+ } ODM_WIRELESS_MODE_E;
+ /*  ODM_CMNINFO_BAND */
+--- a/drivers/staging/rtl8723bs/hal/odm_EdcaTurboCheck.c
++++ b/drivers/staging/rtl8723bs/hal/odm_EdcaTurboCheck.c
+@@ -142,12 +142,10 @@ void odm_EdcaTurboCheckCE(void *pDM_VOID
+               } else if ((iot_peer == HT_IOT_PEER_CISCO) &&
+                          ((wirelessmode == ODM_WM_G) ||
+                           (wirelessmode == (ODM_WM_B | ODM_WM_G)) ||
+-                          (wirelessmode == ODM_WM_A) ||
+                           (wirelessmode == ODM_WM_B))) {
+                       EDCA_BE_DL = edca_setting_DL_GMode[iot_peer];
+               } else if ((iot_peer == HT_IOT_PEER_AIRGO) &&
+-                         ((wirelessmode == ODM_WM_G) ||
+-                          (wirelessmode == ODM_WM_A))) {
++                         (wirelessmode == ODM_WM_G)) {
+                       EDCA_BE_DL = 0xa630;
+               } else if (iot_peer == HT_IOT_PEER_MARVELL) {
+                       EDCA_BE_DL = edca_setting_DL[iot_peer];
+--- a/drivers/staging/rtl8723bs/hal/sdio_halinit.c
++++ b/drivers/staging/rtl8723bs/hal/sdio_halinit.c
+@@ -599,8 +599,6 @@ static void _InitOperationMode(struct ad
+       case WIRELESS_MODE_B:
+               regBwOpMode = BW_OPMODE_20MHZ;
+               break;
+-      case WIRELESS_MODE_A:
+-              break;
+       case WIRELESS_MODE_G:
+               regBwOpMode = BW_OPMODE_20MHZ;
+               break;
+@@ -612,9 +610,6 @@ static void _InitOperationMode(struct ad
+               /*  CCK rate will be filtered out only when associated AP does not support it. */
+               regBwOpMode = BW_OPMODE_20MHZ;
+               break;
+-      case WIRELESS_MODE_N_5G:
+-              regBwOpMode = BW_OPMODE_5G;
+-              break;
+       default: /* for MacOSX compiler warning. */
+               break;
+--- a/drivers/staging/rtl8723bs/include/hal_phy.h
++++ b/drivers/staging/rtl8723bs/include/hal_phy.h
+@@ -118,13 +118,10 @@ enum HW_BLOCK {
+ enum WIRELESS_MODE {
+       WIRELESS_MODE_UNKNOWN = 0x00,
+-      WIRELESS_MODE_A = 0x01,
+       WIRELESS_MODE_B = 0x02,
+       WIRELESS_MODE_G = 0x04,
+       WIRELESS_MODE_AUTO = 0x08,
+       WIRELESS_MODE_N_24G = 0x10,
+-      WIRELESS_MODE_N_5G = 0x20,
+-      WIRELESS_MODE_AC_5G = 0x40,
+       WIRELESS_MODE_AC_24G  = 0x80,
+       WIRELESS_MODE_AC_ONLY  = 0x100,
+ };
+--- a/drivers/staging/rtl8723bs/include/ieee80211.h
++++ b/drivers/staging/rtl8723bs/include/ieee80211.h
+@@ -157,33 +157,20 @@ enum NETWORK_TYPE {
+       /* Sub-Element */
+       WIRELESS_11B = BIT(0), /*  tx: cck only , rx: cck only, hw: cck */
+       WIRELESS_11G = BIT(1), /*  tx: ofdm only, rx: ofdm & cck, hw: cck & ofdm */
+-      WIRELESS_11A = BIT(2), /*  tx: ofdm only, rx: ofdm only, hw: ofdm only */
+       WIRELESS_11_24N = BIT(3), /*  tx: MCS only, rx: MCS & cck, hw: MCS & cck */
+-      WIRELESS_11_5N = BIT(4), /*  tx: MCS only, rx: MCS & ofdm, hw: ofdm only */
+       WIRELESS_AUTO = BIT(5),
+-      WIRELESS_11AC = BIT(6),
+       /* Combination */
+       /* Type for current wireless mode */
+       WIRELESS_11BG = (WIRELESS_11B|WIRELESS_11G), /*  tx: cck & ofdm, rx: cck & ofdm & MCS, hw: cck & ofdm */
+       WIRELESS_11G_24N = (WIRELESS_11G|WIRELESS_11_24N), /*  tx: ofdm & MCS, rx: ofdm & cck & MCS, hw: cck & ofdm */
+-      WIRELESS_11A_5N = (WIRELESS_11A|WIRELESS_11_5N), /*  tx: ofdm & MCS, rx: ofdm & MCS, hw: ofdm only */
+       WIRELESS_11B_24N = (WIRELESS_11B|WIRELESS_11_24N), /*  tx: ofdm & cck & MCS, rx: ofdm & cck & MCS, hw: ofdm & cck */
+       WIRELESS_11BG_24N = (WIRELESS_11B|WIRELESS_11G|WIRELESS_11_24N), /*  tx: ofdm & cck & MCS, rx: ofdm & cck & MCS, hw: ofdm & cck */
+-      WIRELESS_11_24AC = (WIRELESS_11G|WIRELESS_11AC),
+-      WIRELESS_11_5AC = (WIRELESS_11A|WIRELESS_11AC),
+-
+-
+-      /* Type for registry default wireless mode */
+-      WIRELESS_11AGN = (WIRELESS_11A|WIRELESS_11G|WIRELESS_11_24N|WIRELESS_11_5N), /*  tx: ofdm & MCS, rx: ofdm & MCS, hw: ofdm only */
+-      WIRELESS_11ABGN = (WIRELESS_11A|WIRELESS_11B|WIRELESS_11G|WIRELESS_11_24N|WIRELESS_11_5N),
+-      WIRELESS_MODE_24G = (WIRELESS_11B|WIRELESS_11G|WIRELESS_11_24N|WIRELESS_11AC),
+-      WIRELESS_MODE_MAX = (WIRELESS_11A|WIRELESS_11B|WIRELESS_11G|WIRELESS_11_24N|WIRELESS_11_5N|WIRELESS_11AC),
+ };
+ #define SUPPORTED_24G_NETTYPE_MSK (WIRELESS_11B | WIRELESS_11G | WIRELESS_11_24N)
+-#define IsLegacyOnly(NetType)  ((NetType) == ((NetType) & (WIRELESS_11BG|WIRELESS_11A)))
++#define IsLegacyOnly(NetType)  ((NetType) == ((NetType) & (WIRELESS_11BG)))
+ #define IsSupported24G(NetType) ((NetType) & SUPPORTED_24G_NETTYPE_MSK ? true : false)
+@@ -195,11 +182,8 @@ enum NETWORK_TYPE {
+ #define IsSupportedRxHT(NetType) IsEnableHWOFDM(NetType)
+ #define IsSupportedTxCCK(NetType) (((NetType) & (WIRELESS_11B)) ? true : false)
+-#define IsSupportedTxOFDM(NetType) (((NetType) & (WIRELESS_11G|WIRELESS_11A)) ? true : false)
+-#define IsSupportedHT(NetType) (((NetType) & (WIRELESS_11_24N|WIRELESS_11_5N)) ? true : false)
+-
+-#define IsSupportedVHT(NetType) (((NetType) & (WIRELESS_11AC)) ? true : false)
+-
++#define IsSupportedTxOFDM(NetType) (((NetType) & (WIRELESS_11G) ? true : false)
++#define IsSupportedHT(NetType) (((NetType) & (WIRELESS_11_24N)) ? true : false)
+ struct ieee_param {
+       u32 cmd;
+--- a/drivers/staging/rtl8723bs/include/wifi.h
++++ b/drivers/staging/rtl8723bs/include/wifi.h
+@@ -457,7 +457,6 @@ static inline int IsFrameTypeCtrl(unsign
+ #define _PRE_ALLOCICVHDR_             5
+ #define _PRE_ALLOCMICHDR_             6
+-#define _SIFSTIME_                            ((priv->pmib->dot11BssType.net_work_type&WIRELESS_11A)?16:10)
+ #define _ACKCTSLNG_                           14      /* 14 bytes long, including crclng */
+ #define _CRCLNG_                              4
+--- a/drivers/staging/rtl8723bs/os_dep/os_intfs.c
++++ b/drivers/staging/rtl8723bs/os_dep/os_intfs.c
+@@ -24,7 +24,7 @@ static int rtw_lbkmode;/* RTL8712_AIR_TR
+ static int rtw_network_mode = Ndis802_11IBSS;/* Ndis802_11Infrastructure;infra, ad-hoc, auto */
+ /* struct ndis_802_11_ssid    ssid; */
+ static int rtw_channel = 1;/* ad-hoc support requirement */
+-static int rtw_wireless_mode = WIRELESS_MODE_MAX;
++static int rtw_wireless_mode = WIRELESS_11BG_24N;
+ static int rtw_vrtl_carrier_sense = AUTO_VCS;
+ static int rtw_vcs_type = RTS_CTS;/*  */
+ static int rtw_rts_thresh = 2347;/*  */
diff --git a/queue-5.10/staging-rtl8723bs-remove-commented-out-condition.patch b/queue-5.10/staging-rtl8723bs-remove-commented-out-condition.patch
new file mode 100644 (file)
index 0000000..9e3ac6d
--- /dev/null
@@ -0,0 +1,35 @@
+From stable+bounces-274603-greg=kroah.com@vger.kernel.org Wed Jul 15 01:34:18 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 19:34:05 -0400
+Subject: staging: rtl8723bs: remove commented out condition
+To: stable@vger.kernel.org
+Cc: Fabio Aiuto <fabioaiuto83@gmail.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714233407.3591885-6-sashal@kernel.org>
+
+From: Fabio Aiuto <fabioaiuto83@gmail.com>
+
+[ Upstream commit 2a62ff13132a22a754d042b2230117bbea0af477 ]
+
+remove commented out condition checking channel > 14.
+
+Signed-off-by: Fabio Aiuto <fabioaiuto83@gmail.com>
+Link: https://lore.kernel.org/r/83762719c0c13ac8b78612a32db26e691eef17d1.1626874164.git.fabioaiuto83@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a1fc19d61f66 ("staging: rtl8723bs: fix WEP length underflow and OOB read in OnAuth()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/os_dep/ioctl_linux.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
+@@ -165,7 +165,7 @@ static char *translate_scan(struct adapt
+               start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
+       }
+-      if (pnetwork->network.Configuration.DSConfig < 1 /*|| pnetwork->network.Configuration.DSConfig > 14*/)
++      if (pnetwork->network.Configuration.DSConfig < 1)
+               pnetwork->network.Configuration.DSConfig = 1;
+        /* Add frequency/channel */
diff --git a/queue-5.10/staging-rtl8723bs-remove-commented-out-rt_assert-occurrences.patch b/queue-5.10/staging-rtl8723bs-remove-commented-out-rt_assert-occurrences.patch
new file mode 100644 (file)
index 0000000..8e989b7
--- /dev/null
@@ -0,0 +1,90 @@
+From stable+bounces-274599-greg=kroah.com@vger.kernel.org Wed Jul 15 01:34:17 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 19:34:01 -0400
+Subject: staging: rtl8723bs: remove commented out RT_ASSERT occurrences
+To: stable@vger.kernel.org
+Cc: Fabio Aiuto <fabioaiuto83@gmail.com>, Dan Carpenter <dan.carpenter@oracle.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714233407.3591885-2-sashal@kernel.org>
+
+From: Fabio Aiuto <fabioaiuto83@gmail.com>
+
+[ Upstream commit 2172a6576388e63958f47923e435c46af8d006ba ]
+
+remove commented out obsoete RT_ASSERT macro occurences.
+
+Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Fabio Aiuto <fabioaiuto83@gmail.com>
+Link: https://lore.kernel.org/r/3ee98d7bf1685af627e625f413de355fce58d52d.1619794331.git.fabioaiuto83@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a1fc19d61f66 ("staging: rtl8723bs: fix WEP length underflow and OOB read in OnAuth()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_recv.c         |    2 --
+ drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c |    1 -
+ drivers/staging/rtl8723bs/hal/sdio_halinit.c      |    5 -----
+ 3 files changed, 8 deletions(-)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_recv.c
++++ b/drivers/staging/rtl8723bs/core/rtw_recv.c
+@@ -2165,8 +2165,6 @@ int recv_indicatepkts_in_order(struct ad
+                       /* pTS->RxIndicateState = RXTS_INDICATE_PROCESSING; */
+                       /*  Indicate packets */
+-                      /* RT_ASSERT((index<=REORDER_WIN_SIZE), ("RxReorderIndicatePacket(): Rx Reorder buffer full!!\n")); */
+-
+                       /* indicate this recv_frame */
+                       /* DbgPrint("recv_indicatepkts_in_order, indicate_seq =%d, seq_num =%d\n", precvpriv->indicate_seq, pattrib->seq_num); */
+--- a/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c
++++ b/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c
+@@ -158,7 +158,6 @@ static int _WriteFW(struct adapter *pada
+       u8 *bufferPtr = buffer;
+       pageNums = size / MAX_DLFW_PAGE_SIZE;
+-      /* RT_ASSERT((pageNums <= 4), ("Page numbers should not greater then 4\n")); */
+       remainSize = size % MAX_DLFW_PAGE_SIZE;
+       for (page = 0; page < pageNums; page++) {
+--- a/drivers/staging/rtl8723bs/hal/sdio_halinit.c
++++ b/drivers/staging/rtl8723bs/hal/sdio_halinit.c
+@@ -313,7 +313,6 @@ static void _InitNormalChipOneOutEpPrior
+               value = QUEUE_NORMAL;
+               break;
+       default:
+-              /* RT_ASSERT(false, ("Shall not reach here!\n")); */
+               break;
+       }
+@@ -347,7 +346,6 @@ static void _InitNormalChipTwoOutEpPrior
+               valueLow = QUEUE_NORMAL;
+               break;
+       default:
+-              /* RT_ASSERT(false, ("Shall not reach here!\n")); */
+               break;
+       }
+@@ -412,7 +410,6 @@ static void _InitQueuePriority(struct ad
+               _InitNormalChipThreeOutEpPriority(Adapter);
+               break;
+       default:
+-              /* RT_ASSERT(false, ("Shall not reach here!\n")); */
+               break;
+       }
+@@ -603,7 +600,6 @@ static void _InitOperationMode(struct ad
+               regBwOpMode = BW_OPMODE_20MHZ;
+               break;
+       case WIRELESS_MODE_A:
+-/*                    RT_ASSERT(false, ("Error wireless a mode\n")); */
+               break;
+       case WIRELESS_MODE_G:
+               regBwOpMode = BW_OPMODE_20MHZ;
+@@ -617,7 +613,6 @@ static void _InitOperationMode(struct ad
+               regBwOpMode = BW_OPMODE_20MHZ;
+               break;
+       case WIRELESS_MODE_N_5G:
+-/*                    RT_ASSERT(false, ("Error wireless mode")); */
+               regBwOpMode = BW_OPMODE_5G;
+               break;
diff --git a/queue-5.10/staging-rtl8723bs-remove-dbg_871x-log-argument.patch b/queue-5.10/staging-rtl8723bs-remove-dbg_871x-log-argument.patch
new file mode 100644 (file)
index 0000000..9ccf2ca
--- /dev/null
@@ -0,0 +1,52 @@
+From stable+bounces-274677-greg=kroah.com@vger.kernel.org Wed Jul 15 04:45:49 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 22:45:34 -0400
+Subject: staging: rtl8723bs: remove DBG_871X log argument
+To: stable@vger.kernel.org
+Cc: Fabio Aiuto <fabioaiuto83@gmail.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260715024543.105642-1-sashal@kernel.org>
+
+From: Fabio Aiuto <fabioaiuto83@gmail.com>
+
+[ Upstream commit 42c3243ff23d119331a8ace011e0c18b222a1138 ]
+
+This patch prepares the application of the semantic
+patch aimed to remove all DBG_871X logs.
+
+One occurrence of the DBG_871X macro has one
+repeated argument, that's not even comma separated
+value with the previous one nor a format string
+parameter associated.
+
+In normal conditions this worked, for the macro
+is usually not expanded (the do nothing behaviour),
+but if I try to apply the sempantic patch to remove
+all macro occurrences, all macros call after that
+abnormal declaration are left untouched (not removed).
+
+Remove all of the DBG_871X logs as they currently
+do nothing as they require the code to be modified by
+hand in order to be turned on. This obviously has not happened
+since the code was merged, so just remove them as they are unused.
+
+Signed-off-by: Fabio Aiuto <fabioaiuto83@gmail.com>
+Link: https://lore.kernel.org/r/3473925ae9ee5a3bcd0ab86613dbce80b6d3f33f.1617802415.git.fabioaiuto83@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: ed51de4a86e1 ("staging: rtl8723bs: fix OOB read in update_beacon_info() IE loop")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_recv.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_recv.c
++++ b/drivers/staging/rtl8723bs/core/rtw_recv.c
+@@ -923,7 +923,7 @@ sint ap2sta_data_frame(
+                       #ifdef DBG_RX_DROP_FRAME
+                       DBG_871X("DBG_RX_DROP_FRAME %s BSSID ="MAC_FMT", mybssid ="MAC_FMT"\n",
+                               __func__, MAC_ARG(pattrib->bssid), MAC_ARG(mybssid));
+-                      DBG_871X("this adapter = %d, buddy adapter = %d\n", adapter->adapter_type, adapter->pbuddystruct adapter->adapter_type);
++                      DBG_871X("this adapter = %d, buddy adapter = %d\n", adapter->adapter_type, adapter->pbuddystruct);
+                       #endif
+                       if (!bmcast) {
diff --git a/queue-5.10/staging-rtl8723bs-split-too-long-line.patch b/queue-5.10/staging-rtl8723bs-split-too-long-line.patch
new file mode 100644 (file)
index 0000000..1ac0f05
--- /dev/null
@@ -0,0 +1,41 @@
+From stable+bounces-274598-greg=kroah.com@vger.kernel.org Wed Jul 15 01:34:18 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 19:34:00 -0400
+Subject: staging: rtl8723bs: split too long line
+To: stable@vger.kernel.org
+Cc: Fabio Aiuto <fabioaiuto83@gmail.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714233407.3591885-1-sashal@kernel.org>
+
+From: Fabio Aiuto <fabioaiuto83@gmail.com>
+
+[ Upstream commit 98dc120895a9a669e35155ee03b98452723aba95 ]
+
+fix the following post-commit hook checkpatch issue.
+
+WARNING: line length of 103 exceeds 100 columns
+30: FILE: drivers/staging/rtl8723bs/core/rtw_mlme_ext.c:711:
++
+receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 0);
+
+Signed-off-by: Fabio Aiuto <fabioaiuto83@gmail.com>
+Link: https://lore.kernel.org/r/4e87fb741205b9f314aec739921405a7ebef908a.1618480688.git.fabioaiuto83@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a1fc19d61f66 ("staging: rtl8723bs: fix WEP length underflow and OOB read in OnAuth()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_mlme_ext.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+@@ -835,7 +835,8 @@ unsigned int OnBeacon(struct adapter *pa
+                               ret = rtw_check_bcn_info(padapter, pframe, len);
+                               if (!ret) {
+                                               DBG_871X_LEVEL(_drv_always_, "ap has changed, disconnect now\n ");
+-                                              receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 0);
++                                              receive_disconnect(padapter,
++                                                                 pmlmeinfo->network.MacAddress, 0);
+                                               return _SUCCESS;
+                               }
+                               /* update WMM, ERP in the beacon */
diff --git a/queue-5.10/usb-atm-ueagle-atm-wait-for-pre-firmware-load-in-.disconnect.patch b/queue-5.10/usb-atm-ueagle-atm-wait-for-pre-firmware-load-in-.disconnect.patch
new file mode 100644 (file)
index 0000000..d57b594
--- /dev/null
@@ -0,0 +1,175 @@
+From stable+bounces-277539-greg=kroah.com@vger.kernel.org Mon Jul 20 04:35:55 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 22:35:43 -0400
+Subject: usb: atm: ueagle-atm: wait for pre-firmware load in .disconnect()
+To: stable@vger.kernel.org
+Cc: Mauricio Faria de Oliveira <mfo@igalia.com>, stable <stable@kernel.org>, syzbot+ce1e5a1b4e086b43e56d@syzkaller.appspotmail.com, syzbot+306212936b13e520679d@syzkaller.appspotmail.com, syzbot+457452d30bcdda75ead2@syzkaller.appspotmail.com, Andrey Tsygunka <aitsygunka@yandex.ru>, Stanislaw Gruszka <stf_xl@wp.pl>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260720023543.2969189-1-sashal@kernel.org>
+
+From: Mauricio Faria de Oliveira <mfo@igalia.com>
+
+[ Upstream commit e2674dfbed8a30d57e2bc872c4bfa6c3eec918bf ]
+
+ueagle-atm uses the asynchronous request_firmware_nowait() in .probe(),
+but does not wait for its completion, not even in .disconnect(); so, if the
+device is unplugged meanwhile, its teardown runs concurrently with that.
+
+Even though this inconsistency is worth addressing on its own, it has also
+triggered several bug reports in syzbot over the years (some auto-closed)
+where the firmware sysfs fallback mechanism (CONFIG_FW_LOADER_USER_HELPER)
+creates a firmware subdirectory in the device directory during its removal,
+which might hit unexpected conditions in kernfs, apparently, depending at
+which point the add and remove operations raced. (See links.)
+
+The pattern is:
+
+usb ?-?: Direct firmware load for ueagle-atm/eagle?.fw failed with error -2
+usb ?-?: Falling back to sysfs fallback for: ueagle-atm/eagle?.fw
+<ERROR>
+Call trace:
+ ...
+ kernfs_create_dir_ns
+ sysfs_create_dir_ns
+ create_dir
+ kobject_add_internal
+ kobject_add_varg
+ kobject_add
+ class_dir_create_and_add
+ get_device_parent
+ device_add
+ fw_load_sysfs_fallback
+ fw_load_from_user_helper
+ firmware_fallback_sysfs
+ _request_firmware
+ request_firmware_work_func
+ ...
+
+(Some variations are observed, after fw_load_sysfs_fallback(), e.g., [1].)
+
+While the kernfs side is being looked at, the ueagle-atm side can be fixed
+by waiting for the pre-firmware load in the .disconnect() handler.
+
+This change has a similar approach to previous work by Andrey Tsygunka [2]
+(wait_for_completion() in .disconnect()), but it is relatively different in
+design/implementation; using the Originally-by tag for credit assignment.
+
+This has been tested with:
+- synthetic reproducer to check the error path;
+- USB gadget (virtual device) to check the firmware upload path;
+- QEMU device emulator to check the device ID re-enumeration path;
+(The latter two were written by Claude; no other code/text in this commit.)
+
+Links (year first reported):
+ 2025 https://syzbot.org/bug?extid=ce1e5a1b4e086b43e56d
+ 2025 https://syzbot.org/bug?extid=9af8471255ac36e34fd4
+ 2024 https://syzbot.org/bug?extid=306212936b13e520679d
+ 2023 https://syzkaller.appspot.com/bug?extid=457452d30bcdda75ead2
+ 2022 https://syzbot.org/bug?extid=782984d6f1701b526edb
+ 2021 https://syzbot.org/bug?id=f3f221579f4ef7e9691281f3c6f56c05f83e8490
+ 2021 https://syzbot.org/bug?id=84d86f0d71394829df6fc53daf6642c045983881
+ 2021 https://syzbot.org/bug?id=3302dc1c0e2b9c94f2e8edb404eabc9267bc6f90
+
+[1] https://syzkaller.appspot.com/bug?extid=457452d30bcdda75ead2
+[2] https://lore.kernel.org/lkml/20250410093146.3776801-2-aitsygunka@yandex.ru/
+
+Cc: stable <stable@kernel.org>
+Reported-by: syzbot+ce1e5a1b4e086b43e56d@syzkaller.appspotmail.com
+Closes: https://syzbot.org/bug?extid=ce1e5a1b4e086b43e56d
+Reported-by: syzbot+306212936b13e520679d@syzkaller.appspotmail.com
+Closes: https://syzbot.org/bug?extid=306212936b13e520679d
+Reported-by: syzbot+457452d30bcdda75ead2@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=457452d30bcdda75ead2
+Originally-by: Andrey Tsygunka <aitsygunka@yandex.ru>
+Fixes: b72458a80c75 ("[PATCH] USB: Eagle and ADI 930 usb adsl modem driver")
+Assisted-by: Claude:claude-opus-4.7 # usb gadget & qemu device for testing
+Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>
+Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
+Link: https://patch.msgid.link/20260526-ueagle-atm_req-fw-sync-v3-1-93c01961daaf@igalia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/atm/ueagle-atm.c |   36 +++++++++++++++++++++++++++++++-----
+ 1 file changed, 31 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/atm/ueagle-atm.c
++++ b/drivers/usb/atm/ueagle-atm.c
+@@ -599,7 +599,9 @@ static int uea_send_modem_cmd(struct usb
+ static void uea_upload_pre_firmware(const struct firmware *fw_entry,
+                                                               void *context)
+ {
+-      struct usb_device *usb = context;
++      struct usb_interface *intf = context;
++      struct usb_device *usb = interface_to_usbdev(intf);
++      struct completion *fw_done = usb_get_intfdata(intf);
+       const u8 *pfw;
+       u8 value;
+       u32 crc = 0;
+@@ -670,15 +672,17 @@ err_fw_corrupted:
+ err:
+       release_firmware(fw_entry);
+       uea_leaves(usb);
++      complete(fw_done);
+ }
+ /*
+  * uea_load_firmware - Load usb firmware for pre-firmware devices.
+  */
+-static int uea_load_firmware(struct usb_device *usb, unsigned int ver)
++static int uea_load_firmware(struct usb_interface *intf, unsigned int ver)
+ {
+       int ret;
+       char *fw_name = EAGLE_FIRMWARE;
++      struct usb_device *usb = interface_to_usbdev(intf);
+       uea_enters(usb);
+       uea_info(usb, "pre-firmware device, uploading firmware\n");
+@@ -702,7 +706,7 @@ static int uea_load_firmware(struct usb_
+       }
+       ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev,
+-                                      GFP_KERNEL, usb,
++                                      GFP_KERNEL, intf,
+                                       uea_upload_pre_firmware);
+       if (ret)
+               uea_err(usb, "firmware %s is not available\n", fw_name);
+@@ -2598,8 +2602,23 @@ static int uea_probe(struct usb_interfac
+       usb_reset_device(usb);
+-      if (UEA_IS_PREFIRM(id))
+-              return uea_load_firmware(usb, UEA_CHIP_VERSION(id));
++      if (UEA_IS_PREFIRM(id)) {
++              struct completion *fw_done;
++
++              /* Wait for the firmware load to be done, in .disconnect() */
++              fw_done = kzalloc(sizeof(*fw_done), GFP_KERNEL);
++              if (!fw_done)
++                      return -ENOMEM;
++
++              init_completion(fw_done);
++              usb_set_intfdata(intf, fw_done);
++
++              ret = uea_load_firmware(intf, UEA_CHIP_VERSION(id));
++              if (ret)
++                      kfree(fw_done);
++
++              return ret;
++      }
+       ret = usbatm_usb_probe(intf, id, &uea_usbatm_driver);
+       if (ret == 0) {
+@@ -2630,6 +2649,13 @@ static void uea_disconnect(struct usb_in
+               usbatm_usb_disconnect(intf);
+               mutex_unlock(&uea_mutex);
+               uea_info(usb, "ADSL device removed\n");
++      } else if (usb->config->desc.bNumInterfaces == 1) {
++              struct completion *fw_done = usb_get_intfdata(intf);
++
++              uea_dbg(usb, "pre-firmware device, waiting firmware upload\n");
++              wait_for_completion(fw_done);
++              uea_dbg(usb, "pre-firmware device, finished waiting\n");
++              kfree(fw_done);
+       }
+       uea_leaves(usb);
diff --git a/queue-5.10/usb-free-iso-schedules-on-failed-submit.patch b/queue-5.10/usb-free-iso-schedules-on-failed-submit.patch
new file mode 100644 (file)
index 0000000..478aece
--- /dev/null
@@ -0,0 +1,110 @@
+From stable+bounces-277457-greg=kroah.com@vger.kernel.org Sun Jul 19 16:53:53 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 10:53:46 -0400
+Subject: usb: free iso schedules on failed submit
+To: stable@vger.kernel.org
+Cc: Dawei Feng <dawei.feng@seu.edu.cn>, stable <stable@kernel.org>, Alan Stern <stern@rowland.harvard.edu>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260719145346.5460-1-sashal@kernel.org>
+
+From: Dawei Feng <dawei.feng@seu.edu.cn>
+
+[ Upstream commit b9399d25fbb34a05bbe76eeedd730f62ff2670e9 ]
+
+EHCI and FOTG210 isochronous submits build an ehci_iso_sched before
+linking the URB to the endpoint queue, and keep the staged schedule in
+urb->hcpriv until iso_stream_schedule() and the link helpers consume it.
+If the controller is no longer accessible, or usb_hcd_link_urb_to_ep()
+fails, submit jumps to done_not_linked before that handoff happens and
+leaks the staged schedule still attached to urb->hcpriv.
+
+Free the staged schedule from done_not_linked when submit fails before
+the URB is linked and clear urb->hcpriv after the free.
+
+The bug was first flagged by an experimental analysis tool we are
+developing for kernel memory-management bugs while analyzing
+v6.13-rc1. The tool is still under development and is not yet publicly
+available. Manual inspection confirms that the bug is still
+present in v7.1.1.
+
+An x86_64 allyesconfig build showed no new warnings. As we do not have an
+EHCI host controller with a USB isochronous device to test with, no
+runtime testing was able to be performed.
+
+Fixes: 8de98402652c ("[PATCH] USB: Fix USB suspend/resume crasher (#2)")
+Fixes: e9df41c5c589 ("USB: make HCDs responsible for managing endpoint queues")
+Fixes: 7d50195f6c50 ("usb: host: Faraday fotg210-hcd driver")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
+Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://patch.msgid.link/20260630071419.349161-1-dawei.feng@seu.edu.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/ehci-sched.c  |   11 +++++++++--
+ drivers/usb/host/fotg210-hcd.c |    6 ++++--
+ 2 files changed, 13 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/host/ehci-sched.c
++++ b/drivers/usb/host/ehci-sched.c
+@@ -1613,6 +1613,7 @@ iso_stream_schedule(
+                       status = 1;     /* and give it back immediately */
+                       iso_sched_free(stream, sched);
+                       sched = NULL;
++                      urb->hcpriv = NULL;
+               }
+       }
+       urb->error_count = skip / period;
+@@ -1643,8 +1644,6 @@ iso_stream_schedule(
+       return status;
+  fail:
+-      iso_sched_free(stream, sched);
+-      urb->hcpriv = NULL;
+       return status;
+ }
+@@ -1956,6 +1955,10 @@ static int itd_submit(struct ehci_hcd *e
+               usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
+       }
+  done_not_linked:
++      if (status < 0) {
++              iso_sched_free(stream, urb->hcpriv);
++              urb->hcpriv = NULL;
++      }
+       spin_unlock_irqrestore(&ehci->lock, flags);
+  done:
+       return status;
+@@ -2333,6 +2336,10 @@ static int sitd_submit(struct ehci_hcd *
+               usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
+       }
+  done_not_linked:
++      if (status < 0) {
++              iso_sched_free(stream, urb->hcpriv);
++              urb->hcpriv = NULL;
++      }
+       spin_unlock_irqrestore(&ehci->lock, flags);
+  done:
+       return status;
+--- a/drivers/usb/host/fotg210-hcd.c
++++ b/drivers/usb/host/fotg210-hcd.c
+@@ -4271,8 +4271,6 @@ static int iso_stream_schedule(struct fo
+       return 0;
+ fail:
+-      iso_sched_free(stream, sched);
+-      urb->hcpriv = NULL;
+       return status;
+ }
+@@ -4566,6 +4564,10 @@ static int itd_submit(struct fotg210_hcd
+       else
+               usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
+ done_not_linked:
++      if (status < 0) {
++              iso_sched_free(stream, urb->hcpriv);
++              urb->hcpriv = NULL;
++      }
+       spin_unlock_irqrestore(&fotg210->lock, flags);
+ done:
+       return status;
diff --git a/queue-5.10/usb-gadget-f_fs-initialize-reset_work-at-allocation-time.patch b/queue-5.10/usb-gadget-f_fs-initialize-reset_work-at-allocation-time.patch
new file mode 100644 (file)
index 0000000..0b0305f
--- /dev/null
@@ -0,0 +1,94 @@
+From sashal@kernel.org Mon Jul 20 15:59:24 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jul 2026 09:59:20 -0400
+Subject: usb: gadget: f_fs: initialize reset_work at allocation time
+To: stable@vger.kernel.org
+Cc: "Tyler Baker" <tyler.baker@oss.qualcomm.com>, stable <stable@kernel.org>, "Loic Poulain" <loic.poulain@oss.qualcomm.com>, "Dmitry Baryshkov" <dmitry.baryshkov@oss.qualcomm.com>, "Srinivas Kandagatla" <srinivas.kandagatla@oss.qualcomm.com>, "Peter Chen" <peter.chen@kernel.org>, "MichaÅ‚ Nazarewicz" <mina86@mina86.com>, "Greg Kroah-Hartman" <gregkh@linuxfoundation.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260720135920.1408367-1-sashal@kernel.org>
+
+From: Tyler Baker <tyler.baker@oss.qualcomm.com>
+
+[ Upstream commit 3137b243c93982fe3460335e12f9247739766e10 ]
+
+ffs_fs_kill_sb() unconditionally calls cancel_work_sync() on
+ffs->reset_work when a functionfs instance is unmounted:
+
+       ffs_data_reset(ffs);
+       cancel_work_sync(&ffs->reset_work);
+
+However ffs->reset_work is only ever initialized via INIT_WORK() in
+ffs_func_set_alt() and ffs_func_disable(), and only on the
+FFS_DEACTIVATED path. That state is reached solely by ffs_data_closed()
+when the instance is mounted with the "no_disconnect" option, so for the
+common case (no "no_disconnect", or mounted and unmounted without ever
+being deactivated) reset_work is never initialized.
+
+ffs_data_new() allocates the ffs_data with kzalloc_obj() and does not
+initialize reset_work, and ffs_data_reset()/ffs_data_clear() do not touch
+it either, so reset_work.func is left NULL. cancel_work_sync() on such a
+work then trips the WARN_ON(!work->func) guard in __flush_work():
+
+  WARNING: kernel/workqueue.c:4301 at __flush_work+0x330/0x360, CPU#3: umount
+  Call trace:
+   __flush_work
+   cancel_work_sync
+   ffs_fs_kill_sb [usb_f_fs]
+   deactivate_locked_super
+   deactivate_super
+   cleanup_mnt
+   __cleanup_mnt
+   task_work_run
+   exit_to_user_mode_loop
+   el0_svc
+
+On older kernels cancel_work_sync() on a zero-initialized work struct was
+a silent no-op, which hid the missing initialization.
+
+Initialize reset_work once in ffs_data_new() so it is always valid for
+the lifetime of the ffs_data, and drop the now-redundant INIT_WORK()
+calls from the two deactivation paths.
+
+Fixes: 18d6b32fca38 ("usb: gadget: f_fs: add "no_disconnect" mode")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Tyler Baker <tyler.baker@oss.qualcomm.com>
+Cc: Loic Poulain <loic.poulain@oss.qualcomm.com>
+Cc: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Cc: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
+Tested-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
+Reviewed-by: Peter Chen <peter.chen@kernel.org>
+Acked-by: MichaÅ‚ Nazarewicz <mina86@mina86.com>
+Link: https://patch.msgid.link/20260609193635.2284430-1-tyler.baker@oss.qualcomm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ dropped the ffs_func_disable hunk since 6.6 predates the disable-body split and routes disable through ffs_func_set_alt, so removing the single lazy INIT_WORK there covers both paths ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_fs.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/function/f_fs.c
++++ b/drivers/usb/gadget/function/f_fs.c
+@@ -254,6 +254,7 @@ static int ffs_acquire_dev(const char *d
+ static void ffs_release_dev(struct ffs_dev *ffs_dev);
+ static int ffs_ready(struct ffs_data *ffs);
+ static void ffs_closed(struct ffs_data *ffs);
++static void ffs_reset_work(struct work_struct *work);
+ /* Misc helper functions ****************************************************/
+@@ -1774,6 +1775,7 @@ static struct ffs_data *ffs_data_new(con
+       init_waitqueue_head(&ffs->ev.waitq);
+       init_waitqueue_head(&ffs->wait);
+       init_completion(&ffs->ep0req_completion);
++      INIT_WORK(&ffs->reset_work, ffs_reset_work);
+       /* XXX REVISIT need to update it in some places, or do we? */
+       ffs->ev.can_stall = 1;
+@@ -3330,7 +3332,6 @@ static int ffs_func_set_alt(struct usb_f
+       if (ffs->state == FFS_DEACTIVATED) {
+               ffs->state = FFS_CLOSING;
+-              INIT_WORK(&ffs->reset_work, ffs_reset_work);
+               schedule_work(&ffs->reset_work);
+               return -ENODEV;
+       }
diff --git a/queue-5.10/usb-gadget-f_fs-tie-read_buffer-lifetime-to-ffs_epfile.patch b/queue-5.10/usb-gadget-f_fs-tie-read_buffer-lifetime-to-ffs_epfile.patch
new file mode 100644 (file)
index 0000000..ae32794
--- /dev/null
@@ -0,0 +1,55 @@
+From sashal@kernel.org Mon Jul 20 17:56:43 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jul 2026 11:56:40 -0400
+Subject: usb: gadget: f_fs: Tie read_buffer lifetime to ffs_epfile
+To: stable@vger.kernel.org
+Cc: Neill Kapron <nkapron@google.com>, stable <stable@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260720155640.2425938-1-sashal@kernel.org>
+
+From: Neill Kapron <nkapron@google.com>
+
+[ Upstream commit 8bdcf96eb135aebacac319667f87db034fb38406 ]
+
+Currently, ffs_epfile_release unconditionally frees the endpoint's
+read_buffer when a file descriptor is closed. If userspace explicitly
+opens the endpoint multiple times and closes one, the read_buffer is
+destroyed. This can lead to silent data loss if other file descriptors
+are still actively reading from the endpoint.
+
+By tying the lifetime of the read_buffer to the ffs_epfile structure itself
+(which is destroyed when the functionfs instance is torn down in
+ffs_epfiles_destroy), we eliminate the brittle dependency on open/release
+calls while correctly matching the conceptual lifetime of unread data on
+the hardware endpoint.
+
+Fixes: 9353afbbfa7b ("usb: gadget: f_fs: buffer data from â€˜oversized’ OUT requests")
+Cc: stable <stable@kernel.org>
+Assisted-by: Antigravity:gemini-3.1-pro
+Signed-off-by: Neill Kapron <nkapron@google.com>
+Link: https://patch.msgid.link/20260619040609.4010746-3-nkapron@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ adjusted context in ffs_epfiles_destroy() since 6.12 lacks the simple_remove_by_name() rework and still uses dentry-based cleanup ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_fs.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/function/f_fs.c
++++ b/drivers/usb/gadget/function/f_fs.c
+@@ -1279,7 +1279,6 @@ ffs_epfile_release(struct inode *inode,
+       ENTER();
+-      __ffs_epfile_read_buffer_free(epfile);
+       ffs_data_closed(epfile->ffs);
+       return 0;
+@@ -1945,6 +1944,7 @@ static void ffs_epfiles_destroy(struct f
+       for (; count; --count, ++epfile) {
+               BUG_ON(mutex_is_locked(&epfile->mutex));
++              __ffs_epfile_read_buffer_free(epfile);
+               if (epfile->dentry) {
+                       d_delete(epfile->dentry);
+                       dput(epfile->dentry);
diff --git a/queue-5.10/usb-gadget-f_printer-take-kref-only-for-successful-open.patch b/queue-5.10/usb-gadget-f_printer-take-kref-only-for-successful-open.patch
new file mode 100644 (file)
index 0000000..560eb82
--- /dev/null
@@ -0,0 +1,46 @@
+From stable+bounces-277456-greg=kroah.com@vger.kernel.org Sun Jul 19 16:54:07 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 10:53:42 -0400
+Subject: usb: gadget: f_printer: take kref only for successful open
+To: stable@vger.kernel.org
+Cc: Xu Rao <raoxu@uniontech.com>, stable <stable@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260719145342.5397-2-sashal@kernel.org>
+
+From: Xu Rao <raoxu@uniontech.com>
+
+[ Upstream commit 30adce93d5c4a5a1ec29d9249e3fdfcc391d406b ]
+
+printer_open() returns -EBUSY when the character device is already
+open, but it increments dev->kref regardless of the return value. VFS
+does not call ->release() for a failed open, so every rejected second
+open permanently leaks one reference.
+
+Move kref_get() into the successful-open branch.
+
+Fixes: e8d5f92b8d30 ("usb: gadget: function: printer: fix use-after-free in __lock_acquire")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Xu Rao <raoxu@uniontech.com>
+Link: https://patch.msgid.link/80295742B820DA9B+20260626064617.4090626-1-raoxu@uniontech.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_printer.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_printer.c
++++ b/drivers/usb/gadget/function/f_printer.c
+@@ -358,12 +358,11 @@ printer_open(struct inode *inode, struct
+               ret = 0;
+               /* Change the printer status to show that it's on-line. */
+               dev->printer_status |= PRINTER_SELECTED;
++              kref_get(&dev->kref);
+       }
+       spin_unlock_irqrestore(&dev->lock, flags);
+-      kref_get(&dev->kref);
+-
+       return ret;
+ }
diff --git a/queue-5.10/usb-gadget-function-simplify-diagnostic-messaging-in-printer.patch b/queue-5.10/usb-gadget-function-simplify-diagnostic-messaging-in-printer.patch
new file mode 100644 (file)
index 0000000..7cba917
--- /dev/null
@@ -0,0 +1,72 @@
+From stable+bounces-277455-greg=kroah.com@vger.kernel.org Sun Jul 19 16:53:50 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 10:53:41 -0400
+Subject: usb: gadget: function: Simplify diagnostic messaging in printer
+To: stable@vger.kernel.org
+Cc: Andrzej Pietrasiewicz <andrzej.p@collabora.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260719145342.5397-1-sashal@kernel.org>
+
+From: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+
+[ Upstream commit 57b7b733b1a7aeab25bc2670afff608214284863 ]
+
+Don't issue messages which can be easily achieved with ftrace.
+In case of printer_open() the return code is propagated to other layers
+so the user will know about -EBUSY anyway.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+Link: https://lore.kernel.org/r/20221123110746.59611-1-andrzej.p@collabora.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 30adce93d5c4 ("usb: gadget: f_printer: take kref only for successful open")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_printer.c |    9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_printer.c
++++ b/drivers/usb/gadget/function/f_printer.c
+@@ -363,7 +363,7 @@ printer_open(struct inode *inode, struct
+       spin_unlock_irqrestore(&dev->lock, flags);
+       kref_get(&dev->kref);
+-      DBG(dev, "printer_open returned %x\n", ret);
++
+       return ret;
+ }
+@@ -381,7 +381,6 @@ printer_close(struct inode *inode, struc
+       spin_unlock_irqrestore(&dev->lock, flags);
+       kref_put(&dev->kref, printer_dev_free);
+-      DBG(dev, "printer_close\n");
+       return 0;
+ }
+@@ -867,8 +866,6 @@ static void printer_reset_interface(stru
+       if (dev->interface < 0)
+               return;
+-      DBG(dev, "%s\n", __func__);
+-
+       if (dev->in_ep->desc)
+               usb_ep_disable(dev->in_ep);
+@@ -906,8 +903,6 @@ static void printer_soft_reset(struct pr
+ {
+       struct usb_request      *req;
+-      INFO(dev, "Received Printer Reset Request\n");
+-
+       if (usb_ep_disable(dev->in_ep))
+               DBG(dev, "Failed to disable USB in_ep\n");
+       if (usb_ep_disable(dev->out_ep))
+@@ -1204,8 +1199,6 @@ static void printer_func_disable(struct
+ {
+       struct printer_dev *dev = func_to_printer(f);
+-      DBG(dev, "%s\n", __func__);
+-
+       printer_reset_interface(dev);
+ }
diff --git a/queue-5.10/usb-iowarrior-remove-inherent-race-with-minor-number.patch b/queue-5.10/usb-iowarrior-remove-inherent-race-with-minor-number.patch
new file mode 100644 (file)
index 0000000..782a92f
--- /dev/null
@@ -0,0 +1,109 @@
+From stable+bounces-277503-greg=kroah.com@vger.kernel.org Sun Jul 19 18:39:26 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 12:39:18 -0400
+Subject: usb: iowarrior: remove inherent race with minor number
+To: stable@vger.kernel.org
+Cc: Oliver Neukum <oneukum@suse.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260719163919.650822-1-sashal@kernel.org>
+
+From: Oliver Neukum <oneukum@suse.com>
+
+[ Upstream commit 56dd29088c9d9510c48a8ebad2465248fde36551 ]
+
+The driver saves the minor number it gets upon registration
+in its descriptor for debugging purposes. However, there is
+inevitably a window between registration and saving the correct
+minor in a descriptor. During this window the debugging output
+will be wrong.
+As wrong debug output is worse than no debug output, just
+remove it.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Link: https://patch.msgid.link/20260312094619.1590556-1-oneukum@suse.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: c602254ba4c1 ("USB: iowarrior: fix use-after-free on disconnect race")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/misc/iowarrior.c |   17 +++--------------
+ 1 file changed, 3 insertions(+), 14 deletions(-)
+
+--- a/drivers/usb/misc/iowarrior.c
++++ b/drivers/usb/misc/iowarrior.c
+@@ -74,7 +74,6 @@ struct iowarrior {
+       struct mutex mutex;                     /* locks this structure */
+       struct usb_device *udev;                /* save off the usb device pointer */
+       struct usb_interface *interface;        /* the interface for this device */
+-      unsigned char minor;                    /* the starting minor number for this device */
+       struct usb_endpoint_descriptor *int_out_endpoint;       /* endpoint for reading (needed for IOW56 only) */
+       struct usb_endpoint_descriptor *int_in_endpoint;        /* endpoint for reading */
+       struct urb *int_in_urb;         /* the urb for reading data */
+@@ -246,7 +245,6 @@ static void iowarrior_write_callback(str
+  */
+ static inline void iowarrior_delete(struct iowarrior *dev)
+ {
+-      dev_dbg(&dev->interface->dev, "minor %d\n", dev->minor);
+       kfree(dev->int_in_buffer);
+       usb_free_urb(dev->int_in_urb);
+       kfree(dev->read_queue);
+@@ -297,9 +295,6 @@ static ssize_t iowarrior_read(struct fil
+               goto exit;
+       }
+-      dev_dbg(&dev->interface->dev, "minor %d, count = %zd\n",
+-              dev->minor, count);
+-
+       /* read count must be packet size (+ time stamp) */
+       if ((count != dev->report_size)
+           && (count != (dev->report_size + 1))) {
+@@ -379,8 +374,6 @@ static ssize_t iowarrior_write(struct fi
+               retval = -ENODEV;
+               goto exit;
+       }
+-      dev_dbg(&dev->interface->dev, "minor %d, count = %zd\n",
+-              dev->minor, count);
+       /* if count is 0 we're already done */
+       if (count == 0) {
+               retval = 0;
+@@ -526,9 +519,6 @@ static long iowarrior_ioctl(struct file
+               goto error_out;
+       }
+-      dev_dbg(&dev->interface->dev, "minor %d, cmd 0x%.4x, arg %ld\n",
+-              dev->minor, cmd, arg);
+-
+       retval = 0;
+       io_res = 0;
+       switch (cmd) {
+@@ -675,8 +665,6 @@ static int iowarrior_release(struct inod
+       if (!dev)
+               return -ENODEV;
+-      dev_dbg(&dev->interface->dev, "minor %d\n", dev->minor);
+-
+       /* lock our device */
+       mutex_lock(&dev->mutex);
+@@ -779,6 +767,7 @@ static int iowarrior_probe(struct usb_in
+       struct usb_host_interface *iface_desc;
+       int retval = -ENOMEM;
+       int res;
++      int minor;
+       /* allocate memory for our device state and initialize it */
+       dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL);
+@@ -894,12 +883,12 @@ static int iowarrior_probe(struct usb_in
+               goto error;
+       }
+-      dev->minor = interface->minor;
++      minor = interface->minor;
+       /* let the user know what node this device is now attached to */
+       dev_info(&interface->dev, "IOWarrior product=0x%x, serial=%s interface=%d "
+                "now attached to iowarrior%d\n", dev->product_id, dev->chip_serial,
+-               iface_desc->desc.bInterfaceNumber, dev->minor - IOWARRIOR_MINOR_BASE);
++               iface_desc->desc.bInterfaceNumber, minor - IOWARRIOR_MINOR_BASE);
+       return retval;
+ error:
diff --git a/queue-5.10/usb-serial-digi_acceleport-fix-write-buffer-corruption.patch b/queue-5.10/usb-serial-digi_acceleport-fix-write-buffer-corruption.patch
new file mode 100644 (file)
index 0000000..216b471
--- /dev/null
@@ -0,0 +1,79 @@
+From sashal@kernel.org Sun Jul 19 20:01:32 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 14:01:28 -0400
+Subject: USB: serial: digi_acceleport: fix write buffer corruption
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260719180128.1055268-1-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 24ca1fea8f2753bf33e1d458ec1ae5d9b7796a65 ]
+
+The digi_write_inb_command() is supposed to wait for the write urb to
+become available or return an error, but instead it updates the transfer
+buffer and tries to resubmit the urb on timeout.
+
+To make things worse, for commands like break control where no timeout
+is used, the driver would corrupt the urb immediately due to a broken
+jiffies comparison (on 32-bit machines this takes five minutes of uptime
+to trigger due to INITIAL_JIFFIES).
+
+Fix this by adding the missing return on timeout and waiting
+indefinitely when no timeout has been specified as intended.
+
+This issue was (sort of) flagged by Sashiko when reviewing an unrelated
+change to the driver.
+
+Link: https://sashiko.dev/#/patchset/20260610132232.356139-1-johan%40kernel.org?part=11
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+[ adjusted context for 5.10's `&port->write_wait` (no `priv->write_wait`) and kept the existing `unsigned long flags = 0;` declaration alongside the new `expire` variable ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/serial/digi_acceleport.c |   15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/serial/digi_acceleport.c
++++ b/drivers/usb/serial/digi_acceleport.c
+@@ -431,20 +431,22 @@ static int digi_write_inb_command(struct
+       int len;
+       struct digi_port *priv = usb_get_serial_port_data(port);
+       unsigned char *data = port->write_urb->transfer_buffer;
++      unsigned long expire;
+       unsigned long flags = 0;
+       dev_dbg(&port->dev, "digi_write_inb_command: TOP: port=%d, count=%d\n",
+               priv->dp_port_num, count);
+       if (timeout)
+-              timeout += jiffies;
+-      else
+-              timeout = ULONG_MAX;
++              expire = jiffies + timeout;
+       spin_lock_irqsave(&priv->dp_port_lock, flags);
+       while (count > 0 && ret == 0) {
+-              while (priv->dp_write_urb_in_use &&
+-                     time_before(jiffies, timeout)) {
++              while (priv->dp_write_urb_in_use) {
++                      if (timeout && time_after(jiffies, expire)) {
++                              ret = -ETIMEDOUT;
++                              break;
++                      }
+                       cond_wait_interruptible_timeout_irqrestore(
+                               &port->write_wait, DIGI_RETRY_TIMEOUT,
+                               &priv->dp_port_lock, flags);
+@@ -453,6 +455,9 @@ static int digi_write_inb_command(struct
+                       spin_lock_irqsave(&priv->dp_port_lock, flags);
+               }
++              if (ret)
++                      break;
++
+               /* len must be a multiple of 4 and small enough to */
+               /* guarantee the write will send buffered data first, */
+               /* so commands are in order with data and not split */
diff --git a/queue-5.10/usb-typec-tcpm-fix-vdm-type-for-enter-mode-commands.patch b/queue-5.10/usb-typec-tcpm-fix-vdm-type-for-enter-mode-commands.patch
new file mode 100644 (file)
index 0000000..235eada
--- /dev/null
@@ -0,0 +1,39 @@
+From sashal@kernel.org Mon Jul 20 12:56:38 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jul 2026 06:54:58 -0400
+Subject: usb: typec: tcpm: Fix VDM type for Enter Mode commands
+To: stable@vger.kernel.org
+Cc: Andy Yan <andyshrk@163.com>, stable <stable@kernel.org>, Heikki Krogerus <heikki.krogerus@linux.intel.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260720105458.217218-1-sashal@kernel.org>
+
+From: Andy Yan <andyshrk@163.com>
+
+[ Upstream commit 9cff680e47632b7723cb19f9c5e63669063c3417 ]
+
+VDO() second parameter is VDM type (bit 15): 1 for SVDM, 0 for UVDM.
+Using 'vdo ? 2 : 1' corrupts SVID low bit when vdo is non-NULL
+(2 << 15 = BIT(16)). Enter Mode is always SVDM, hardcode to 1.
+
+Fixes: 8face9aa57c8 ("usb: typec: Add parameter for the VDO to typec_altmode_enter()")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Andy Yan <andyshrk@163.com>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://patch.msgid.link/20260604105059.18750-1-andyshrk@163.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/tcpm/tcpm.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -1671,7 +1671,7 @@ static int tcpm_altmode_enter(struct typ
+       struct tcpm_port *port = typec_altmode_get_drvdata(altmode);
+       u32 header;
+-      header = VDO(altmode->svid, vdo ? 2 : 1, CMD_ENTER_MODE);
++      header = VDO(altmode->svid, 1, CMD_ENTER_MODE);
+       header |= VDO_OPOS(altmode->mode);
+       tcpm_queue_vdm_unlocked(port, header, vdo, vdo ? 1 : 0);
diff --git a/queue-5.10/usb-typec-ucsi-ccg-fix-use-after-free-of-ucsi-on-remove.patch b/queue-5.10/usb-typec-ucsi-ccg-fix-use-after-free-of-ucsi-on-remove.patch
new file mode 100644 (file)
index 0000000..b104805
--- /dev/null
@@ -0,0 +1,56 @@
+From stable+bounces-277540-greg=kroah.com@vger.kernel.org Mon Jul 20 04:36:00 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jul 2026 22:35:39 -0400
+Subject: usb: typec: ucsi: ccg: Fix use-after-free of ucsi on remove
+To: stable@vger.kernel.org
+Cc: Fan Wu <fanwu01@zju.edu.cn>, stable <stable@kernel.org>, Heikki Krogerus <heikki.krogerus@linux.intel.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260720023539.2968115-5-sashal@kernel.org>
+
+From: Fan Wu <fanwu01@zju.edu.cn>
+
+[ Upstream commit 1f0bdc2884b67de337215079bba166df0cdf4ac5 ]
+
+The threaded IRQ handler ccg_irq_handler() calls ucsi_notify_common(),
+which on a connector-change event calls ucsi_connector_change() and
+schedules connector work.  In ucsi_ccg_remove(), ucsi_destroy() frees
+uc->ucsi (kfree) before free_irq() is called, so a handler invocation
+already in flight may access the freed object after ucsi_destroy().
+
+  CPU 0 (remove)            | CPU 1 (threaded IRQ)
+    ucsi_destroy(uc->ucsi)  |   ccg_irq_handler()
+      kfree(ucsi) // FREE   |     ucsi_notify_common(uc->ucsi) // USE
+
+Move free_irq() before ucsi_destroy() in the remove path.  It is kept
+after ucsi_unregister(): ucsi_unregister() cancels connector work whose
+handler issues GET_CONNECTOR_STATUS through ucsi_send_command_common(),
+which waits for a completion that is signalled from the IRQ handler, so
+the IRQ must stay active until that work has been cancelled.
+
+The probe error path already orders free_irq() before ucsi_destroy().
+
+This bug was found by static analysis.
+
+Fixes: e32fd989ac1c ("usb: typec: ucsi: ccg: Move to the new API")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://patch.msgid.link/20260616132011.103279-1-fanwu01@zju.edu.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/ucsi/ucsi_ccg.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/typec/ucsi/ucsi_ccg.c
++++ b/drivers/usb/typec/ucsi/ucsi_ccg.c
+@@ -1418,8 +1418,8 @@ static int ucsi_ccg_remove(struct i2c_cl
+       cancel_work_sync(&uc->work);
+       pm_runtime_disable(uc->dev);
+       ucsi_unregister(uc->ucsi);
+-      ucsi_destroy(uc->ucsi);
+       free_irq(uc->irq, uc);
++      ucsi_destroy(uc->ucsi);
+       return 0;
+ }
diff --git a/queue-5.10/vfio-pci-release-the-vga-arbiter-client-on-register_device-failure.patch b/queue-5.10/vfio-pci-release-the-vga-arbiter-client-on-register_device-failure.patch
new file mode 100644 (file)
index 0000000..ff3c60d
--- /dev/null
@@ -0,0 +1,46 @@
+From stable+bounces-274251-greg=kroah.com@vger.kernel.org Tue Jul 14 15:44:56 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 09:40:09 -0400
+Subject: vfio/pci: Release the VGA arbiter client on register_device() failure
+To: stable@vger.kernel.org
+Cc: Alex Williamson <alex.williamson@nvidia.com>, Kevin Tian <kevin.tian@intel.com>, Alex Williamson <alex@shazbot.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260714134009.2674596-1-sashal@kernel.org>
+
+From: Alex Williamson <alex.williamson@nvidia.com>
+
+[ Upstream commit daedde7f024ecf88bc8e832ed40cf2c795f0796a ]
+
+The re-order in the Fixes commit below displaced vfio_pci_vga_init() as
+the last failure point of what is now vfio_pci_core_register_device()
+without introducing an unwind for the VGA arbiter registration.
+
+In current kernels this is mostly benign because vfio_pci_set_decode()
+only uses pci_dev state, but the original failure path could leave a
+callback with a freed vdev cookie.  The stale registration also becomes
+unsafe again once the callback follows drvdata to the vfio device.
+
+Add the required VGA unwind callout.
+
+Fixes: 4aeec3984ddc ("vfio/pci: Re-order vfio_pci_probe()")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Alex Williamson <alex.williamson@nvidia.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Link: https://lore.kernel.org/r/20260615191241.688297-3-alex.williamson@nvidia.com
+Signed-off-by: Alex Williamson <alex@shazbot.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/vfio/pci/vfio_pci.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/vfio/pci/vfio_pci.c
++++ b/drivers/vfio/pci/vfio_pci.c
+@@ -2094,6 +2094,7 @@ static int vfio_pci_probe(struct pci_dev
+ out_power:
+       if (!disable_idle_d3)
+               vfio_pci_set_power_state(vdev, PCI_D0);
++      vfio_pci_vga_uninit(vdev);
+ out_vf:
+       vfio_pci_vf_uninit(vdev);
+ out_reflck:
diff --git a/queue-5.10/writeback-fix-race-between-cgroup_writeback_umount-and-inode_switch_wbs.patch b/queue-5.10/writeback-fix-race-between-cgroup_writeback_umount-and-inode_switch_wbs.patch
new file mode 100644 (file)
index 0000000..9eaba4d
--- /dev/null
@@ -0,0 +1,149 @@
+From stable+bounces-276823-greg=kroah.com@vger.kernel.org Thu Jul 16 21:49:41 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jul 2026 15:49:31 -0400
+Subject: writeback: fix race between cgroup_writeback_umount() and inode_switch_wbs()
+To: stable@vger.kernel.org
+Cc: Baokun Li <libaokun@linux.alibaba.com>, Jan Kara <jack@suse.cz>, Tejun Heo <tj@kernel.org>, "Christian Brauner (Amutable)" <brauner@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260716194931.1111583-1-sashal@kernel.org>
+
+From: Baokun Li <libaokun@linux.alibaba.com>
+
+[ Upstream commit cba38ec4cbd3a7b8b942a8d52531a05be8a9ff0d ]
+
+When a container exits, the following BUG_ON() is occasionally triggered:
+
+==================================================================
+ VFS: Busy inodes after unmount of sdb (ext4)
+ ------------[ cut here ]------------
+ kernel BUG at fs/super.c:695!
+ CPU: 3 PID: 6 Comm: containerd-shim Tainted: G OE K 6.6 #1
+ pstate: 63400009 (nZCv daif +PAN -UAO +TCO +DIT -SSBS BTYPE=--)
+ pc : generic_shutdown_super+0xf0/0x100
+ lr : generic_shutdown_super+0xf0/0x100
+ Call trace:
+  generic_shutdown_super+0xf0/0x100
+  kill_block_super+0x20/0x48
+  ext4_kill_sb+0x28/0x60
+  deactivate_locked_super+0x54/0x130
+  deactivate_super+0x84/0xa0
+  cleanup_mnt+0xa4/0x140
+  __cleanup_mnt+0x18/0x28
+  task_work_run+0x78/0xe0
+  do_notify_resume+0x204/0x240
+==================================================================
+
+The root cause is a race between cgroup_writeback_umount() and
+inode_switch_wbs()/cleanup_offline_cgwb(). There is a window between
+inode_prepare_wbs_switch() returning true and the subsequent
+wb_queue_isw() call. Following is the process that triggers the issue:
+
+      CPU A (umount)           |          CPU B (writeback)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                                 inode_switch_wbs/cleanup_offline_cgwb
+                                  atomic_inc(&isw_nr_in_flight)
+                                  inode_prepare_wbs_switch
+                                   -> passes SB_ACTIVE check
+                                   __iget(inode)
+ generic_shutdown_super
+  sb->s_flags &= ~SB_ACTIVE
+  cgroup_writeback_umount(sb)
+   smp_mb()
+   atomic_read(&isw_nr_in_flight)
+   rcu_barrier()
+    -> no pending RCU callbacks
+   flush_workqueue(isw_wq)
+    -> nothing queued, returns
+  evict_inodes(sb)
+   -> Inode skipped as isw still holds a ref.
+  sop->put_super(sb)
+   /* destroys percpu counters */
+  -> VFS: Busy inodes after unmount!
+                                  wb_queue_isw()
+                                   queue_work(isw_wq, ...)
+                                  /* later in work function */
+                                  inode_switch_wbs_work_fn
+                                   process_inode_switch_wbs
+                                    iput() -> evict
+                                     percpu_counter_dec() // UAF!
+
+Fix this by extending the RCU read-side critical section in
+inode_switch_wbs() and cleanup_offline_cgwb() to cover from
+inode_prepare_wbs_switch() through wb_queue_isw().  Since there is
+no sleep in this window, rcu_read_lock() can be used.  Then add a
+synchronize_rcu() in cgroup_writeback_umount() before the existing
+rcu_barrier(), so that all in-flight switchers that have passed the
+SB_ACTIVE check have completed queue_work() before flush_workqueue()
+is called.
+
+The existing rcu_barrier() is intentionally retained so this fix can
+be backported unchanged to stable kernels (5.10.y, 6.6.y, ...) that
+still queue switches via queue_rcu_work(). It is a no-op on current
+mainline (since commit e1b849cfa6b6 ("writeback: Avoid contention on
+wb->list_lock when switching inodes")) and is removed in a follow-up
+patch.
+
+Fixes: a1a0e23e4903 ("writeback: flush inode cgroup wb switches instead of pinning super_block")
+Cc: stable@vger.kernel.org
+Suggested-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/all/mxnjq2l6guusfchvauxr3v7c4bwjasybxlleqbbh4efloeqspz@iqylk76ohufz
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
+Link: https://patch.msgid.link/20260521095016.2791354-2-libaokun@linux.alibaba.com
+Acked-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/fs-writeback.c |   20 ++++++++++++++++++--
+ 1 file changed, 18 insertions(+), 2 deletions(-)
+
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -507,12 +507,18 @@ static void inode_switch_wbs(struct inod
+       atomic_inc(&isw_nr_in_flight);
+-      /* find and pin the new wb */
++      /*
++       * Paired with synchronize_rcu() in cgroup_writeback_umount():
++       * holding rcu_read_lock across the SB_ACTIVE check, the inode
++       * grab and call_rcu() ensures synchronize_rcu() cannot return
++       * until the switch is queued, so the subsequent rcu_barrier()
++       * and flush_workqueue() will wait for the switch.
++       */
+       rcu_read_lock();
++      /* find and pin the new wb */
+       memcg_css = css_from_id(new_wb_id, &memory_cgrp_subsys);
+       if (memcg_css && !css_tryget(memcg_css))
+               memcg_css = NULL;
+-      rcu_read_unlock();
+       if (!memcg_css)
+               goto out_free;
+@@ -542,9 +548,11 @@ static void inode_switch_wbs(struct inod
+        * Let's continue after I_WB_SWITCH is guaranteed to be visible.
+        */
+       call_rcu(&isw->rcu_head, inode_switch_wbs_rcu_fn);
++      rcu_read_unlock();
+       return;
+ out_free:
++      rcu_read_unlock();
+       atomic_dec(&isw_nr_in_flight);
+       if (isw->new_wb)
+               wb_put(isw->new_wb);
+@@ -1011,6 +1019,14 @@ void cgroup_writeback_umount(void)
+ {
+       if (atomic_read(&isw_nr_in_flight)) {
+               /*
++               * Paired with rcu_read_lock() in inode_switch_wbs().
++               * synchronize_rcu() waits for any in-flight switcher that
++               * already passed the SB_ACTIVE check to finish calling
++               * call_rcu(), so the rcu_barrier() and flush_workqueue()
++               * below will then drain it.
++               */
++              synchronize_rcu();
++              /*
+                * Use rcu_barrier() to wait for all pending callbacks to
+                * ensure that all in-flight wb switches are in the workqueue.
+                */
diff --git a/queue-5.10/x.509-fix-validation-of-asn.1-certificate-header.patch b/queue-5.10/x.509-fix-validation-of-asn.1-certificate-header.patch
new file mode 100644 (file)
index 0000000..a69f8e1
--- /dev/null
@@ -0,0 +1,44 @@
+From stable+bounces-276826-greg=kroah.com@vger.kernel.org Thu Jul 16 21:54:31 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jul 2026 15:54:23 -0400
+Subject: X.509: Fix validation of ASN.1 certificate header
+To: stable@vger.kernel.org
+Cc: Lukas Wunner <lukas@wunner.de>, Sashiko <sashiko-bot@kernel.org>, Ignat Korchagin <ignat@linux.win>, Alistair Francis <alistair.francis@wdc.com>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260716195423.1113794-1-sashal@kernel.org>
+
+From: Lukas Wunner <lukas@wunner.de>
+
+[ Upstream commit 3b626ba431c4501512ad07549310685e07fe4706 ]
+
+x509_load_certificate_list() seeks to enforce that a certificate starts
+with 0x30 0x82 (ASN.1 SEQUENCE tag followed by a length of more than 256
+and less than 65535 bytes).
+
+But it only enforces that *either* of those two byte values are present,
+instead of checking for the *conjunction* of the two values.  Fix it.
+
+Fixes: 631cc66eb9ea ("MODSIGN: Provide module signing public keys to the kernel")
+Reported-by: Sashiko <sashiko-bot@kernel.org>
+Closes: https://lore.kernel.org/r/20260508033917.B5873C2BCB0@smtp.kernel.org/
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: stable@vger.kernel.org # v3.7+
+Reviewed-by: Ignat Korchagin <ignat@linux.win>
+Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ certs/common.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/certs/common.c
++++ b/certs/common.c
+@@ -20,7 +20,7 @@ int load_certificate_list(const u8 cert_
+                */
+               if (end - p < 4)
+                       goto dodgy_cert;
+-              if (p[0] != 0x30 &&
++              if (p[0] != 0x30 ||
+                   p[1] != 0x82)
+                       goto dodgy_cert;
+               plen = (p[2] << 8) | p[3];
diff --git a/queue-5.10/xfs-fix-unreachable-bigtime-check-in-dquot-flush-validation.patch b/queue-5.10/xfs-fix-unreachable-bigtime-check-in-dquot-flush-validation.patch
new file mode 100644 (file)
index 0000000..39c0987
--- /dev/null
@@ -0,0 +1,63 @@
+From stable+bounces-277293-greg=kroah.com@vger.kernel.org Sat Jul 18 13:21:00 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jul 2026 07:20:48 -0400
+Subject: xfs: fix unreachable BIGTIME check in dquot flush validation
+To: stable@vger.kernel.org
+Cc: Alexey Nepomnyashih <sdl@nppct.ru>, "Darrick J. Wong" <djwong@kernel.org>, Allison Henderson <achender@kernel.org>, Carlos Maiolino <cem@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260718112048.2959902-2-sashal@kernel.org>
+
+From: Alexey Nepomnyashih <sdl@nppct.ru>
+
+[ Upstream commit 03866d130ed33ab68cc7faaf4bf2c4abef96d42e ]
+
+The dqp->q_id == 0 check inside the XFS_DQTYPE_BIGTIME block is
+unreachable because root dquots return successfully earlier. Reject root
+dquots with XFS_DQTYPE_BIGTIME before that early return, preserving the
+intended validation and removing the unreachable condition.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 4ea1ff3b4968 ("xfs: widen ondisk quota expiration timestamps to handle y2038+")
+Cc: stable@vger.kernel.org # v5.10+
+Signed-off-by: Alexey Nepomnyashih <sdl@nppct.ru>
+Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
+Reviewed-by: Allison Henderson <achender@kernel.org>
+Signed-off-by: Carlos Maiolino <cem@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/xfs_dquot.c |   16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/fs/xfs/xfs_dquot.c
++++ b/fs/xfs/xfs_dquot.c
+@@ -1201,6 +1201,14 @@ xfs_qm_dqflush_check(
+           type != XFS_DQTYPE_PROJ)
+               return __this_address;
++      /* bigtime flag should never be set on root dquots */
++      if (dqp->q_type & XFS_DQTYPE_BIGTIME) {
++              if (!xfs_has_bigtime(dqp->q_mount))
++                      return __this_address;
++              if (dqp->q_id == 0)
++                      return __this_address;
++      }
++
+       if (dqp->q_id == 0)
+               return NULL;
+@@ -1216,14 +1224,6 @@ xfs_qm_dqflush_check(
+           !dqp->q_rtb.timer)
+               return __this_address;
+-      /* bigtime flag should never be set on root dquots */
+-      if (dqp->q_type & XFS_DQTYPE_BIGTIME) {
+-              if (!xfs_has_bigtime(dqp->q_mount))
+-                      return __this_address;
+-              if (dqp->q_id == 0)
+-                      return __this_address;
+-      }
+-
+       return NULL;
+ }
diff --git a/queue-5.10/xfs-reflect-sb-features-in-xfs_mount.patch b/queue-5.10/xfs-reflect-sb-features-in-xfs_mount.patch
new file mode 100644 (file)
index 0000000..82151bc
--- /dev/null
@@ -0,0 +1,270 @@
+From stable+bounces-277292-greg=kroah.com@vger.kernel.org Sat Jul 18 13:20:58 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jul 2026 07:20:47 -0400
+Subject: xfs: reflect sb features in xfs_mount
+To: stable@vger.kernel.org
+Cc: Dave Chinner <dchinner@redhat.com>, Christoph Hellwig <hch@lst.de>, "Darrick J. Wong" <djwong@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260718112048.2959902-1-sashal@kernel.org>
+
+From: Dave Chinner <dchinner@redhat.com>
+
+[ Upstream commit a1d86e8dec8c1325d301c9d5594bb794bc428fc3 ]
+
+Currently on-disk feature checks require decoding the superblock
+fileds and so can be non-trivial. We have almost 400 hundred
+individual feature checks in the XFS code, so this is a significant
+amount of code. To reduce runtime check overhead, pre-process all
+the version flags into a features field in the xfs_mount at mount
+time so we can convert all the feature checks to a simple flag
+check.
+
+There is also a need to convert the dynamic feature flags to update
+the m_features field. This is required for attr, attr2 and quota
+features. New xfs_mount based wrappers are added for this.
+
+Signed-off-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Stable-dep-of: 03866d130ed3 ("xfs: fix unreachable BIGTIME check in dquot flush validation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/libxfs/xfs_format.h |    2 -
+ fs/xfs/libxfs/xfs_sb.c     |   64 ++++++++++++++++++++++++++++++++++++++
+ fs/xfs/libxfs/xfs_sb.h     |    1 
+ fs/xfs/xfs_dquot.c         |    2 -
+ fs/xfs/xfs_log_recover.c   |    1 
+ fs/xfs/xfs_mount.c         |    1 
+ fs/xfs/xfs_mount.h         |   75 +++++++++++++++++++++++++++++++++++++++++++++
+ fs/xfs/xfs_rtalloc.c       |    3 +
+ 8 files changed, 147 insertions(+), 2 deletions(-)
+
+--- a/fs/xfs/libxfs/xfs_format.h
++++ b/fs/xfs/libxfs/xfs_format.h
+@@ -412,7 +412,7 @@ static inline bool xfs_sb_version_haspro
+               (sbp->sb_features2 & XFS_SB_VERSION2_PROJID32BIT));
+ }
+-static inline void xfs_sb_version_addprojid32bit(struct xfs_sb *sbp)
++static inline void xfs_sb_version_addprojid32(struct xfs_sb *sbp)
+ {
+       sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT;
+       sbp->sb_features2 |= XFS_SB_VERSION2_PROJID32BIT;
+--- a/fs/xfs/libxfs/xfs_sb.c
++++ b/fs/xfs/libxfs/xfs_sb.c
+@@ -91,6 +91,70 @@ xfs_perag_put(
+       trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_);
+ }
++uint64_t
++xfs_sb_version_to_features(
++      struct xfs_sb   *sbp)
++{
++      uint64_t        features = 0;
++
++      /* optional V4 features */
++      if (sbp->sb_rblocks > 0)
++              features |= XFS_FEAT_REALTIME;
++      if (sbp->sb_versionnum & XFS_SB_VERSION_ATTRBIT)
++              features |= XFS_FEAT_ATTR;
++      if (sbp->sb_versionnum & XFS_SB_VERSION_QUOTABIT)
++              features |= XFS_FEAT_QUOTA;
++      if (sbp->sb_versionnum & XFS_SB_VERSION_ALIGNBIT)
++              features |= XFS_FEAT_ALIGN;
++      if (sbp->sb_versionnum & XFS_SB_VERSION_LOGV2BIT)
++              features |= XFS_FEAT_LOGV2;
++      if (sbp->sb_versionnum & XFS_SB_VERSION_DALIGNBIT)
++              features |= XFS_FEAT_DALIGN;
++      if (sbp->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT)
++              features |= XFS_FEAT_EXTFLG;
++      if (sbp->sb_versionnum & XFS_SB_VERSION_SECTORBIT)
++              features |= XFS_FEAT_SECTOR;
++      if (sbp->sb_versionnum & XFS_SB_VERSION_BORGBIT)
++              features |= XFS_FEAT_ASCIICI;
++      if (sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) {
++              if (sbp->sb_features2 & XFS_SB_VERSION2_LAZYSBCOUNTBIT)
++                      features |= XFS_FEAT_LAZYSBCOUNT;
++              if (sbp->sb_features2 & XFS_SB_VERSION2_ATTR2BIT)
++                      features |= XFS_FEAT_ATTR2;
++              if (sbp->sb_features2 & XFS_SB_VERSION2_PROJID32BIT)
++                      features |= XFS_FEAT_PROJID32;
++              if (sbp->sb_features2 & XFS_SB_VERSION2_FTYPE)
++                      features |= XFS_FEAT_FTYPE;
++      }
++
++      if (XFS_SB_VERSION_NUM(sbp) != XFS_SB_VERSION_5)
++              return features;
++
++      /* Always on V5 features */
++      features |= XFS_FEAT_ALIGN | XFS_FEAT_LOGV2 | XFS_FEAT_EXTFLG |
++                  XFS_FEAT_LAZYSBCOUNT | XFS_FEAT_ATTR2 | XFS_FEAT_PROJID32 |
++                  XFS_FEAT_V3INODES | XFS_FEAT_CRC | XFS_FEAT_PQUOTINO;
++
++      /* Optional V5 features */
++      if (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_FINOBT)
++              features |= XFS_FEAT_FINOBT;
++      if (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_RMAPBT)
++              features |= XFS_FEAT_RMAPBT;
++      if (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_REFLINK)
++              features |= XFS_FEAT_REFLINK;
++      if (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_INOBTCNT)
++              features |= XFS_FEAT_INOBTCNT;
++      if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_FTYPE)
++              features |= XFS_FEAT_FTYPE;
++      if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_SPINODES)
++              features |= XFS_FEAT_SPINODES;
++      if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_META_UUID)
++              features |= XFS_FEAT_META_UUID;
++      if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_BIGTIME)
++              features |= XFS_FEAT_BIGTIME;
++      return features;
++}
++
+ /* Check all the superblock fields we care about when reading one in. */
+ STATIC int
+ xfs_validate_sb_read(
+--- a/fs/xfs/libxfs/xfs_sb.h
++++ b/fs/xfs/libxfs/xfs_sb.h
+@@ -29,6 +29,7 @@ extern void  xfs_sb_mount_common(struct x
+ extern void   xfs_sb_from_disk(struct xfs_sb *to, struct xfs_dsb *from);
+ extern void   xfs_sb_to_disk(struct xfs_dsb *to, struct xfs_sb *from);
+ extern void   xfs_sb_quota_from_disk(struct xfs_sb *sbp);
++extern uint64_t       xfs_sb_version_to_features(struct xfs_sb *sbp);
+ extern int    xfs_update_secondary_sbs(struct xfs_mount *mp);
+--- a/fs/xfs/xfs_dquot.c
++++ b/fs/xfs/xfs_dquot.c
+@@ -1218,7 +1218,7 @@ xfs_qm_dqflush_check(
+       /* bigtime flag should never be set on root dquots */
+       if (dqp->q_type & XFS_DQTYPE_BIGTIME) {
+-              if (!xfs_sb_version_hasbigtime(&dqp->q_mount->m_sb))
++              if (!xfs_has_bigtime(dqp->q_mount))
+                       return __this_address;
+               if (dqp->q_id == 0)
+                       return __this_address;
+--- a/fs/xfs/xfs_log_recover.c
++++ b/fs/xfs/xfs_log_recover.c
+@@ -3325,6 +3325,7 @@ xlog_do_recover(
+       xfs_buf_relse(bp);
+       /* re-initialise in-core superblock and geometry structures */
++      mp->m_features |= xfs_sb_version_to_features(sbp);
+       xfs_reinit_percpu_counters(mp);
+       error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
+       if (error) {
+--- a/fs/xfs/xfs_mount.c
++++ b/fs/xfs/xfs_mount.c
+@@ -345,6 +345,7 @@ reread:
+               goto reread;
+       }
++      mp->m_features |= xfs_sb_version_to_features(sbp);
+       xfs_reinit_percpu_counters(mp);
+       /* no need to be quiet anymore, so reset the buf ops */
+--- a/fs/xfs/xfs_mount.h
++++ b/fs/xfs/xfs_mount.h
+@@ -131,6 +131,7 @@ typedef struct xfs_mount {
+       int                     m_fixedfsid[2]; /* unchanged for life of FS */
+       uint                    m_qflags;       /* quota status flags */
+       uint64_t                m_flags;        /* global mount flags */
++      uint64_t                m_features;     /* active filesystem features */
+       int64_t                 m_low_space[XFS_LOWSP_MAX];
+       struct xfs_ino_geometry m_ino_geo;      /* inode geometry */
+       struct xfs_trans_resv   m_resv;         /* precomputed res values */
+@@ -222,6 +223,80 @@ typedef struct xfs_mount {
+ #define M_IGEO(mp)            (&(mp)->m_ino_geo)
+ /*
++ * Flags for m_features.
++ *
++ * These are all the active features in the filesystem, regardless of how
++ * they are configured.
++ */
++#define XFS_FEAT_ATTR         (1ULL << 0)     /* xattrs present in fs */
++#define XFS_FEAT_NLINK                (1ULL << 1)     /* 32 bit link counts */
++#define XFS_FEAT_QUOTA                (1ULL << 2)     /* quota active */
++#define XFS_FEAT_ALIGN                (1ULL << 3)     /* inode alignment */
++#define XFS_FEAT_DALIGN               (1ULL << 4)     /* data alignment */
++#define XFS_FEAT_LOGV2                (1ULL << 5)     /* version 2 logs */
++#define XFS_FEAT_SECTOR               (1ULL << 6)     /* sector size > 512 bytes */
++#define XFS_FEAT_EXTFLG               (1ULL << 7)     /* unwritten extents */
++#define XFS_FEAT_ASCIICI      (1ULL << 8)     /* ASCII only case-insens. */
++#define XFS_FEAT_LAZYSBCOUNT  (1ULL << 9)     /* Superblk counters */
++#define XFS_FEAT_ATTR2                (1ULL << 10)    /* dynamic attr fork */
++#define XFS_FEAT_PARENT               (1ULL << 11)    /* parent pointers */
++#define XFS_FEAT_PROJID32     (1ULL << 12)    /* 32 bit project id */
++#define XFS_FEAT_CRC          (1ULL << 13)    /* metadata CRCs */
++#define XFS_FEAT_V3INODES     (1ULL << 14)    /* Version 3 inodes */
++#define XFS_FEAT_PQUOTINO     (1ULL << 15)    /* non-shared proj/grp quotas */
++#define XFS_FEAT_FTYPE                (1ULL << 16)    /* inode type in dir */
++#define XFS_FEAT_FINOBT               (1ULL << 17)    /* free inode btree */
++#define XFS_FEAT_RMAPBT               (1ULL << 18)    /* reverse map btree */
++#define XFS_FEAT_REFLINK      (1ULL << 19)    /* reflinked files */
++#define XFS_FEAT_SPINODES     (1ULL << 20)    /* sparse inode chunks */
++#define XFS_FEAT_META_UUID    (1ULL << 21)    /* metadata UUID */
++#define XFS_FEAT_REALTIME     (1ULL << 22)    /* realtime device present */
++#define XFS_FEAT_INOBTCNT     (1ULL << 23)    /* inobt block counts */
++#define XFS_FEAT_BIGTIME      (1ULL << 24)    /* large timestamps */
++#define XFS_FEAT_NEEDSREPAIR  (1ULL << 25)    /* needs xfs_repair */
++
++#define __XFS_HAS_FEAT(name, NAME) \
++static inline bool xfs_has_ ## name (struct xfs_mount *mp) \
++{ \
++      return mp->m_features & XFS_FEAT_ ## NAME; \
++}
++
++/* Some features can be added dynamically so they need a set wrapper, too. */
++#define __XFS_ADD_FEAT(name, NAME) \
++      __XFS_HAS_FEAT(name, NAME); \
++static inline void xfs_add_ ## name (struct xfs_mount *mp) \
++{ \
++      mp->m_features |= XFS_FEAT_ ## NAME; \
++      xfs_sb_version_add ## name(&mp->m_sb); \
++}
++
++__XFS_HAS_FEAT(nlink, NLINK)
++__XFS_ADD_FEAT(quota, QUOTA)
++__XFS_HAS_FEAT(align, ALIGN)
++__XFS_HAS_FEAT(dalign, DALIGN)
++__XFS_HAS_FEAT(logv2, LOGV2)
++__XFS_HAS_FEAT(sector, SECTOR)
++__XFS_HAS_FEAT(extflg, EXTFLG)
++__XFS_HAS_FEAT(asciici, ASCIICI)
++__XFS_HAS_FEAT(lazysbcount, LAZYSBCOUNT)
++__XFS_ADD_FEAT(attr2, ATTR2)
++__XFS_HAS_FEAT(parent, PARENT)
++__XFS_ADD_FEAT(projid32, PROJID32)
++__XFS_HAS_FEAT(crc, CRC)
++__XFS_HAS_FEAT(v3inodes, V3INODES)
++__XFS_HAS_FEAT(pquotino, PQUOTINO)
++__XFS_HAS_FEAT(ftype, FTYPE)
++__XFS_HAS_FEAT(finobt, FINOBT)
++__XFS_HAS_FEAT(rmapbt, RMAPBT)
++__XFS_HAS_FEAT(reflink, REFLINK)
++__XFS_HAS_FEAT(sparseinodes, SPINODES)
++__XFS_HAS_FEAT(metauuid, META_UUID)
++__XFS_HAS_FEAT(realtime, REALTIME)
++__XFS_HAS_FEAT(inobtcounts, INOBTCNT)
++__XFS_HAS_FEAT(bigtime, BIGTIME)
++__XFS_HAS_FEAT(needsrepair, NEEDSREPAIR)
++
++/*
+  * Flags for m_flags.
+  */
+ #define XFS_MOUNT_WSYNC               (1ULL << 0)     /* for nfs - all metadata ops
+--- a/fs/xfs/xfs_rtalloc.c
++++ b/fs/xfs/xfs_rtalloc.c
+@@ -1101,6 +1101,9 @@ error_cancel:
+               error = xfs_trans_commit(tp);
+               if (error)
+                       break;
++
++              /* Ensure the mount RT feature flag is now set. */
++              mp->m_features |= XFS_FEAT_REALTIME;
+       }
+       if (error)
+               goto out_free;
diff --git a/queue-5.10/xfs-use-null-daddr-for-unset-first-bad-log-block.patch b/queue-5.10/xfs-use-null-daddr-for-unset-first-bad-log-block.patch
new file mode 100644 (file)
index 0000000..3417841
--- /dev/null
@@ -0,0 +1,55 @@
+From stable+bounces-277294-greg=kroah.com@vger.kernel.org Sat Jul 18 13:21:09 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jul 2026 07:21:01 -0400
+Subject: xfs: use null daddr for unset first bad log block
+To: stable@vger.kernel.org
+Cc: Yousef Alhouseen <alhouseenyousef@gmail.com>, "Darrick J. Wong" <djwong@kernel.org>, syzbot+b7dfbed0c6c2b5e9fd34@syzkaller.appspotmail.com, Carlos Maiolino <cem@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260718112101.2964955-1-sashal@kernel.org>
+
+From: Yousef Alhouseen <alhouseenyousef@gmail.com>
+
+[ Upstream commit cc9af5e461ea5f6e37738f3f1e41c45a9b7f45d6 ]
+
+xlog_do_recovery_pass() may return before setting first_bad.  The caller
+must distinguish that case from an error at a valid log block, including
+block zero after the log wraps.
+
+Initialize first_bad to XFS_BUF_DADDR_NULL and test it explicitly before
+treating the error as a torn write.
+
+Fixes: 7088c4136fa1 ("xfs: detect and trim torn writes during log recovery")
+Suggested-by: Darrick J. Wong <djwong@kernel.org>
+Reported-by: syzbot+b7dfbed0c6c2b5e9fd34@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=b7dfbed0c6c2b5e9fd34
+Cc: stable@vger.kernel.org # v4.5
+Signed-off-by: Yousef Alhouseen <alhouseenyousef@gmail.com>
+Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
+Signed-off-by: Carlos Maiolino <cem@kernel.org>
+[ adjusted hunk offsets for context drift and dropped an inapplicable whitespace-only end-of-file hunk whose context doesn't exist in 5.10 ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/xfs_log_recover.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/fs/xfs/xfs_log_recover.c
++++ b/fs/xfs/xfs_log_recover.c
+@@ -1034,7 +1034,7 @@ xlog_verify_head(
+ {
+       struct xlog_rec_header  *tmp_rhead;
+       char                    *tmp_buffer;
+-      xfs_daddr_t             first_bad;
++      xfs_daddr_t             first_bad = XFS_BUF_DADDR_NULL;
+       xfs_daddr_t             tmp_rhead_blk;
+       int                     found;
+       int                     error;
+@@ -1063,7 +1063,8 @@ xlog_verify_head(
+        */
+       error = xlog_do_recovery_pass(log, *head_blk, tmp_rhead_blk,
+                                     XLOG_RECOVER_CRCPASS, &first_bad);
+-      if ((error == -EFSBADCRC || error == -EFSCORRUPTED) && first_bad) {
++      if ((error == -EFSBADCRC || error == -EFSCORRUPTED) &&
++          first_bad != XFS_BUF_DADDR_NULL) {
+               /*
+                * We've hit a potential torn write. Reset the error and warn
+                * about it.