]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.9
authorSasha Levin <sashal@kernel.org>
Fri, 21 Jun 2024 15:39:24 +0000 (11:39 -0400)
committerSasha Levin <sashal@kernel.org>
Fri, 21 Jun 2024 15:39:24 +0000 (11:39 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
96 files changed:
queue-6.9/acpi-ec-install-address-space-handler-at-the-namespa.patch [new file with mode: 0644]
queue-6.9/acpi-resource-do-irq-override-on-gmxbgxx-xmg-apex-17.patch [new file with mode: 0644]
queue-6.9/acpi-resource-skip-irq-override-on-asus-vivobook-pro.patch [new file with mode: 0644]
queue-6.9/acpi-video-add-backlight-native-quirk-for-lenovo-sli.patch [new file with mode: 0644]
queue-6.9/acpi-x86-add-pnp_uart1_skip-quirk-for-lenovo-blade2-.patch [new file with mode: 0644]
queue-6.9/af_packet-avoid-a-false-positive-warning-in-packet_s.patch [new file with mode: 0644]
queue-6.9/alsa-hda-realtek-add-quirks-for-hp-omen-models-using.patch [new file with mode: 0644]
queue-6.9/alsa-hda-realtek-add-quirks-for-lenovo-13x.patch [new file with mode: 0644]
queue-6.9/arm64-defconfig-select-interconnect_qcom_sm6115-as-b.patch [new file with mode: 0644]
queue-6.9/arm64-sysreg-update-pie-permission-encodings.patch [new file with mode: 0644]
queue-6.9/asoc-intel-sof_cs42l42-rename-bt-offload-quirk.patch [new file with mode: 0644]
queue-6.9/asoc-intel-sof_sdw-add-jd2-quirk-for-hp-omen-14.patch [new file with mode: 0644]
queue-6.9/asoc-intel-sof_sdw-add-quirk-for-dell-sku-0c0f.patch [new file with mode: 0644]
queue-6.9/avoid-hw_desc-array-overrun-in-dw-axi-dmac.patch [new file with mode: 0644]
queue-6.9/batman-adv-bypass-empty-buckets-in-batadv_purge_orig.patch [new file with mode: 0644]
queue-6.9/block-ioctl-prefer-different-overflow-check.patch [new file with mode: 0644]
queue-6.9/bluetooth-ath3k-fix-multiple-issues-reported-by-chec.patch [new file with mode: 0644]
queue-6.9/bpf-avoid-kfree_rcu-under-lock-in-bpf_lpm_trie.patch [new file with mode: 0644]
queue-6.9/bpf-avoid-uninitialized-warnings-in-verifier_global_.patch [new file with mode: 0644]
queue-6.9/cgroup-cpuset-make-cpuset-hotplug-processing-synchro.patch [new file with mode: 0644]
queue-6.9/clocksource-make-watchdog-and-suspend-timing-multipl.patch [new file with mode: 0644]
queue-6.9/cpufreq-amd-pstate-fix-memory-leak-on-cpu-epp-exit.patch [new file with mode: 0644]
queue-6.9/crypto-hisilicon-qm-add-the-err-memory-release-proce.patch [new file with mode: 0644]
queue-6.9/crypto-hisilicon-sec-fix-memory-leak-for-sec-resourc.patch [new file with mode: 0644]
queue-6.9/cxl-add-post-reset-warning-if-reset-results-in-loss-.patch [new file with mode: 0644]
queue-6.9/devlink-use-kvzalloc-to-allocate-devlink-instance-re.patch [new file with mode: 0644]
queue-6.9/drm-amd-display-exit-idle-optimizations-before-hdcp-.patch [new file with mode: 0644]
queue-6.9/drm-amd-display-workaround-register-access-in-idle-r.patch [new file with mode: 0644]
queue-6.9/drm-lima-add-mask-irq-callback-to-gp-and-pp.patch [new file with mode: 0644]
queue-6.9/drm-lima-include-pp-bcast-irq-in-timeout-handler-che.patch [new file with mode: 0644]
queue-6.9/drm-lima-mask-irqs-in-timeout-path-before-hard-reset.patch [new file with mode: 0644]
queue-6.9/drop_monitor-replace-spin_lock-by-raw_spin_lock.patch [new file with mode: 0644]
queue-6.9/ext4-do-not-create-ea-inode-under-buffer-lock.patch [new file with mode: 0644]
queue-6.9/ext4-fix-uninitialized-ratelimit_state-lock-access-i.patch [new file with mode: 0644]
queue-6.9/f2fs-don-t-set-ro-when-shutting-down-f2fs.patch [new file with mode: 0644]
queue-6.9/f2fs-fix-to-detect-inconsistent-nat-entry-during-tru.patch [new file with mode: 0644]
queue-6.9/f2fs-remove-clear-sb_inlinecrypt-flag-in-default_opt.patch [new file with mode: 0644]
queue-6.9/fs-writeback-bail-out-if-there-is-no-more-inodes-for.patch [new file with mode: 0644]
queue-6.9/hid-add-quirk-for-logitech-casa-touchpad.patch [new file with mode: 0644]
queue-6.9/hid-asus-fix-more-n-key-report-descriptors-if-n-key-.patch [new file with mode: 0644]
queue-6.9/i2c-lpi2c-avoid-calling-clk_get_rate-during-transfer.patch [new file with mode: 0644]
queue-6.9/io_uring-sqpoll-work-around-a-potential-audit-memory.patch [new file with mode: 0644]
queue-6.9/iommu-arm-smmu-v3-free-msis-in-case-of-enomem.patch [new file with mode: 0644]
queue-6.9/kprobe-ftrace-bail-out-if-ftrace-was-killed.patch [new file with mode: 0644]
queue-6.9/kselftest-arm64-add-a-null-pointer-check.patch [new file with mode: 0644]
queue-6.9/media-intel-ipu6-fix-build-with-acpi.patch [new file with mode: 0644]
queue-6.9/media-mtk-vcodec-potential-null-pointer-deference-in.patch [new file with mode: 0644]
queue-6.9/mips-octeon-add-pcie-link-status-check.patch [new file with mode: 0644]
queue-6.9/net-dsa-realtek-do-not-assert-reset-on-remove.patch [new file with mode: 0644]
queue-6.9/net-dsa-realtek-keep-default-led-state-in-rtl8366rb.patch [new file with mode: 0644]
queue-6.9/net-ena-add-validation-for-completion-descriptors-co.patch [new file with mode: 0644]
queue-6.9/net-sched-fix-false-lockdep-warning-on-qdisc-root-lo.patch [new file with mode: 0644]
queue-6.9/net-sfp-add-quirk-for-ats-sfp-ge-t-1000base-tx-modul.patch [new file with mode: 0644]
queue-6.9/net-sfp-enhance-quirk-for-fibrestore-2.5g-copper-sfp.patch [new file with mode: 0644]
queue-6.9/netpoll-fix-race-condition-in-netpoll_owner_active.patch [new file with mode: 0644]
queue-6.9/opp-fix-required_opp_tables-for-multiple-genpds-usin.patch [new file with mode: 0644]
queue-6.9/padata-disable-bh-when-taking-works-lock-on-mt-path.patch [new file with mode: 0644]
queue-6.9/pci-do-not-wait-for-disconnected-devices-when-resumi.patch [new file with mode: 0644]
queue-6.9/pci-pm-avoid-d3cold-for-hp-pavilion-17-pc-1972-pcie-.patch [new file with mode: 0644]
queue-6.9/platform-chrome-cros_usbpd_logger-provide-id-table-f.patch [new file with mode: 0644]
queue-6.9/platform-chrome-cros_usbpd_notify-provide-id-table-f.patch [new file with mode: 0644]
queue-6.9/platform-x86-p2sb-don-t-init-until-unassigned-resour.patch [new file with mode: 0644]
queue-6.9/platform-x86-toshiba_acpi-add-quirk-for-buttons-on-z.patch [new file with mode: 0644]
queue-6.9/platform-x86-x86-android-tablets-add-lenovo-yoga-tab.patch [new file with mode: 0644]
queue-6.9/platform-x86-x86-android-tablets-unregister-devices-.patch [new file with mode: 0644]
queue-6.9/power-supply-cros_usbpd-provide-id-table-for-avoidin.patch [new file with mode: 0644]
queue-6.9/powerpc-io-avoid-clang-null-pointer-arithmetic-warni.patch [new file with mode: 0644]
queue-6.9/powerpc-pseries-enforce-hcall-result-buffer-validity.patch [new file with mode: 0644]
queue-6.9/rcutorture-fix-invalid-context-warning-when-enable-s.patch [new file with mode: 0644]
queue-6.9/rcutorture-fix-rcu_torture_one_read-pipe_count-overf.patch [new file with mode: 0644]
queue-6.9/rcutorture-make-stall-tasks-directly-exit-when-rcuto.patch [new file with mode: 0644]
queue-6.9/scsi-qedi-fix-crash-while-reading-debugfs-attribute.patch [new file with mode: 0644]
queue-6.9/selftests-bpf-fix-flaky-test-btf_map_in_map-lookup_u.patch [new file with mode: 0644]
queue-6.9/selftests-bpf-prevent-client-connect-before-server-b.patch [new file with mode: 0644]
queue-6.9/selftests-net-fix-timestamp-not-arriving-in-cmsg_tim.patch [new file with mode: 0644]
queue-6.9/serial-exar-adding-missing-cti-and-exar-pci-ids.patch [new file with mode: 0644]
queue-6.9/serial-imx-introduce-timeout-when-waiting-on-transmi.patch [new file with mode: 0644]
queue-6.9/series [new file with mode: 0644]
queue-6.9/ssb-fix-potential-null-pointer-dereference-in-ssb_de.patch [new file with mode: 0644]
queue-6.9/tty-add-the-option-to-have-a-tty-reject-a-new-ldisc.patch [new file with mode: 0644]
queue-6.9/ubsan-avoid-i386-ubsan-handler-crashes-with-clang.patch [new file with mode: 0644]
queue-6.9/udf-udftime-prevent-overflow-in-udf_disk_stamp_to_ti.patch [new file with mode: 0644]
queue-6.9/usb-dwc3-pci-don-t-set-linux-phy_charger_detect-prop.patch [new file with mode: 0644]
queue-6.9/usb-gadget-function-remove-usage-of-the-deprecated-i.patch [new file with mode: 0644]
queue-6.9/usb-gadget-uvc-configfs-ensure-guid-to-be-valid-befo.patch [new file with mode: 0644]
queue-6.9/usb-misc-uss720-check-for-incompatible-versions-of-t.patch [new file with mode: 0644]
queue-6.9/usb-typec-qcom-pmic-typec-split-hpd-bridge-alloc-and.patch [new file with mode: 0644]
queue-6.9/usb-typec-ucsi_glink-drop-special-handling-for-cci_b.patch [new file with mode: 0644]
queue-6.9/usb-typec-ucsi_glink-rework-quirks-implementation.patch [new file with mode: 0644]
queue-6.9/vfio-pci-collect-hot-reset-devices-to-local-buffer.patch [new file with mode: 0644]
queue-6.9/wifi-ath12k-fix-kernel-crash-during-resume.patch [new file with mode: 0644]
queue-6.9/wifi-ath12k-fix-the-problem-that-down-grade-phy-mode.patch [new file with mode: 0644]
queue-6.9/wifi-ath9k-work-around-memset-overflow-warning.patch [new file with mode: 0644]
queue-6.9/wifi-mt76-mt7921s-fix-potential-hung-tasks-during-ch.patch [new file with mode: 0644]
queue-6.9/wifi-rtw89-8852c-add-quirk-to-set-pci-ber-for-certai.patch [new file with mode: 0644]
queue-6.9/xhci-remove-xhci_trust_tx_length-quirk.patch [new file with mode: 0644]

diff --git a/queue-6.9/acpi-ec-install-address-space-handler-at-the-namespa.patch b/queue-6.9/acpi-ec-install-address-space-handler-at-the-namespa.patch
new file mode 100644 (file)
index 0000000..fc00ce3
--- /dev/null
@@ -0,0 +1,131 @@
+From 4b8b13358d687b767f4b4c129bd4eed43477e5f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 May 2024 21:40:54 +0200
+Subject: ACPI: EC: Install address space handler at the namespace root
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 60fa6ae6e6d09e377fce6f8d9b6f6a4d88769f63 ]
+
+It is reported that _DSM evaluation fails in ucsi_acpi_dsm() on Lenovo
+IdeaPad Pro 5 due to a missing address space handler for the EC address
+space:
+
+ ACPI Error: No handler for Region [ECSI] (000000007b8176ee) [EmbeddedControl] (20230628/evregion-130)
+
+This happens because if there is no ECDT, the EC driver only registers
+the EC address space handler for operation regions defined in the EC
+device scope of the ACPI namespace while the operation region being
+accessed by the _DSM in question is located beyond that scope.
+
+To address this, modify the ACPI EC driver to install the EC address
+space handler at the root of the ACPI namespace for the first EC that
+can be found regardless of whether or not an ECDT is present.
+
+Note that this change is consistent with some examples in the ACPI
+specification in which EC operation regions located outside the EC
+device scope are used (for example, see Section 9.17.15 in ACPI 6.5),
+so the current behavior of the EC driver is arguably questionable.
+
+Reported-by: webcaptcha <webcapcha@gmail.com>
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=218789
+Link: https://uefi.org/specs/ACPI/6.5/09_ACPI_Defined_Devices_and_Device_Specific_Objects.html#example-asl-code
+Link: https://lore.kernel.org/linux-acpi/Zi+0whTvDbAdveHq@kuha.fi.intel.com
+Suggested-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/ec.c       | 25 ++++++++++++++++---------
+ drivers/acpi/internal.h |  1 -
+ 2 files changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
+index 02255795b800d..e7793ee9e6498 100644
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -1482,13 +1482,14 @@ static bool install_gpio_irq_event_handler(struct acpi_ec *ec)
+ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device,
+                              bool call_reg)
+ {
++      acpi_handle scope_handle = ec == first_ec ? ACPI_ROOT_OBJECT : ec->handle;
+       acpi_status status;
+       acpi_ec_start(ec, false);
+       if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) {
+               acpi_ec_enter_noirq(ec);
+-              status = acpi_install_address_space_handler_no_reg(ec->handle,
++              status = acpi_install_address_space_handler_no_reg(scope_handle,
+                                                                  ACPI_ADR_SPACE_EC,
+                                                                  &acpi_ec_space_handler,
+                                                                  NULL, ec);
+@@ -1497,11 +1498,10 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device,
+                       return -ENODEV;
+               }
+               set_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags);
+-              ec->address_space_handler_holder = ec->handle;
+       }
+       if (call_reg && !test_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags)) {
+-              acpi_execute_reg_methods(ec->handle, ACPI_ADR_SPACE_EC);
++              acpi_execute_reg_methods(scope_handle, ACPI_ADR_SPACE_EC);
+               set_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags);
+       }
+@@ -1553,10 +1553,13 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device,
+ static void ec_remove_handlers(struct acpi_ec *ec)
+ {
++      acpi_handle scope_handle = ec == first_ec ? ACPI_ROOT_OBJECT : ec->handle;
++
+       if (test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) {
+               if (ACPI_FAILURE(acpi_remove_address_space_handler(
+-                                      ec->address_space_handler_holder,
+-                                      ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
++                                              scope_handle,
++                                              ACPI_ADR_SPACE_EC,
++                                              &acpi_ec_space_handler)))
+                       pr_err("failed to remove space handler\n");
+               clear_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags);
+       }
+@@ -1595,14 +1598,18 @@ static int acpi_ec_setup(struct acpi_ec *ec, struct acpi_device *device, bool ca
+ {
+       int ret;
+-      ret = ec_install_handlers(ec, device, call_reg);
+-      if (ret)
+-              return ret;
+-
+       /* First EC capable of handling transactions */
+       if (!first_ec)
+               first_ec = ec;
++      ret = ec_install_handlers(ec, device, call_reg);
++      if (ret) {
++              if (ec == first_ec)
++                      first_ec = NULL;
++
++              return ret;
++      }
++
+       pr_info("EC_CMD/EC_SC=0x%lx, EC_DATA=0x%lx\n", ec->command_addr,
+               ec->data_addr);
+diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
+index ca72a0dc57151..a0801e0876fc0 100644
+--- a/drivers/acpi/internal.h
++++ b/drivers/acpi/internal.h
+@@ -185,7 +185,6 @@ enum acpi_ec_event_state {
+ struct acpi_ec {
+       acpi_handle handle;
+-      acpi_handle address_space_handler_holder;
+       int gpe;
+       int irq;
+       unsigned long command_addr;
+-- 
+2.43.0
+
diff --git a/queue-6.9/acpi-resource-do-irq-override-on-gmxbgxx-xmg-apex-17.patch b/queue-6.9/acpi-resource-do-irq-override-on-gmxbgxx-xmg-apex-17.patch
new file mode 100644 (file)
index 0000000..f5ae172
--- /dev/null
@@ -0,0 +1,45 @@
+From 8cb0cf1c1a269209d6af930c5cab1cde8ab253d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Apr 2024 20:51:18 +0200
+Subject: ACPI: resource: Do IRQ override on GMxBGxx (XMG APEX 17 M23)
+
+From: Guenter Schafranek <gschafra@web.de>
+
+[ Upstream commit 6eaf375a5a98642ba4c327f79673f4f308e0ac03 ]
+
+The XM APEX 17 M23 (TongFang?) GMxBGxx (got using `sudo dmidecode -s
+baseboard-product-name`) needs IRQ overriding for the keyboard to work.
+
+Adding an entry for this laptop to the override_table makes the internal
+keyboard functional [1].
+
+Successfully tested with Arch Linux Kernel v6.8 under Manjaro Linux v23.1.4.
+
+Link: https://www.reddit.com/r/XMG_gg/comments/15kd5pg/xmg_apex_17_m23_keyboard_not_working_on_linux/ # [1]
+Signed-off-by: Guenter Schafranek <gschafra@web.de>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/resource.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
+index 6cc8572759a3d..65fa94729d9de 100644
+--- a/drivers/acpi/resource.c
++++ b/drivers/acpi/resource.c
+@@ -533,6 +533,12 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = {
+  * to have a working keyboard.
+  */
+ static const struct dmi_system_id irq1_edge_low_force_override[] = {
++      {
++              /* XMG APEX 17 (M23) */
++              .matches = {
++                      DMI_MATCH(DMI_BOARD_NAME, "GMxBGxx"),
++              },
++      },
+       {
+               /* TongFang GMxRGxx/XMG CORE 15 (M22)/TUXEDO Stellaris 15 Gen4 AMD */
+               .matches = {
+-- 
+2.43.0
+
diff --git a/queue-6.9/acpi-resource-skip-irq-override-on-asus-vivobook-pro.patch b/queue-6.9/acpi-resource-skip-irq-override-on-asus-vivobook-pro.patch
new file mode 100644 (file)
index 0000000..6c2f0c7
--- /dev/null
@@ -0,0 +1,45 @@
+From accaab45570f2362b974eaa361bad8d0e351a253 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 Apr 2024 13:08:12 -0400
+Subject: ACPI: resource: Skip IRQ override on Asus Vivobook Pro N6506MV
+
+From: Tamim Khan <tamim@fusetak.com>
+
+[ Upstream commit 7c52c7071bd403acee8cb0064627d46c6c2a1ea3 ]
+
+Like various other Asus Vivobook and Expertbook laptops, the Asus
+Vivobook Pro N6506MV has a DSDT table that describes IRQ 1 as ActiveLow
+while the kernel is overriding it to Edge_High. This prevents the internal
+keyboard from working. This patch prevents this issue by adding this laptop
+to the override table that prevents the kernel from overriding this IRQ
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=218745
+Tested-by: Gianni <gianni.casagrande.mail@gmail.com>
+Signed-off-by: Tamim Khan <tamim@fusetak.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/resource.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
+index 65fa94729d9de..b5bf8b81a050a 100644
+--- a/drivers/acpi/resource.c
++++ b/drivers/acpi/resource.c
+@@ -517,6 +517,13 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = {
+                       DMI_MATCH(DMI_BOARD_NAME, "E1504GAB"),
+               },
+       },
++      {
++              /* Asus Vivobook Pro N6506MV */
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++                      DMI_MATCH(DMI_BOARD_NAME, "N6506MV"),
++              },
++      },
+       {
+               /* LG Electronics 17U70P */
+               .matches = {
+-- 
+2.43.0
+
diff --git a/queue-6.9/acpi-video-add-backlight-native-quirk-for-lenovo-sli.patch b/queue-6.9/acpi-video-add-backlight-native-quirk-for-lenovo-sli.patch
new file mode 100644 (file)
index 0000000..a967964
--- /dev/null
@@ -0,0 +1,47 @@
+From d59d25b059d576496071429175afd15f2c00bc60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 May 2024 16:08:50 +0200
+Subject: ACPI: video: Add backlight=native quirk for Lenovo Slim 7 16ARH7
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit c901f63dc142c48326931f164f787dfff69273d9 ]
+
+Lenovo Slim 7 16ARH7 is a machine with switchable graphics between AMD
+and Nvidia, and the backlight can't be adjusted properly unless
+acpi_backlight=native is passed.  Although nvidia-wmi-backlight is
+present and loaded, this doesn't work as expected at all.
+
+For making it working as default, add the corresponding quirk entry
+with a DMI matching "LENOVO" "82UX".
+
+Link: https://bugzilla.suse.com/show_bug.cgi?id=1217750
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/video_detect.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
+index 9fdcc620c6524..2cc3821b2b16e 100644
+--- a/drivers/acpi/video_detect.c
++++ b/drivers/acpi/video_detect.c
+@@ -497,6 +497,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
+               DMI_MATCH(DMI_PRODUCT_NAME, "82BK"),
+               },
+       },
++      {
++       .callback = video_detect_force_native,
++       /* Lenovo Slim 7 16ARH7 */
++       .matches = {
++              DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++              DMI_MATCH(DMI_PRODUCT_NAME, "82UX"),
++              },
++      },
+       {
+        .callback = video_detect_force_native,
+        /* Lenovo ThinkPad X131e (3371 AMD version) */
+-- 
+2.43.0
+
diff --git a/queue-6.9/acpi-x86-add-pnp_uart1_skip-quirk-for-lenovo-blade2-.patch b/queue-6.9/acpi-x86-add-pnp_uart1_skip-quirk-for-lenovo-blade2-.patch
new file mode 100644 (file)
index 0000000..7dde799
--- /dev/null
@@ -0,0 +1,89 @@
+From 28471a74e51330c9c0062d3e12f654a6f41148f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Apr 2024 15:56:25 +0200
+Subject: ACPI: x86: Add PNP_UART1_SKIP quirk for Lenovo Blade2 tablets
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit d8f20383a2fc3a3844b08a4999cf0e81164a0e56 ]
+
+The x86 Android tablets on which quirks to skip looking for a matching
+UartSerialBus resource and instead unconditionally create a serial bus
+device (serdev) are necessary there are 2 sorts of serialports:
+
+ACPI enumerated highspeed designware UARTs, these are the ones which
+typcially need to be skipped since they need a serdev for the attached
+BT HCI.
+
+A PNP enumerated UART which is part of the PCU. So far the existing
+quirks have ignored this. But on the Lenovo Yoga Tablet 2 Pro 1380
+models this is used for a custom fastcharging protocol. There is
+a Micro USB switch which can switch the USB data lines to this uart
+and then a 600 baud protocol is used to configure the charger for
+a voltage higher then 5V.
+
+Add a new ACPI_QUIRK_PNP_UART1_SKIP quirk type and set this for
+the existing entry for the Lenovo Yoga Tablet 2 830 / 1050 models.
+Note this will lead to unnecessarily also creating a serdev for
+the PCU UART on the 830 / 1050 which don't need this, but the UART
+is not used otherwise there so that is not a problem.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/x86/utils.c | 20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c
+index 7507a7706898c..448e0d14fd7bd 100644
+--- a/drivers/acpi/x86/utils.c
++++ b/drivers/acpi/x86/utils.c
+@@ -256,9 +256,10 @@ bool force_storage_d3(void)
+ #define ACPI_QUIRK_SKIP_I2C_CLIENTS                           BIT(0)
+ #define ACPI_QUIRK_UART1_SKIP                                 BIT(1)
+ #define ACPI_QUIRK_UART1_TTY_UART2_SKIP                               BIT(2)
+-#define ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY                   BIT(3)
+-#define ACPI_QUIRK_USE_ACPI_AC_AND_BATTERY                    BIT(4)
+-#define ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS                   BIT(5)
++#define ACPI_QUIRK_PNP_UART1_SKIP                             BIT(3)
++#define ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY                   BIT(4)
++#define ACPI_QUIRK_USE_ACPI_AC_AND_BATTERY                    BIT(5)
++#define ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS                   BIT(6)
+ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
+       /*
+@@ -338,6 +339,7 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
+                       DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"),
+               },
+               .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
++                                      ACPI_QUIRK_PNP_UART1_SKIP |
+                                       ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
+       },
+       {
+@@ -436,14 +438,18 @@ static int acpi_dmi_skip_serdev_enumeration(struct device *controller_parent, bo
+       if (ret)
+               return 0;
+-      /* to not match on PNP enumerated debug UARTs */
+-      if (!dev_is_platform(controller_parent))
+-              return 0;
+-
+       dmi_id = dmi_first_match(acpi_quirk_skip_dmi_ids);
+       if (dmi_id)
+               quirks = (unsigned long)dmi_id->driver_data;
++      if (!dev_is_platform(controller_parent)) {
++              /* PNP enumerated UARTs */
++              if ((quirks & ACPI_QUIRK_PNP_UART1_SKIP) && uid == 1)
++                      *skip = true;
++
++              return 0;
++      }
++
+       if ((quirks & ACPI_QUIRK_UART1_SKIP) && uid == 1)
+               *skip = true;
+-- 
+2.43.0
+
diff --git a/queue-6.9/af_packet-avoid-a-false-positive-warning-in-packet_s.patch b/queue-6.9/af_packet-avoid-a-false-positive-warning-in-packet_s.patch
new file mode 100644 (file)
index 0000000..d36a2e2
--- /dev/null
@@ -0,0 +1,81 @@
+From 770942a1e647c0d193f878047164336a0b78ebc0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Apr 2024 11:49:39 +0000
+Subject: af_packet: avoid a false positive warning in packet_setsockopt()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 86d43e2bf93ccac88ef71cee36a23282ebd9e427 ]
+
+Although the code is correct, the following line
+
+       copy_from_sockptr(&req_u.req, optval, len));
+
+triggers this warning :
+
+memcpy: detected field-spanning write (size 28) of single field "dst" at include/linux/sockptr.h:49 (size 16)
+
+Refactor the code to be more explicit.
+
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Kees Cook <keescook@chromium.org>
+Cc: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/packet/af_packet.c | 26 ++++++++++++++------------
+ 1 file changed, 14 insertions(+), 12 deletions(-)
+
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index 150451ddd7553..ea3ebc160e25c 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -3799,28 +3799,30 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval,
+       case PACKET_TX_RING:
+       {
+               union tpacket_req_u req_u;
+-              int len;
++              ret = -EINVAL;
+               lock_sock(sk);
+               switch (po->tp_version) {
+               case TPACKET_V1:
+               case TPACKET_V2:
+-                      len = sizeof(req_u.req);
++                      if (optlen < sizeof(req_u.req))
++                              break;
++                      ret = copy_from_sockptr(&req_u.req, optval,
++                                              sizeof(req_u.req)) ?
++                                              -EINVAL : 0;
+                       break;
+               case TPACKET_V3:
+               default:
+-                      len = sizeof(req_u.req3);
++                      if (optlen < sizeof(req_u.req3))
++                              break;
++                      ret = copy_from_sockptr(&req_u.req3, optval,
++                                              sizeof(req_u.req3)) ?
++                                              -EINVAL : 0;
+                       break;
+               }
+-              if (optlen < len) {
+-                      ret = -EINVAL;
+-              } else {
+-                      if (copy_from_sockptr(&req_u.req, optval, len))
+-                              ret = -EFAULT;
+-                      else
+-                              ret = packet_set_ring(sk, &req_u, 0,
+-                                                  optname == PACKET_TX_RING);
+-              }
++              if (!ret)
++                      ret = packet_set_ring(sk, &req_u, 0,
++                                            optname == PACKET_TX_RING);
+               release_sock(sk);
+               return ret;
+       }
+-- 
+2.43.0
+
diff --git a/queue-6.9/alsa-hda-realtek-add-quirks-for-hp-omen-models-using.patch b/queue-6.9/alsa-hda-realtek-add-quirks-for-hp-omen-models-using.patch
new file mode 100644 (file)
index 0000000..bd2fc3a
--- /dev/null
@@ -0,0 +1,46 @@
+From 4ee88440862349990cb5b89645176935bf928f68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Apr 2024 12:08:09 +0100
+Subject: ALSA: hda/realtek: Add quirks for HP Omen models using CS35L41
+
+From: Stefan Binding <sbinding@opensource.cirrus.com>
+
+[ Upstream commit 875e0cd59758a3d636ce94936287787514305095 ]
+
+Add 4 laptops using CS35L41 HDA.
+None of these laptops have _DSD, so require entries in property
+configuration table for cs35l41_hda driver.
+
+Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Message-ID: <20240411110813.330483-4-sbinding@opensource.cirrus.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 1a1ca7caaff07..152ad2c429a61 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -10147,6 +10147,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x103c, 0x8b92, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+       SND_PCI_QUIRK(0x103c, 0x8b96, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
+       SND_PCI_QUIRK(0x103c, 0x8b97, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
++      SND_PCI_QUIRK(0x103c, 0x8bb3, "HP Slim OMEN", ALC287_FIXUP_CS35L41_I2C_2),
++      SND_PCI_QUIRK(0x103c, 0x8bb4, "HP Slim OMEN", ALC287_FIXUP_CS35L41_I2C_2),
+       SND_PCI_QUIRK(0x103c, 0x8bdd, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
+       SND_PCI_QUIRK(0x103c, 0x8bde, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
+       SND_PCI_QUIRK(0x103c, 0x8bdf, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2),
+@@ -10167,6 +10169,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x103c, 0x8c47, "HP EliteBook 840 G11", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+       SND_PCI_QUIRK(0x103c, 0x8c48, "HP EliteBook 860 G11", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+       SND_PCI_QUIRK(0x103c, 0x8c49, "HP Elite x360 830 2-in-1 G11", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
++      SND_PCI_QUIRK(0x103c, 0x8c4d, "HP Omen", ALC287_FIXUP_CS35L41_I2C_2),
++      SND_PCI_QUIRK(0x103c, 0x8c4e, "HP Omen", ALC287_FIXUP_CS35L41_I2C_2),
+       SND_PCI_QUIRK(0x103c, 0x8c4f, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2),
+       SND_PCI_QUIRK(0x103c, 0x8c50, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
+       SND_PCI_QUIRK(0x103c, 0x8c51, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
+-- 
+2.43.0
+
diff --git a/queue-6.9/alsa-hda-realtek-add-quirks-for-lenovo-13x.patch b/queue-6.9/alsa-hda-realtek-add-quirks-for-lenovo-13x.patch
new file mode 100644 (file)
index 0000000..815ac4e
--- /dev/null
@@ -0,0 +1,37 @@
+From cabed86c6eb55fdd6dbebfc6d84eb388ee3d3127 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Apr 2024 17:23:03 +0100
+Subject: ALSA: hda/realtek: Add quirks for Lenovo 13X
+
+From: Stefan Binding <sbinding@opensource.cirrus.com>
+
+[ Upstream commit 25f46354dca912c84f1f79468fd636a94b8d287a ]
+
+Add laptop using CS35L41 HDA.
+This laptop does not have _DSD, so require entries in property
+configuration table for cs35l41_hda driver.
+
+Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com>
+Message-ID: <20240423162303.638211-3-sbinding@opensource.cirrus.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 152ad2c429a61..1e77bbba8de11 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -10501,6 +10501,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x17aa, 0x3852, "Lenovo Yoga 7 14ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
+       SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
+       SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6),
++      SND_PCI_QUIRK(0x17aa, 0x3865, "Lenovo 13X", ALC287_FIXUP_CS35L41_I2C_2),
++      SND_PCI_QUIRK(0x17aa, 0x3866, "Lenovo 13X", ALC287_FIXUP_CS35L41_I2C_2),
+       SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
+       SND_PCI_QUIRK(0x17aa, 0x386f, "Legion Pro 7/7i", ALC287_FIXUP_LENOVO_LEGION_7),
+       SND_PCI_QUIRK(0x17aa, 0x3870, "Lenovo Yoga 7 14ARB7", ALC287_FIXUP_YOGA7_14ARB7_I2C),
+-- 
+2.43.0
+
diff --git a/queue-6.9/arm64-defconfig-select-interconnect_qcom_sm6115-as-b.patch b/queue-6.9/arm64-defconfig-select-interconnect_qcom_sm6115-as-b.patch
new file mode 100644 (file)
index 0000000..df6f719
--- /dev/null
@@ -0,0 +1,37 @@
+From c11d3be03d993557746a8d585d9428ced1459434 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Apr 2024 04:19:27 +0300
+Subject: arm64: defconfig: select INTERCONNECT_QCOM_SM6115 as built-in
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit b052c7fe3cb787282ab7e1fa088c794a1eb7fdb0 ]
+
+Enable CONFIG_INTERCONNECT_QCOM_SM6115 as built-in to enable the
+interconnect driver for the SoC used on Qualcomm Robotics RB2 board.
+Building as built-in is required as on this platform interconnects are
+required to bring up the console.
+
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20240424-enable-sm6115-icc-v3-1-21c83be48f0e@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/configs/defconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
+index 2c30d617e1802..8d39b863251b2 100644
+--- a/arch/arm64/configs/defconfig
++++ b/arch/arm64/configs/defconfig
+@@ -1585,6 +1585,7 @@ CONFIG_INTERCONNECT_QCOM_SC8180X=y
+ CONFIG_INTERCONNECT_QCOM_SC8280XP=y
+ CONFIG_INTERCONNECT_QCOM_SDM845=y
+ CONFIG_INTERCONNECT_QCOM_SDX75=y
++CONFIG_INTERCONNECT_QCOM_SM6115=y
+ CONFIG_INTERCONNECT_QCOM_SM8150=m
+ CONFIG_INTERCONNECT_QCOM_SM8250=y
+ CONFIG_INTERCONNECT_QCOM_SM8350=m
+-- 
+2.43.0
+
diff --git a/queue-6.9/arm64-sysreg-update-pie-permission-encodings.patch b/queue-6.9/arm64-sysreg-update-pie-permission-encodings.patch
new file mode 100644 (file)
index 0000000..90e0f9d
--- /dev/null
@@ -0,0 +1,98 @@
+From b12c572a695336fbfc92a5b011bb85440b9e65ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Apr 2024 14:33:28 +0800
+Subject: arm64/sysreg: Update PIE permission encodings
+
+From: Shiqi Liu <shiqiliu@hust.edu.cn>
+
+[ Upstream commit 12d712dc8e4f1a30b18f8c3789adfbc07f5eb050 ]
+
+Fix left shift overflow issue when the parameter idx is greater than or
+equal to 8 in the calculation of perm in PIRx_ELx_PERM macro.
+
+Fix this by modifying the encoding to use a long integer type.
+
+Signed-off-by: Shiqi Liu <shiqiliu@hust.edu.cn>
+Acked-by: Marc Zyngier <maz@kernel.org>
+Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
+Link: https://lore.kernel.org/r/20240421063328.29710-1-shiqiliu@hust.edu.cn
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/sysreg.h       | 24 ++++++++++++------------
+ tools/arch/arm64/include/asm/sysreg.h | 24 ++++++++++++------------
+ 2 files changed, 24 insertions(+), 24 deletions(-)
+
+diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
+index 9e8999592f3af..af3b206fa4239 100644
+--- a/arch/arm64/include/asm/sysreg.h
++++ b/arch/arm64/include/asm/sysreg.h
+@@ -1036,18 +1036,18 @@
+  * Permission Indirection Extension (PIE) permission encodings.
+  * Encodings with the _O suffix, have overlays applied (Permission Overlay Extension).
+  */
+-#define PIE_NONE_O    0x0
+-#define PIE_R_O               0x1
+-#define PIE_X_O               0x2
+-#define PIE_RX_O      0x3
+-#define PIE_RW_O      0x5
+-#define PIE_RWnX_O    0x6
+-#define PIE_RWX_O     0x7
+-#define PIE_R         0x8
+-#define PIE_GCS               0x9
+-#define PIE_RX                0xa
+-#define PIE_RW                0xc
+-#define PIE_RWX               0xe
++#define PIE_NONE_O    UL(0x0)
++#define PIE_R_O               UL(0x1)
++#define PIE_X_O               UL(0x2)
++#define PIE_RX_O      UL(0x3)
++#define PIE_RW_O      UL(0x5)
++#define PIE_RWnX_O    UL(0x6)
++#define PIE_RWX_O     UL(0x7)
++#define PIE_R         UL(0x8)
++#define PIE_GCS               UL(0x9)
++#define PIE_RX                UL(0xa)
++#define PIE_RW                UL(0xc)
++#define PIE_RWX               UL(0xe)
+ #define PIRx_ELx_PERM(idx, perm)      ((perm) << ((idx) * 4))
+diff --git a/tools/arch/arm64/include/asm/sysreg.h b/tools/arch/arm64/include/asm/sysreg.h
+index ccc13e9913760..cd8420e8c3ad8 100644
+--- a/tools/arch/arm64/include/asm/sysreg.h
++++ b/tools/arch/arm64/include/asm/sysreg.h
+@@ -701,18 +701,18 @@
+  * Permission Indirection Extension (PIE) permission encodings.
+  * Encodings with the _O suffix, have overlays applied (Permission Overlay Extension).
+  */
+-#define PIE_NONE_O    0x0
+-#define PIE_R_O               0x1
+-#define PIE_X_O               0x2
+-#define PIE_RX_O      0x3
+-#define PIE_RW_O      0x5
+-#define PIE_RWnX_O    0x6
+-#define PIE_RWX_O     0x7
+-#define PIE_R         0x8
+-#define PIE_GCS               0x9
+-#define PIE_RX                0xa
+-#define PIE_RW                0xc
+-#define PIE_RWX               0xe
++#define PIE_NONE_O    UL(0x0)
++#define PIE_R_O               UL(0x1)
++#define PIE_X_O               UL(0x2)
++#define PIE_RX_O      UL(0x3)
++#define PIE_RW_O      UL(0x5)
++#define PIE_RWnX_O    UL(0x6)
++#define PIE_RWX_O     UL(0x7)
++#define PIE_R         UL(0x8)
++#define PIE_GCS               UL(0x9)
++#define PIE_RX                UL(0xa)
++#define PIE_RW                UL(0xc)
++#define PIE_RWX               UL(0xe)
+ #define PIRx_ELx_PERM(idx, perm)      ((perm) << ((idx) * 4))
+-- 
+2.43.0
+
diff --git a/queue-6.9/asoc-intel-sof_cs42l42-rename-bt-offload-quirk.patch b/queue-6.9/asoc-intel-sof_cs42l42-rename-bt-offload-quirk.patch
new file mode 100644 (file)
index 0000000..47ef0ee
--- /dev/null
@@ -0,0 +1,56 @@
+From 25de722027644cf7cbb33d6e7566bc924103718c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Mar 2024 17:10:44 -0500
+Subject: ASoC: Intel: sof_cs42l42: rename BT offload quirk
+
+From: Brent Lu <brent.lu@intel.com>
+
+[ Upstream commit 109896246a5311aa05692ecf38c0d71e1837fe23 ]
+
+Rename the quirk in preparation for future changes: common quriks will
+be defined and handled in board helper module.
+
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Signed-off-by: Brent Lu <brent.lu@intel.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://msgid.link/r/20240325221059.206042-7-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/sof_cs42l42.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/intel/boards/sof_cs42l42.c b/sound/soc/intel/boards/sof_cs42l42.c
+index 323b86c42ef95..330d596b2eb6d 100644
+--- a/sound/soc/intel/boards/sof_cs42l42.c
++++ b/sound/soc/intel/boards/sof_cs42l42.c
+@@ -34,7 +34,7 @@
+ #define SOF_CS42L42_NUM_HDMIDEV_MASK          (GENMASK(9, 7))
+ #define SOF_CS42L42_NUM_HDMIDEV(quirk)        \
+       (((quirk) << SOF_CS42L42_NUM_HDMIDEV_SHIFT) & SOF_CS42L42_NUM_HDMIDEV_MASK)
+-#define SOF_BT_OFFLOAD_PRESENT                        BIT(25)
++#define SOF_CS42L42_BT_OFFLOAD_PRESENT                BIT(25)
+ #define SOF_CS42L42_SSP_BT_SHIFT              26
+ #define SOF_CS42L42_SSP_BT_MASK                       (GENMASK(28, 26))
+ #define SOF_CS42L42_SSP_BT(quirk)     \
+@@ -268,7 +268,7 @@ static int sof_audio_probe(struct platform_device *pdev)
+       ctx->ssp_codec = sof_cs42l42_quirk & SOF_CS42L42_SSP_CODEC_MASK;
+-      if (sof_cs42l42_quirk & SOF_BT_OFFLOAD_PRESENT)
++      if (sof_cs42l42_quirk & SOF_CS42L42_BT_OFFLOAD_PRESENT)
+               ctx->bt_offload_present = true;
+       /* update dai_link */
+@@ -306,7 +306,7 @@ static const struct platform_device_id board_ids[] = {
+               .driver_data = (kernel_ulong_t)(SOF_CS42L42_SSP_CODEC(0) |
+                               SOF_CS42L42_SSP_AMP(1) |
+                               SOF_CS42L42_NUM_HDMIDEV(4) |
+-                              SOF_BT_OFFLOAD_PRESENT |
++                              SOF_CS42L42_BT_OFFLOAD_PRESENT |
+                               SOF_CS42L42_SSP_BT(2)),
+       },
+       { }
+-- 
+2.43.0
+
diff --git a/queue-6.9/asoc-intel-sof_sdw-add-jd2-quirk-for-hp-omen-14.patch b/queue-6.9/asoc-intel-sof_sdw-add-jd2-quirk-for-hp-omen-14.patch
new file mode 100644 (file)
index 0000000..fbbd84e
--- /dev/null
@@ -0,0 +1,42 @@
+From a2505346878cb09610ac8066f9d6c993cef41dbf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Apr 2024 17:03:38 -0500
+Subject: ASoC: Intel: sof_sdw: add JD2 quirk for HP Omen 14
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit 4fee07fbf47d2a5f1065d985459e5ce7bf7969f0 ]
+
+The default JD1 does not seem to work, use JD2 instead.
+
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20240411220347.131267-4-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/sof_sdw.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
+index a90b43162a54b..a98b9da2a2c4c 100644
+--- a/sound/soc/intel/boards/sof_sdw.c
++++ b/sound/soc/intel/boards/sof_sdw.c
+@@ -495,6 +495,15 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
+                                       SOF_BT_OFFLOAD_SSP(1) |
+                                       SOF_SSP_BT_OFFLOAD_PRESENT),
+       },
++      {
++              .callback = sof_sdw_quirk_cb,
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "HP"),
++                      DMI_MATCH(DMI_PRODUCT_NAME, "OMEN Transcend Gaming Laptop"),
++              },
++              .driver_data = (void *)(RT711_JD2),
++      },
++
+       /* LunarLake devices */
+       {
+               .callback = sof_sdw_quirk_cb,
+-- 
+2.43.0
+
diff --git a/queue-6.9/asoc-intel-sof_sdw-add-quirk-for-dell-sku-0c0f.patch b/queue-6.9/asoc-intel-sof_sdw-add-quirk-for-dell-sku-0c0f.patch
new file mode 100644 (file)
index 0000000..0a7dac0
--- /dev/null
@@ -0,0 +1,46 @@
+From c78d7dd9481a1555cebc1e442cd5c9dc6a50d918 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Apr 2024 17:03:39 -0500
+Subject: ASoC: Intel: sof_sdw: add quirk for Dell SKU 0C0F
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit b10cb955c6c0b8dbd9a768166d71cc12680b7fdf ]
+
+The JD1 jack detection doesn't seem to work, use JD2.
+Also use the 4 speaker configuration.
+
+Link: https://github.com/thesofproject/linux/issues/4900
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Link: https://lore.kernel.org/r/20240411220347.131267-5-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/sof_sdw.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
+index a98b9da2a2c4c..a5e2ffcc36e2e 100644
+--- a/sound/soc/intel/boards/sof_sdw.c
++++ b/sound/soc/intel/boards/sof_sdw.c
+@@ -429,6 +429,16 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
+                                       RT711_JD2 |
+                                       SOF_SDW_FOUR_SPK),
+       },
++      {
++              .callback = sof_sdw_quirk_cb,
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
++                      DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C0F")
++              },
++              .driver_data = (void *)(SOF_SDW_TGL_HDMI |
++                                      RT711_JD2 |
++                                      SOF_SDW_FOUR_SPK),
++      },
+       {
+               .callback = sof_sdw_quirk_cb,
+               .matches = {
+-- 
+2.43.0
+
diff --git a/queue-6.9/avoid-hw_desc-array-overrun-in-dw-axi-dmac.patch b/queue-6.9/avoid-hw_desc-array-overrun-in-dw-axi-dmac.patch
new file mode 100644 (file)
index 0000000..b6b55af
--- /dev/null
@@ -0,0 +1,77 @@
+From 35ee34be96196e99a8593152fc02bbfa16fbfa90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Mar 2024 10:49:24 +0000
+Subject: Avoid hw_desc array overrun in dw-axi-dmac
+
+From: Joao Pinto <Joao.Pinto@synopsys.com>
+
+[ Upstream commit 333e11bf47fa8d477db90e2900b1ed3c9ae9b697 ]
+
+I have a use case where nr_buffers = 3 and in which each descriptor is composed by 3
+segments, resulting in the DMA channel descs_allocated to be 9. Since axi_desc_put()
+handles the hw_desc considering the descs_allocated, this scenario would result in a
+kernel panic (hw_desc array will be overrun).
+
+To fix this, the proposal is to add a new member to the axi_dma_desc structure,
+where we keep the number of allocated hw_descs (axi_desc_alloc()) and use it in
+axi_desc_put() to handle the hw_desc array correctly.
+
+Additionally I propose to remove the axi_chan_start_first_queued() call after completing
+the transfer, since it was identified that unbalance can occur (started descriptors can
+be interrupted and transfer ignored due to DMA channel not being enabled).
+
+Signed-off-by: Joao Pinto <jpinto@synopsys.com>
+Link: https://lore.kernel.org/r/1711536564-12919-1-git-send-email-jpinto@synopsys.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 6 ++----
+ drivers/dma/dw-axi-dmac/dw-axi-dmac.h          | 1 +
+ 2 files changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+index a86a81ff0caa6..321446fdddbd7 100644
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -302,6 +302,7 @@ static struct axi_dma_desc *axi_desc_alloc(u32 num)
+               kfree(desc);
+               return NULL;
+       }
++      desc->nr_hw_descs = num;
+       return desc;
+ }
+@@ -328,7 +329,7 @@ static struct axi_dma_lli *axi_desc_get(struct axi_dma_chan *chan,
+ static void axi_desc_put(struct axi_dma_desc *desc)
+ {
+       struct axi_dma_chan *chan = desc->chan;
+-      int count = atomic_read(&chan->descs_allocated);
++      int count = desc->nr_hw_descs;
+       struct axi_dma_hw_desc *hw_desc;
+       int descs_put;
+@@ -1139,9 +1140,6 @@ static void axi_chan_block_xfer_complete(struct axi_dma_chan *chan)
+               /* Remove the completed descriptor from issued list before completing */
+               list_del(&vd->node);
+               vchan_cookie_complete(vd);
+-
+-              /* Submit queued descriptors after processing the completed ones */
+-              axi_chan_start_first_queued(chan);
+       }
+ out:
+diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+index 454904d996540..ac571b413b21c 100644
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+@@ -104,6 +104,7 @@ struct axi_dma_desc {
+       u32                             completed_blocks;
+       u32                             length;
+       u32                             period_len;
++      u32                             nr_hw_descs;
+ };
+ struct axi_dma_chan_config {
+-- 
+2.43.0
+
diff --git a/queue-6.9/batman-adv-bypass-empty-buckets-in-batadv_purge_orig.patch b/queue-6.9/batman-adv-bypass-empty-buckets-in-batadv_purge_orig.patch
new file mode 100644 (file)
index 0000000..dd8fc44
--- /dev/null
@@ -0,0 +1,110 @@
+From f2444ffdf5a83bb406276a7195832c407aef6baa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 Mar 2024 15:54:38 +0000
+Subject: batman-adv: bypass empty buckets in batadv_purge_orig_ref()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 40dc8ab605894acae1473e434944924a22cfaaa0 ]
+
+Many syzbot reports are pointing to soft lockups in
+batadv_purge_orig_ref() [1]
+
+Root cause is unknown, but we can avoid spending too much
+time there and perhaps get more interesting reports.
+
+[1]
+
+watchdog: BUG: soft lockup - CPU#0 stuck for 27s! [kworker/u4:6:621]
+Modules linked in:
+irq event stamp: 6182794
+ hardirqs last  enabled at (6182793): [<ffff8000801dae10>] __local_bh_enable_ip+0x224/0x44c kernel/softirq.c:386
+ hardirqs last disabled at (6182794): [<ffff80008ad66a78>] __el1_irq arch/arm64/kernel/entry-common.c:533 [inline]
+ hardirqs last disabled at (6182794): [<ffff80008ad66a78>] el1_interrupt+0x24/0x68 arch/arm64/kernel/entry-common.c:551
+ softirqs last  enabled at (6182792): [<ffff80008aab71c4>] spin_unlock_bh include/linux/spinlock.h:396 [inline]
+ softirqs last  enabled at (6182792): [<ffff80008aab71c4>] batadv_purge_orig_ref+0x114c/0x1228 net/batman-adv/originator.c:1287
+ softirqs last disabled at (6182790): [<ffff80008aab61dc>] spin_lock_bh include/linux/spinlock.h:356 [inline]
+ softirqs last disabled at (6182790): [<ffff80008aab61dc>] batadv_purge_orig_ref+0x164/0x1228 net/batman-adv/originator.c:1271
+CPU: 0 PID: 621 Comm: kworker/u4:6 Not tainted 6.8.0-rc7-syzkaller-g707081b61156 #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/29/2024
+Workqueue: bat_events batadv_purge_orig
+pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+ pc : should_resched arch/arm64/include/asm/preempt.h:79 [inline]
+ pc : __local_bh_enable_ip+0x228/0x44c kernel/softirq.c:388
+ lr : __local_bh_enable_ip+0x224/0x44c kernel/softirq.c:386
+sp : ffff800099007970
+x29: ffff800099007980 x28: 1fffe00018fce1bd x27: dfff800000000000
+x26: ffff0000d2620008 x25: ffff0000c7e70de8 x24: 0000000000000001
+x23: 1fffe00018e57781 x22: dfff800000000000 x21: ffff80008aab71c4
+x20: ffff0001b40136c0 x19: ffff0000c72bbc08 x18: 1fffe0001a817bb0
+x17: ffff800125414000 x16: ffff80008032116c x15: 0000000000000001
+x14: 1fffe0001ee9d610 x13: 0000000000000000 x12: 0000000000000003
+x11: 0000000000000000 x10: 0000000000ff0100 x9 : 0000000000000000
+x8 : 00000000005e5789 x7 : ffff80008aab61dc x6 : 0000000000000000
+x5 : 0000000000000000 x4 : 0000000000000001 x3 : 0000000000000000
+x2 : 0000000000000006 x1 : 0000000000000080 x0 : ffff800125414000
+Call trace:
+  __daif_local_irq_enable arch/arm64/include/asm/irqflags.h:27 [inline]
+  arch_local_irq_enable arch/arm64/include/asm/irqflags.h:49 [inline]
+  __local_bh_enable_ip+0x228/0x44c kernel/softirq.c:386
+  __raw_spin_unlock_bh include/linux/spinlock_api_smp.h:167 [inline]
+  _raw_spin_unlock_bh+0x3c/0x4c kernel/locking/spinlock.c:210
+  spin_unlock_bh include/linux/spinlock.h:396 [inline]
+  batadv_purge_orig_ref+0x114c/0x1228 net/batman-adv/originator.c:1287
+  batadv_purge_orig+0x20/0x70 net/batman-adv/originator.c:1300
+  process_one_work+0x694/0x1204 kernel/workqueue.c:2633
+  process_scheduled_works kernel/workqueue.c:2706 [inline]
+  worker_thread+0x938/0xef4 kernel/workqueue.c:2787
+  kthread+0x288/0x310 kernel/kthread.c:388
+  ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:860
+Sending NMI from CPU 0 to CPUs 1:
+NMI backtrace for cpu 1
+CPU: 1 PID: 0 Comm: swapper/1 Not tainted 6.8.0-rc7-syzkaller-g707081b61156 #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/29/2024
+pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+ pc : arch_local_irq_enable+0x8/0xc arch/arm64/include/asm/irqflags.h:51
+ lr : default_idle_call+0xf8/0x128 kernel/sched/idle.c:103
+sp : ffff800093a17d30
+x29: ffff800093a17d30 x28: dfff800000000000 x27: 1ffff00012742fb4
+x26: ffff80008ec9d000 x25: 0000000000000000 x24: 0000000000000002
+x23: 1ffff00011d93a74 x22: ffff80008ec9d3a0 x21: 0000000000000000
+x20: ffff0000c19dbc00 x19: ffff8000802d0fd8 x18: 1fffe00036804396
+x17: ffff80008ec9d000 x16: ffff8000802d089c x15: 0000000000000001
+x14: 1fffe00036805f10 x13: 0000000000000000 x12: 0000000000000003
+x11: 0000000000000001 x10: 0000000000000003 x9 : 0000000000000000
+x8 : 00000000000ce8d1 x7 : ffff8000804609e4 x6 : 0000000000000000
+x5 : 0000000000000001 x4 : 0000000000000001 x3 : ffff80008ad6aac0
+x2 : 0000000000000000 x1 : ffff80008aedea60 x0 : ffff800125436000
+Call trace:
+  __daif_local_irq_enable arch/arm64/include/asm/irqflags.h:27 [inline]
+  arch_local_irq_enable+0x8/0xc arch/arm64/include/asm/irqflags.h:49
+  cpuidle_idle_call kernel/sched/idle.c:170 [inline]
+  do_idle+0x1f0/0x4e8 kernel/sched/idle.c:312
+  cpu_startup_entry+0x5c/0x74 kernel/sched/idle.c:410
+  secondary_start_kernel+0x198/0x1c0 arch/arm64/kernel/smp.c:272
+  __secondary_switched+0xb8/0xbc arch/arm64/kernel/head.S:404
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/batman-adv/originator.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
+index 71c143d4b6d05..ac74f6ead62d5 100644
+--- a/net/batman-adv/originator.c
++++ b/net/batman-adv/originator.c
+@@ -1266,6 +1266,8 @@ void batadv_purge_orig_ref(struct batadv_priv *bat_priv)
+       /* for all origins... */
+       for (i = 0; i < hash->size; i++) {
+               head = &hash->table[i];
++              if (hlist_empty(head))
++                      continue;
+               list_lock = &hash->list_locks[i];
+               spin_lock_bh(list_lock);
+-- 
+2.43.0
+
diff --git a/queue-6.9/block-ioctl-prefer-different-overflow-check.patch b/queue-6.9/block-ioctl-prefer-different-overflow-check.patch
new file mode 100644 (file)
index 0000000..8b74fe3
--- /dev/null
@@ -0,0 +1,88 @@
+From 8b7633082325017cf15beb69b64fd80013e253a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 May 2024 03:53:49 +0000
+Subject: block/ioctl: prefer different overflow check
+
+From: Justin Stitt <justinstitt@google.com>
+
+[ Upstream commit ccb326b5f9e623eb7f130fbbf2505ec0e2dcaff9 ]
+
+Running syzkaller with the newly reintroduced signed integer overflow
+sanitizer shows this report:
+
+[   62.982337] ------------[ cut here ]------------
+[   62.985692] cgroup: Invalid name
+[   62.986211] UBSAN: signed-integer-overflow in ../block/ioctl.c:36:46
+[   62.989370] 9pnet_fd: p9_fd_create_tcp (7343): problem connecting socket to 127.0.0.1
+[   62.992992] 9223372036854775807 + 4095 cannot be represented in type 'long long'
+[   62.997827] 9pnet_fd: p9_fd_create_tcp (7345): problem connecting socket to 127.0.0.1
+[   62.999369] random: crng reseeded on system resumption
+[   63.000634] GUP no longer grows the stack in syz-executor.2 (7353): 20002000-20003000 (20001000)
+[   63.000668] CPU: 0 PID: 7353 Comm: syz-executor.2 Not tainted 6.8.0-rc2-00035-gb3ef86b5a957 #1
+[   63.000677] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+[   63.000682] Call Trace:
+[   63.000686]  <TASK>
+[   63.000731]  dump_stack_lvl+0x93/0xd0
+[   63.000919]  __get_user_pages+0x903/0xd30
+[   63.001030]  __gup_longterm_locked+0x153e/0x1ba0
+[   63.001041]  ? _raw_read_unlock_irqrestore+0x17/0x50
+[   63.001072]  ? try_get_folio+0x29c/0x2d0
+[   63.001083]  internal_get_user_pages_fast+0x1119/0x1530
+[   63.001109]  iov_iter_extract_pages+0x23b/0x580
+[   63.001206]  bio_iov_iter_get_pages+0x4de/0x1220
+[   63.001235]  iomap_dio_bio_iter+0x9b6/0x1410
+[   63.001297]  __iomap_dio_rw+0xab4/0x1810
+[   63.001316]  iomap_dio_rw+0x45/0xa0
+[   63.001328]  ext4_file_write_iter+0xdde/0x1390
+[   63.001372]  vfs_write+0x599/0xbd0
+[   63.001394]  ksys_write+0xc8/0x190
+[   63.001403]  do_syscall_64+0xd4/0x1b0
+[   63.001421]  ? arch_exit_to_user_mode_prepare+0x3a/0x60
+[   63.001479]  entry_SYSCALL_64_after_hwframe+0x6f/0x77
+[   63.001535] RIP: 0033:0x7f7fd3ebf539
+[   63.001551] Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 f1 14 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
+[   63.001562] RSP: 002b:00007f7fd32570c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
+[   63.001584] RAX: ffffffffffffffda RBX: 00007f7fd3ff3f80 RCX: 00007f7fd3ebf539
+[   63.001590] RDX: 4db6d1e4f7e43360 RSI: 0000000020000000 RDI: 0000000000000004
+[   63.001595] RBP: 00007f7fd3f1e496 R08: 0000000000000000 R09: 0000000000000000
+[   63.001599] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+[   63.001604] R13: 0000000000000006 R14: 00007f7fd3ff3f80 R15: 00007ffd415ad2b8
+...
+[   63.018142] ---[ end trace ]---
+
+Historically, the signed integer overflow sanitizer did not work in the
+kernel due to its interaction with `-fwrapv` but this has since been
+changed [1] in the newest version of Clang; It was re-enabled in the
+kernel with Commit 557f8c582a9ba8ab ("ubsan: Reintroduce signed overflow
+sanitizer").
+
+Let's rework this overflow checking logic to not actually perform an
+overflow during the check itself, thus avoiding the UBSAN splat.
+
+[1]: https://github.com/llvm/llvm-project/pull/82432
+
+Signed-off-by: Justin Stitt <justinstitt@google.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20240507-b4-sio-block-ioctl-v3-1-ba0c2b32275e@google.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/ioctl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/block/ioctl.c b/block/ioctl.c
+index f505f9c341eb0..2639ce9df3852 100644
+--- a/block/ioctl.c
++++ b/block/ioctl.c
+@@ -33,7 +33,7 @@ static int blkpg_do_ioctl(struct block_device *bdev,
+       if (op == BLKPG_DEL_PARTITION)
+               return bdev_del_partition(disk, p.pno);
+-      if (p.start < 0 || p.length <= 0 || p.start + p.length < 0)
++      if (p.start < 0 || p.length <= 0 || LLONG_MAX - p.length < p.start)
+               return -EINVAL;
+       /* Check that the partition is aligned to the block size */
+       if (!IS_ALIGNED(p.start | p.length, bdev_logical_block_size(bdev)))
+-- 
+2.43.0
+
diff --git a/queue-6.9/bluetooth-ath3k-fix-multiple-issues-reported-by-chec.patch b/queue-6.9/bluetooth-ath3k-fix-multiple-issues-reported-by-chec.patch
new file mode 100644 (file)
index 0000000..80dde78
--- /dev/null
@@ -0,0 +1,190 @@
+From ec4615daa60c2d782ea403da8b5e87464c57e43f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Apr 2024 00:42:24 +0300
+Subject: Bluetooth: ath3k: Fix multiple issues reported by checkpatch.pl
+
+From: Uri Arev <me@wantyapps.xyz>
+
+[ Upstream commit 68aa21054ec3a1a313af90a5f95ade16c3326d20 ]
+
+This fixes some CHECKs reported by the checkpatch script.
+
+Issues reported in ath3k.c:
+-------
+ath3k.c
+-------
+CHECK: Please don't use multiple blank lines
++
++
+
+CHECK: Blank lines aren't necessary after an open brace '{'
++static const struct usb_device_id ath3k_blist_tbl[] = {
++
+
+CHECK: Alignment should match open parenthesis
++static int ath3k_load_firmware(struct usb_device *udev,
++                               const struct firmware *firmware)
+
+CHECK: Alignment should match open parenthesis
++               err = usb_bulk_msg(udev, pipe, send_buf, size,
++                                       &len, 3000);
+
+CHECK: Unnecessary parentheses around 'len != size'
++               if (err || (len != size)) {
+
+CHECK: Alignment should match open parenthesis
++static int ath3k_get_version(struct usb_device *udev,
++                       struct ath3k_version *version)
+
+CHECK: Alignment should match open parenthesis
++static int ath3k_load_fwfile(struct usb_device *udev,
++               const struct firmware *firmware)
+
+CHECK: Alignment should match open parenthesis
++               err = usb_bulk_msg(udev, pipe, send_buf, size,
++                                       &len, 3000);
+
+CHECK: Unnecessary parentheses around 'len != size'
++               if (err || (len != size)) {
+
+CHECK: Blank lines aren't necessary after an open brace '{'
++       switch (fw_version.ref_clock) {
++
+
+CHECK: Alignment should match open parenthesis
++       snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s",
++               le32_to_cpu(fw_version.rom_version), clk_value, ".dfu");
+
+CHECK: Alignment should match open parenthesis
++static int ath3k_probe(struct usb_interface *intf,
++                       const struct usb_device_id *id)
+
+CHECK: Alignment should match open parenthesis
++                       BT_ERR("Firmware file \"%s\" not found",
++                                                       ATH3K_FIRMWARE);
+
+CHECK: Alignment should match open parenthesis
++               BT_ERR("Firmware file \"%s\" request failed (err=%d)",
++                                               ATH3K_FIRMWARE, ret);
+
+total: 0 errors, 0 warnings, 14 checks, 540 lines checked
+
+Signed-off-by: Uri Arev <me@wantyapps.xyz>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/ath3k.c | 25 +++++++++++--------------
+ 1 file changed, 11 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
+index 88262d3a93923..ce97b336fbfb8 100644
+--- a/drivers/bluetooth/ath3k.c
++++ b/drivers/bluetooth/ath3k.c
+@@ -3,7 +3,6 @@
+  * Copyright (c) 2008-2009 Atheros Communications Inc.
+  */
+-
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+@@ -128,7 +127,6 @@ MODULE_DEVICE_TABLE(usb, ath3k_table);
+  * for AR3012
+  */
+ static const struct usb_device_id ath3k_blist_tbl[] = {
+-
+       /* Atheros AR3012 with sflash firmware*/
+       { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 },
+@@ -202,7 +200,7 @@ static inline void ath3k_log_failed_loading(int err, int len, int size,
+ #define TIMEGAP_USEC_MAX      100
+ static int ath3k_load_firmware(struct usb_device *udev,
+-                              const struct firmware *firmware)
++                             const struct firmware *firmware)
+ {
+       u8 *send_buf;
+       int len = 0;
+@@ -237,9 +235,9 @@ static int ath3k_load_firmware(struct usb_device *udev,
+               memcpy(send_buf, firmware->data + sent, size);
+               err = usb_bulk_msg(udev, pipe, send_buf, size,
+-                                      &len, 3000);
++                                 &len, 3000);
+-              if (err || (len != size)) {
++              if (err || len != size) {
+                       ath3k_log_failed_loading(err, len, size, count);
+                       goto error;
+               }
+@@ -262,7 +260,7 @@ static int ath3k_get_state(struct usb_device *udev, unsigned char *state)
+ }
+ static int ath3k_get_version(struct usb_device *udev,
+-                      struct ath3k_version *version)
++                           struct ath3k_version *version)
+ {
+       return usb_control_msg_recv(udev, 0, ATH3K_GETVERSION,
+                                   USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
+@@ -271,7 +269,7 @@ static int ath3k_get_version(struct usb_device *udev,
+ }
+ static int ath3k_load_fwfile(struct usb_device *udev,
+-              const struct firmware *firmware)
++                           const struct firmware *firmware)
+ {
+       u8 *send_buf;
+       int len = 0;
+@@ -310,8 +308,8 @@ static int ath3k_load_fwfile(struct usb_device *udev,
+               memcpy(send_buf, firmware->data + sent, size);
+               err = usb_bulk_msg(udev, pipe, send_buf, size,
+-                                      &len, 3000);
+-              if (err || (len != size)) {
++                                 &len, 3000);
++              if (err || len != size) {
+                       ath3k_log_failed_loading(err, len, size, count);
+                       kfree(send_buf);
+                       return err;
+@@ -425,7 +423,6 @@ static int ath3k_load_syscfg(struct usb_device *udev)
+       }
+       switch (fw_version.ref_clock) {
+-
+       case ATH3K_XTAL_FREQ_26M:
+               clk_value = 26;
+               break;
+@@ -441,7 +438,7 @@ static int ath3k_load_syscfg(struct usb_device *udev)
+       }
+       snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s",
+-              le32_to_cpu(fw_version.rom_version), clk_value, ".dfu");
++               le32_to_cpu(fw_version.rom_version), clk_value, ".dfu");
+       ret = request_firmware(&firmware, filename, &udev->dev);
+       if (ret < 0) {
+@@ -456,7 +453,7 @@ static int ath3k_load_syscfg(struct usb_device *udev)
+ }
+ static int ath3k_probe(struct usb_interface *intf,
+-                      const struct usb_device_id *id)
++                     const struct usb_device_id *id)
+ {
+       const struct firmware *firmware;
+       struct usb_device *udev = interface_to_usbdev(intf);
+@@ -505,10 +502,10 @@ static int ath3k_probe(struct usb_interface *intf,
+       if (ret < 0) {
+               if (ret == -ENOENT)
+                       BT_ERR("Firmware file \"%s\" not found",
+-                                                      ATH3K_FIRMWARE);
++                             ATH3K_FIRMWARE);
+               else
+                       BT_ERR("Firmware file \"%s\" request failed (err=%d)",
+-                                                      ATH3K_FIRMWARE, ret);
++                             ATH3K_FIRMWARE, ret);
+               return ret;
+       }
+-- 
+2.43.0
+
diff --git a/queue-6.9/bpf-avoid-kfree_rcu-under-lock-in-bpf_lpm_trie.patch b/queue-6.9/bpf-avoid-kfree_rcu-under-lock-in-bpf_lpm_trie.patch
new file mode 100644 (file)
index 0000000..18d703f
--- /dev/null
@@ -0,0 +1,102 @@
+From 4cf47ae2ac977f2150800aa5dabd7bfaf2093d4b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Mar 2024 10:14:39 -0700
+Subject: bpf: Avoid kfree_rcu() under lock in bpf_lpm_trie.
+
+From: Alexei Starovoitov <ast@kernel.org>
+
+[ Upstream commit 59f2f841179aa6a0899cb9cf53659149a35749b7 ]
+
+syzbot reported the following lock sequence:
+cpu 2:
+  grabs timer_base lock
+    spins on bpf_lpm lock
+
+cpu 1:
+  grab rcu krcp lock
+    spins on timer_base lock
+
+cpu 0:
+  grab bpf_lpm lock
+    spins on rcu krcp lock
+
+bpf_lpm lock can be the same.
+timer_base lock can also be the same due to timer migration.
+but rcu krcp lock is always per-cpu, so it cannot be the same lock.
+Hence it's a false positive.
+To avoid lockdep complaining move kfree_rcu() after spin_unlock.
+
+Reported-by: syzbot+1fa663a2100308ab6eab@syzkaller.appspotmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20240329171439.37813-1-alexei.starovoitov@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/lpm_trie.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c
+index 050fe1ebf0f7d..d0febf07051ed 100644
+--- a/kernel/bpf/lpm_trie.c
++++ b/kernel/bpf/lpm_trie.c
+@@ -308,6 +308,7 @@ static long trie_update_elem(struct bpf_map *map,
+ {
+       struct lpm_trie *trie = container_of(map, struct lpm_trie, map);
+       struct lpm_trie_node *node, *im_node = NULL, *new_node = NULL;
++      struct lpm_trie_node *free_node = NULL;
+       struct lpm_trie_node __rcu **slot;
+       struct bpf_lpm_trie_key_u8 *key = _key;
+       unsigned long irq_flags;
+@@ -382,7 +383,7 @@ static long trie_update_elem(struct bpf_map *map,
+                       trie->n_entries--;
+               rcu_assign_pointer(*slot, new_node);
+-              kfree_rcu(node, rcu);
++              free_node = node;
+               goto out;
+       }
+@@ -429,6 +430,7 @@ static long trie_update_elem(struct bpf_map *map,
+       }
+       spin_unlock_irqrestore(&trie->lock, irq_flags);
++      kfree_rcu(free_node, rcu);
+       return ret;
+ }
+@@ -437,6 +439,7 @@ static long trie_update_elem(struct bpf_map *map,
+ static long trie_delete_elem(struct bpf_map *map, void *_key)
+ {
+       struct lpm_trie *trie = container_of(map, struct lpm_trie, map);
++      struct lpm_trie_node *free_node = NULL, *free_parent = NULL;
+       struct bpf_lpm_trie_key_u8 *key = _key;
+       struct lpm_trie_node __rcu **trim, **trim2;
+       struct lpm_trie_node *node, *parent;
+@@ -506,8 +509,8 @@ static long trie_delete_elem(struct bpf_map *map, void *_key)
+               else
+                       rcu_assign_pointer(
+                               *trim2, rcu_access_pointer(parent->child[0]));
+-              kfree_rcu(parent, rcu);
+-              kfree_rcu(node, rcu);
++              free_parent = parent;
++              free_node = node;
+               goto out;
+       }
+@@ -521,10 +524,12 @@ static long trie_delete_elem(struct bpf_map *map, void *_key)
+               rcu_assign_pointer(*trim, rcu_access_pointer(node->child[1]));
+       else
+               RCU_INIT_POINTER(*trim, NULL);
+-      kfree_rcu(node, rcu);
++      free_node = node;
+ out:
+       spin_unlock_irqrestore(&trie->lock, irq_flags);
++      kfree_rcu(free_parent, rcu);
++      kfree_rcu(free_node, rcu);
+       return ret;
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.9/bpf-avoid-uninitialized-warnings-in-verifier_global_.patch b/queue-6.9/bpf-avoid-uninitialized-warnings-in-verifier_global_.patch
new file mode 100644 (file)
index 0000000..fdc7d34
--- /dev/null
@@ -0,0 +1,69 @@
+From ea4f0bc17ae646ce580b331db8736d05149d9bff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 May 2024 20:47:56 +0200
+Subject: bpf: avoid uninitialized warnings in verifier_global_subprogs.c
+
+From: Jose E. Marchesi <jose.marchesi@oracle.com>
+
+[ Upstream commit cd3fc3b9782130a5bc1dc3dfccffbc1657637a93 ]
+
+[Changes from V1:
+- The warning to disable is -Wmaybe-uninitialized, not -Wuninitialized.
+- This warning is only supported in GCC.]
+
+The BPF selftest verifier_global_subprogs.c contains code that
+purposedly performs out of bounds access to memory, to check whether
+the kernel verifier is able to catch them.  For example:
+
+  __noinline int global_unsupp(const int *mem)
+  {
+       if (!mem)
+               return 0;
+       return mem[100]; /* BOOM */
+  }
+
+With -O1 and higher and no inlining, GCC notices this fact and emits a
+"maybe uninitialized" warning.  This is by design.  Note that the
+emission of these warnings is highly dependent on the precise
+optimizations that are performed.
+
+This patch adds a compiler pragma to verifier_global_subprogs.c to
+ignore these warnings.
+
+Tested in bpf-next master.
+No regressions.
+
+Signed-off-by: Jose E. Marchesi <jose.marchesi@oracle.com>
+Cc: david.faust@oracle.com
+Cc: cupertino.miranda@oracle.com
+Cc: Yonghong Song <yonghong.song@linux.dev>
+Cc: Eduard Zingerman <eddyz87@gmail.com>
+Acked-by: Yonghong Song <yonghong.song@linux.dev>
+Link: https://lore.kernel.org/r/20240507184756.1772-1-jose.marchesi@oracle.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../testing/selftests/bpf/progs/verifier_global_subprogs.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/tools/testing/selftests/bpf/progs/verifier_global_subprogs.c b/tools/testing/selftests/bpf/progs/verifier_global_subprogs.c
+index baff5ffe94051..a9fc30ed4d732 100644
+--- a/tools/testing/selftests/bpf/progs/verifier_global_subprogs.c
++++ b/tools/testing/selftests/bpf/progs/verifier_global_subprogs.c
+@@ -8,6 +8,13 @@
+ #include "xdp_metadata.h"
+ #include "bpf_kfuncs.h"
++/* The compiler may be able to detect the access to uninitialized
++   memory in the routines performing out of bound memory accesses and
++   emit warnings about it.  This is the case of GCC. */
++#if !defined(__clang__)
++#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
++#endif
++
+ int arr[1];
+ int unkn_idx;
+ const volatile bool call_dead_subprog = false;
+-- 
+2.43.0
+
diff --git a/queue-6.9/cgroup-cpuset-make-cpuset-hotplug-processing-synchro.patch b/queue-6.9/cgroup-cpuset-make-cpuset-hotplug-processing-synchro.patch
new file mode 100644 (file)
index 0000000..d4c3343
--- /dev/null
@@ -0,0 +1,462 @@
+From 4b7d38a52a42bec3bdacdff0de92db3090ca492b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Apr 2024 09:47:48 -0400
+Subject: cgroup/cpuset: Make cpuset hotplug processing synchronous
+
+From: Waiman Long <longman@redhat.com>
+
+[ Upstream commit 2125c0034c5dfd61171b494bd309bb7637bff6eb ]
+
+Since commit 3a5a6d0c2b03("cpuset: don't nest cgroup_mutex inside
+get_online_cpus()"), cpuset hotplug was done asynchronously via a work
+function. This is to avoid recursive locking of cgroup_mutex.
+
+Since then, the cgroup locking scheme has changed quite a bit. A
+cpuset_mutex was introduced to protect cpuset specific operations.
+The cpuset_mutex is then replaced by a cpuset_rwsem. With commit
+d74b27d63a8b ("cgroup/cpuset: Change cpuset_rwsem and hotplug lock
+order"), cpu_hotplug_lock is acquired before cpuset_rwsem. Later on,
+cpuset_rwsem is reverted back to cpuset_mutex. All these locking changes
+allow the hotplug code to call into cpuset core directly.
+
+The following commits were also merged due to the asynchronous nature
+of cpuset hotplug processing.
+
+  - commit b22afcdf04c9 ("cpu/hotplug: Cure the cpusets trainwreck")
+  - commit 50e76632339d ("sched/cpuset/pm: Fix cpuset vs. suspend-resume
+    bugs")
+  - commit 28b89b9e6f7b ("cpuset: handle race between CPU hotplug and
+    cpuset_hotplug_work")
+
+Clean up all these bandages by making cpuset hotplug
+processing synchronous again with the exception that the call to
+cgroup_transfer_tasks() to transfer tasks out of an empty cgroup v1
+cpuset, if necessary, will still be done via a work function due to the
+existing cgroup_mutex -> cpu_hotplug_lock dependency. It is possible
+to reverse that dependency, but that will require updating a number of
+different cgroup controllers. This special hotplug code path should be
+rarely taken anyway.
+
+As all the cpuset states will be updated by the end of the hotplug
+operation, we can revert most the above commits except commit
+50e76632339d ("sched/cpuset/pm: Fix cpuset vs. suspend-resume bugs")
+which is partially reverted.  Also removing some cpus_read_lock trylock
+attempts in the cpuset partition code as they are no longer necessary
+since the cpu_hotplug_lock is now held for the whole duration of the
+cpuset hotplug code path.
+
+Signed-off-by: Waiman Long <longman@redhat.com>
+Tested-by: Valentin Schneider <vschneid@redhat.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/cpuset.h |   3 -
+ kernel/cgroup/cpuset.c | 141 ++++++++++++++++-------------------------
+ kernel/cpu.c           |  48 --------------
+ kernel/power/process.c |   2 -
+ 4 files changed, 56 insertions(+), 138 deletions(-)
+
+diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
+index 0ce6ff0d9c9aa..de4cf0ee96f79 100644
+--- a/include/linux/cpuset.h
++++ b/include/linux/cpuset.h
+@@ -70,7 +70,6 @@ extern int cpuset_init(void);
+ extern void cpuset_init_smp(void);
+ extern void cpuset_force_rebuild(void);
+ extern void cpuset_update_active_cpus(void);
+-extern void cpuset_wait_for_hotplug(void);
+ extern void inc_dl_tasks_cs(struct task_struct *task);
+ extern void dec_dl_tasks_cs(struct task_struct *task);
+ extern void cpuset_lock(void);
+@@ -185,8 +184,6 @@ static inline void cpuset_update_active_cpus(void)
+       partition_sched_domains(1, NULL, NULL);
+ }
+-static inline void cpuset_wait_for_hotplug(void) { }
+-
+ static inline void inc_dl_tasks_cs(struct task_struct *task) { }
+ static inline void dec_dl_tasks_cs(struct task_struct *task) { }
+ static inline void cpuset_lock(void) { }
+diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
+index da24187c4e025..73ef0dabc3f22 100644
+--- a/kernel/cgroup/cpuset.c
++++ b/kernel/cgroup/cpuset.c
+@@ -201,6 +201,14 @@ struct cpuset {
+       struct list_head remote_sibling;
+ };
++/*
++ * Legacy hierarchy call to cgroup_transfer_tasks() is handled asynchrously
++ */
++struct cpuset_remove_tasks_struct {
++      struct work_struct work;
++      struct cpuset *cs;
++};
++
+ /*
+  * Exclusive CPUs distributed out to sub-partitions of top_cpuset
+  */
+@@ -449,12 +457,6 @@ static DEFINE_SPINLOCK(callback_lock);
+ static struct workqueue_struct *cpuset_migrate_mm_wq;
+-/*
+- * CPU / memory hotplug is handled asynchronously.
+- */
+-static void cpuset_hotplug_workfn(struct work_struct *work);
+-static DECLARE_WORK(cpuset_hotplug_work, cpuset_hotplug_workfn);
+-
+ static DECLARE_WAIT_QUEUE_HEAD(cpuset_attach_wq);
+ static inline void check_insane_mems_config(nodemask_t *nodes)
+@@ -540,22 +542,10 @@ static void guarantee_online_cpus(struct task_struct *tsk,
+       rcu_read_lock();
+       cs = task_cs(tsk);
+-      while (!cpumask_intersects(cs->effective_cpus, pmask)) {
++      while (!cpumask_intersects(cs->effective_cpus, pmask))
+               cs = parent_cs(cs);
+-              if (unlikely(!cs)) {
+-                      /*
+-                       * The top cpuset doesn't have any online cpu as a
+-                       * consequence of a race between cpuset_hotplug_work
+-                       * and cpu hotplug notifier.  But we know the top
+-                       * cpuset's effective_cpus is on its way to be
+-                       * identical to cpu_online_mask.
+-                       */
+-                      goto out_unlock;
+-              }
+-      }
+-      cpumask_and(pmask, pmask, cs->effective_cpus);
+-out_unlock:
++      cpumask_and(pmask, pmask, cs->effective_cpus);
+       rcu_read_unlock();
+ }
+@@ -1217,7 +1207,7 @@ static void rebuild_sched_domains_locked(void)
+       /*
+        * If we have raced with CPU hotplug, return early to avoid
+        * passing doms with offlined cpu to partition_sched_domains().
+-       * Anyways, cpuset_hotplug_workfn() will rebuild sched domains.
++       * Anyways, cpuset_handle_hotplug() will rebuild sched domains.
+        *
+        * With no CPUs in any subpartitions, top_cpuset's effective CPUs
+        * should be the same as the active CPUs, so checking only top_cpuset
+@@ -1260,12 +1250,17 @@ static void rebuild_sched_domains_locked(void)
+ }
+ #endif /* CONFIG_SMP */
+-void rebuild_sched_domains(void)
++static void rebuild_sched_domains_cpuslocked(void)
+ {
+-      cpus_read_lock();
+       mutex_lock(&cpuset_mutex);
+       rebuild_sched_domains_locked();
+       mutex_unlock(&cpuset_mutex);
++}
++
++void rebuild_sched_domains(void)
++{
++      cpus_read_lock();
++      rebuild_sched_domains_cpuslocked();
+       cpus_read_unlock();
+ }
+@@ -2079,14 +2074,11 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
+       /*
+        * For partcmd_update without newmask, it is being called from
+-       * cpuset_hotplug_workfn() where cpus_read_lock() wasn't taken.
+-       * Update the load balance flag and scheduling domain if
+-       * cpus_read_trylock() is successful.
++       * cpuset_handle_hotplug(). Update the load balance flag and
++       * scheduling domain accordingly.
+        */
+-      if ((cmd == partcmd_update) && !newmask && cpus_read_trylock()) {
++      if ((cmd == partcmd_update) && !newmask)
+               update_partition_sd_lb(cs, old_prs);
+-              cpus_read_unlock();
+-      }
+       notify_partition_change(cs, old_prs);
+       return 0;
+@@ -3599,8 +3591,8 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of,
+        * proceeding, so that we don't end up keep removing tasks added
+        * after execution capability is restored.
+        *
+-       * cpuset_hotplug_work calls back into cgroup core via
+-       * cgroup_transfer_tasks() and waiting for it from a cgroupfs
++       * cpuset_handle_hotplug may call back into cgroup core asynchronously
++       * via cgroup_transfer_tasks() and waiting for it from a cgroupfs
+        * operation like this one can lead to a deadlock through kernfs
+        * active_ref protection.  Let's break the protection.  Losing the
+        * protection is okay as we check whether @cs is online after
+@@ -3609,7 +3601,6 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of,
+        */
+       css_get(&cs->css);
+       kernfs_break_active_protection(of->kn);
+-      flush_work(&cpuset_hotplug_work);
+       cpus_read_lock();
+       mutex_lock(&cpuset_mutex);
+@@ -4354,6 +4345,16 @@ static void remove_tasks_in_empty_cpuset(struct cpuset *cs)
+       }
+ }
++static void cpuset_migrate_tasks_workfn(struct work_struct *work)
++{
++      struct cpuset_remove_tasks_struct *s;
++
++      s = container_of(work, struct cpuset_remove_tasks_struct, work);
++      remove_tasks_in_empty_cpuset(s->cs);
++      css_put(&s->cs->css);
++      kfree(s);
++}
++
+ static void
+ hotplug_update_tasks_legacy(struct cpuset *cs,
+                           struct cpumask *new_cpus, nodemask_t *new_mems,
+@@ -4383,12 +4384,21 @@ hotplug_update_tasks_legacy(struct cpuset *cs,
+       /*
+        * Move tasks to the nearest ancestor with execution resources,
+        * This is full cgroup operation which will also call back into
+-       * cpuset. Should be done outside any lock.
++       * cpuset. Execute it asynchronously using workqueue.
+        */
+-      if (is_empty) {
+-              mutex_unlock(&cpuset_mutex);
+-              remove_tasks_in_empty_cpuset(cs);
+-              mutex_lock(&cpuset_mutex);
++      if (is_empty && cs->css.cgroup->nr_populated_csets &&
++          css_tryget_online(&cs->css)) {
++              struct cpuset_remove_tasks_struct *s;
++
++              s = kzalloc(sizeof(*s), GFP_KERNEL);
++              if (WARN_ON_ONCE(!s)) {
++                      css_put(&cs->css);
++                      return;
++              }
++
++              s->cs = cs;
++              INIT_WORK(&s->work, cpuset_migrate_tasks_workfn);
++              schedule_work(&s->work);
+       }
+ }
+@@ -4421,30 +4431,6 @@ void cpuset_force_rebuild(void)
+       force_rebuild = true;
+ }
+-/*
+- * Attempt to acquire a cpus_read_lock while a hotplug operation may be in
+- * progress.
+- * Return: true if successful, false otherwise
+- *
+- * To avoid circular lock dependency between cpuset_mutex and cpus_read_lock,
+- * cpus_read_trylock() is used here to acquire the lock.
+- */
+-static bool cpuset_hotplug_cpus_read_trylock(void)
+-{
+-      int retries = 0;
+-
+-      while (!cpus_read_trylock()) {
+-              /*
+-               * CPU hotplug still in progress. Retry 5 times
+-               * with a 10ms wait before bailing out.
+-               */
+-              if (++retries > 5)
+-                      return false;
+-              msleep(10);
+-      }
+-      return true;
+-}
+-
+ /**
+  * cpuset_hotplug_update_tasks - update tasks in a cpuset for hotunplug
+  * @cs: cpuset in interest
+@@ -4493,13 +4479,11 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp)
+               compute_partition_effective_cpumask(cs, &new_cpus);
+       if (remote && cpumask_empty(&new_cpus) &&
+-          partition_is_populated(cs, NULL) &&
+-          cpuset_hotplug_cpus_read_trylock()) {
++          partition_is_populated(cs, NULL)) {
+               remote_partition_disable(cs, tmp);
+               compute_effective_cpumask(&new_cpus, cs, parent);
+               remote = false;
+               cpuset_force_rebuild();
+-              cpus_read_unlock();
+       }
+       /*
+@@ -4519,18 +4503,8 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp)
+       else if (is_partition_valid(parent) && is_partition_invalid(cs))
+               partcmd = partcmd_update;
+-      /*
+-       * cpus_read_lock needs to be held before calling
+-       * update_parent_effective_cpumask(). To avoid circular lock
+-       * dependency between cpuset_mutex and cpus_read_lock,
+-       * cpus_read_trylock() is used here to acquire the lock.
+-       */
+       if (partcmd >= 0) {
+-              if (!cpuset_hotplug_cpus_read_trylock())
+-                      goto update_tasks;
+-
+               update_parent_effective_cpumask(cs, partcmd, NULL, tmp);
+-              cpus_read_unlock();
+               if ((partcmd == partcmd_invalidate) || is_partition_valid(cs)) {
+                       compute_partition_effective_cpumask(cs, &new_cpus);
+                       cpuset_force_rebuild();
+@@ -4558,8 +4532,7 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp)
+ }
+ /**
+- * cpuset_hotplug_workfn - handle CPU/memory hotunplug for a cpuset
+- * @work: unused
++ * cpuset_handle_hotplug - handle CPU/memory hot{,un}plug for a cpuset
+  *
+  * This function is called after either CPU or memory configuration has
+  * changed and updates cpuset accordingly.  The top_cpuset is always
+@@ -4573,8 +4546,10 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp)
+  *
+  * Note that CPU offlining during suspend is ignored.  We don't modify
+  * cpusets across suspend/resume cycles at all.
++ *
++ * CPU / memory hotplug is handled synchronously.
+  */
+-static void cpuset_hotplug_workfn(struct work_struct *work)
++static void cpuset_handle_hotplug(void)
+ {
+       static cpumask_t new_cpus;
+       static nodemask_t new_mems;
+@@ -4585,6 +4560,7 @@ static void cpuset_hotplug_workfn(struct work_struct *work)
+       if (on_dfl && !alloc_cpumasks(NULL, &tmp))
+               ptmp = &tmp;
++      lockdep_assert_cpus_held();
+       mutex_lock(&cpuset_mutex);
+       /* fetch the available cpus/mems and find out which changed how */
+@@ -4666,7 +4642,7 @@ static void cpuset_hotplug_workfn(struct work_struct *work)
+       /* rebuild sched domains if cpus_allowed has changed */
+       if (cpus_updated || force_rebuild) {
+               force_rebuild = false;
+-              rebuild_sched_domains();
++              rebuild_sched_domains_cpuslocked();
+       }
+       free_cpumasks(NULL, ptmp);
+@@ -4679,12 +4655,7 @@ void cpuset_update_active_cpus(void)
+        * inside cgroup synchronization.  Bounce actual hotplug processing
+        * to a work item to avoid reverse locking order.
+        */
+-      schedule_work(&cpuset_hotplug_work);
+-}
+-
+-void cpuset_wait_for_hotplug(void)
+-{
+-      flush_work(&cpuset_hotplug_work);
++      cpuset_handle_hotplug();
+ }
+ /*
+@@ -4695,7 +4666,7 @@ void cpuset_wait_for_hotplug(void)
+ static int cpuset_track_online_nodes(struct notifier_block *self,
+                               unsigned long action, void *arg)
+ {
+-      schedule_work(&cpuset_hotplug_work);
++      cpuset_handle_hotplug();
+       return NOTIFY_OK;
+ }
+diff --git a/kernel/cpu.c b/kernel/cpu.c
+index 63447eb85dab6..563877d6c28b6 100644
+--- a/kernel/cpu.c
++++ b/kernel/cpu.c
+@@ -1208,52 +1208,6 @@ void __init cpuhp_threads_init(void)
+       kthread_unpark(this_cpu_read(cpuhp_state.thread));
+ }
+-/*
+- *
+- * Serialize hotplug trainwrecks outside of the cpu_hotplug_lock
+- * protected region.
+- *
+- * The operation is still serialized against concurrent CPU hotplug via
+- * cpu_add_remove_lock, i.e. CPU map protection.  But it is _not_
+- * serialized against other hotplug related activity like adding or
+- * removing of state callbacks and state instances, which invoke either the
+- * startup or the teardown callback of the affected state.
+- *
+- * This is required for subsystems which are unfixable vs. CPU hotplug and
+- * evade lock inversion problems by scheduling work which has to be
+- * completed _before_ cpu_up()/_cpu_down() returns.
+- *
+- * Don't even think about adding anything to this for any new code or even
+- * drivers. It's only purpose is to keep existing lock order trainwrecks
+- * working.
+- *
+- * For cpu_down() there might be valid reasons to finish cleanups which are
+- * not required to be done under cpu_hotplug_lock, but that's a different
+- * story and would be not invoked via this.
+- */
+-static void cpu_up_down_serialize_trainwrecks(bool tasks_frozen)
+-{
+-      /*
+-       * cpusets delegate hotplug operations to a worker to "solve" the
+-       * lock order problems. Wait for the worker, but only if tasks are
+-       * _not_ frozen (suspend, hibernate) as that would wait forever.
+-       *
+-       * The wait is required because otherwise the hotplug operation
+-       * returns with inconsistent state, which could even be observed in
+-       * user space when a new CPU is brought up. The CPU plug uevent
+-       * would be delivered and user space reacting on it would fail to
+-       * move tasks to the newly plugged CPU up to the point where the
+-       * work has finished because up to that point the newly plugged CPU
+-       * is not assignable in cpusets/cgroups. On unplug that's not
+-       * necessarily a visible issue, but it is still inconsistent state,
+-       * which is the real problem which needs to be "fixed". This can't
+-       * prevent the transient state between scheduling the work and
+-       * returning from waiting for it.
+-       */
+-      if (!tasks_frozen)
+-              cpuset_wait_for_hotplug();
+-}
+-
+ #ifdef CONFIG_HOTPLUG_CPU
+ #ifndef arch_clear_mm_cpumask_cpu
+ #define arch_clear_mm_cpumask_cpu(cpu, mm) cpumask_clear_cpu(cpu, mm_cpumask(mm))
+@@ -1494,7 +1448,6 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen,
+        */
+       lockup_detector_cleanup();
+       arch_smt_update();
+-      cpu_up_down_serialize_trainwrecks(tasks_frozen);
+       return ret;
+ }
+@@ -1728,7 +1681,6 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen, enum cpuhp_state target)
+ out:
+       cpus_write_unlock();
+       arch_smt_update();
+-      cpu_up_down_serialize_trainwrecks(tasks_frozen);
+       return ret;
+ }
+diff --git a/kernel/power/process.c b/kernel/power/process.c
+index cae81a87cc91e..66ac067d9ae64 100644
+--- a/kernel/power/process.c
++++ b/kernel/power/process.c
+@@ -194,8 +194,6 @@ void thaw_processes(void)
+       __usermodehelper_set_disable_depth(UMH_FREEZING);
+       thaw_workqueues();
+-      cpuset_wait_for_hotplug();
+-
+       read_lock(&tasklist_lock);
+       for_each_process_thread(g, p) {
+               /* No other threads should have PF_SUSPEND_TASK set */
+-- 
+2.43.0
+
diff --git a/queue-6.9/clocksource-make-watchdog-and-suspend-timing-multipl.patch b/queue-6.9/clocksource-make-watchdog-and-suspend-timing-multipl.patch
new file mode 100644 (file)
index 0000000..a8b5011
--- /dev/null
@@ -0,0 +1,143 @@
+From 9dcfa1b9a635e6f58ff76a81653f7ef64df382cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Mar 2024 08:40:23 +0200
+Subject: clocksource: Make watchdog and suspend-timing multiplication overflow
+ safe
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit d0304569fb019d1bcfbbbce1ce6df6b96f04079b ]
+
+Kernel timekeeping is designed to keep the change in cycles (since the last
+timer interrupt) below max_cycles, which prevents multiplication overflow
+when converting cycles to nanoseconds. However, if timer interrupts stop,
+the clocksource_cyc2ns() calculation will eventually overflow.
+
+Add protection against that. Simplify by folding together
+clocksource_delta() and clocksource_cyc2ns() into cycles_to_nsec_safe().
+Check against max_cycles, falling back to a slower higher precision
+calculation.
+
+Suggested-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Link: https://lore.kernel.org/r/20240325064023.2997-20-adrian.hunter@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/clocksource.c | 42 +++++++++++++++++++--------------------
+ 1 file changed, 20 insertions(+), 22 deletions(-)
+
+diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
+index e5b260aa0e02c..4d50d53ac719f 100644
+--- a/kernel/time/clocksource.c
++++ b/kernel/time/clocksource.c
+@@ -20,6 +20,16 @@
+ #include "tick-internal.h"
+ #include "timekeeping_internal.h"
++static noinline u64 cycles_to_nsec_safe(struct clocksource *cs, u64 start, u64 end)
++{
++      u64 delta = clocksource_delta(end, start, cs->mask);
++
++      if (likely(delta < cs->max_cycles))
++              return clocksource_cyc2ns(delta, cs->mult, cs->shift);
++
++      return mul_u64_u32_shr(delta, cs->mult, cs->shift);
++}
++
+ /**
+  * clocks_calc_mult_shift - calculate mult/shift factors for scaled math of clocks
+  * @mult:     pointer to mult variable
+@@ -222,8 +232,8 @@ enum wd_read_status {
+ static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow, u64 *wdnow)
+ {
+       unsigned int nretries, max_retries;
+-      u64 wd_end, wd_end2, wd_delta;
+       int64_t wd_delay, wd_seq_delay;
++      u64 wd_end, wd_end2;
+       max_retries = clocksource_get_max_watchdog_retry();
+       for (nretries = 0; nretries <= max_retries; nretries++) {
+@@ -234,9 +244,7 @@ static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow,
+               wd_end2 = watchdog->read(watchdog);
+               local_irq_enable();
+-              wd_delta = clocksource_delta(wd_end, *wdnow, watchdog->mask);
+-              wd_delay = clocksource_cyc2ns(wd_delta, watchdog->mult,
+-                                            watchdog->shift);
++              wd_delay = cycles_to_nsec_safe(watchdog, *wdnow, wd_end);
+               if (wd_delay <= WATCHDOG_MAX_SKEW) {
+                       if (nretries > 1 || nretries >= max_retries) {
+                               pr_warn("timekeeping watchdog on CPU%d: %s retried %d times before success\n",
+@@ -254,8 +262,7 @@ static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow,
+                * report system busy, reinit the watchdog and skip the current
+                * watchdog test.
+                */
+-              wd_delta = clocksource_delta(wd_end2, wd_end, watchdog->mask);
+-              wd_seq_delay = clocksource_cyc2ns(wd_delta, watchdog->mult, watchdog->shift);
++              wd_seq_delay = cycles_to_nsec_safe(watchdog, wd_end, wd_end2);
+               if (wd_seq_delay > WATCHDOG_MAX_SKEW/2)
+                       goto skip_test;
+       }
+@@ -366,8 +373,7 @@ void clocksource_verify_percpu(struct clocksource *cs)
+               delta = (csnow_end - csnow_mid) & cs->mask;
+               if (delta < 0)
+                       cpumask_set_cpu(cpu, &cpus_ahead);
+-              delta = clocksource_delta(csnow_end, csnow_begin, cs->mask);
+-              cs_nsec = clocksource_cyc2ns(delta, cs->mult, cs->shift);
++              cs_nsec = cycles_to_nsec_safe(cs, csnow_begin, csnow_end);
+               if (cs_nsec > cs_nsec_max)
+                       cs_nsec_max = cs_nsec;
+               if (cs_nsec < cs_nsec_min)
+@@ -398,8 +404,8 @@ static inline void clocksource_reset_watchdog(void)
+ static void clocksource_watchdog(struct timer_list *unused)
+ {
+-      u64 csnow, wdnow, cslast, wdlast, delta;
+       int64_t wd_nsec, cs_nsec, interval;
++      u64 csnow, wdnow, cslast, wdlast;
+       int next_cpu, reset_pending;
+       struct clocksource *cs;
+       enum wd_read_status read_ret;
+@@ -456,12 +462,8 @@ static void clocksource_watchdog(struct timer_list *unused)
+                       continue;
+               }
+-              delta = clocksource_delta(wdnow, cs->wd_last, watchdog->mask);
+-              wd_nsec = clocksource_cyc2ns(delta, watchdog->mult,
+-                                           watchdog->shift);
+-
+-              delta = clocksource_delta(csnow, cs->cs_last, cs->mask);
+-              cs_nsec = clocksource_cyc2ns(delta, cs->mult, cs->shift);
++              wd_nsec = cycles_to_nsec_safe(watchdog, cs->wd_last, wdnow);
++              cs_nsec = cycles_to_nsec_safe(cs, cs->cs_last, csnow);
+               wdlast = cs->wd_last; /* save these in case we print them */
+               cslast = cs->cs_last;
+               cs->cs_last = csnow;
+@@ -832,7 +834,7 @@ void clocksource_start_suspend_timing(struct clocksource *cs, u64 start_cycles)
+  */
+ u64 clocksource_stop_suspend_timing(struct clocksource *cs, u64 cycle_now)
+ {
+-      u64 now, delta, nsec = 0;
++      u64 now, nsec = 0;
+       if (!suspend_clocksource)
+               return 0;
+@@ -847,12 +849,8 @@ u64 clocksource_stop_suspend_timing(struct clocksource *cs, u64 cycle_now)
+       else
+               now = suspend_clocksource->read(suspend_clocksource);
+-      if (now > suspend_start) {
+-              delta = clocksource_delta(now, suspend_start,
+-                                        suspend_clocksource->mask);
+-              nsec = mul_u64_u32_shr(delta, suspend_clocksource->mult,
+-                                     suspend_clocksource->shift);
+-      }
++      if (now > suspend_start)
++              nsec = cycles_to_nsec_safe(suspend_clocksource, suspend_start, now);
+       /*
+        * Disable the suspend timer to save power if current clocksource is
+-- 
+2.43.0
+
diff --git a/queue-6.9/cpufreq-amd-pstate-fix-memory-leak-on-cpu-epp-exit.patch b/queue-6.9/cpufreq-amd-pstate-fix-memory-leak-on-cpu-epp-exit.patch
new file mode 100644 (file)
index 0000000..e380189
--- /dev/null
@@ -0,0 +1,43 @@
+From 06bc74f02509d5d5afe93e4dba7da825c982039e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 May 2024 14:30:42 +0800
+Subject: cpufreq: amd-pstate: fix memory leak on CPU EPP exit
+
+From: Peng Ma <andypma@tencent.com>
+
+[ Upstream commit cea04f3d9aeebda9d9c063c0dfa71e739c322c81 ]
+
+The cpudata memory from kzalloc() in amd_pstate_epp_cpu_init() is
+not freed in the analogous exit function, so fix that.
+
+Signed-off-by: Peng Ma <andypma@tencent.com>
+Acked-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: Perry Yuan <Perry.Yuan@amd.com>
+[ rjw: Subject and changelog edits ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/amd-pstate.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
+index 6c989d859b396..6af175e6c08ac 100644
+--- a/drivers/cpufreq/amd-pstate.c
++++ b/drivers/cpufreq/amd-pstate.c
+@@ -1462,6 +1462,13 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
+ static int amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
+ {
++      struct amd_cpudata *cpudata = policy->driver_data;
++
++      if (cpudata) {
++              kfree(cpudata);
++              policy->driver_data = NULL;
++      }
++
+       pr_debug("CPU %d exiting\n", policy->cpu);
+       return 0;
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.9/crypto-hisilicon-qm-add-the-err-memory-release-proce.patch b/queue-6.9/crypto-hisilicon-qm-add-the-err-memory-release-proce.patch
new file mode 100644 (file)
index 0000000..39743d9
--- /dev/null
@@ -0,0 +1,46 @@
+From b15c02b8b7d37cdc71a50ada9c2f925fd36059a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Apr 2024 16:00:00 +0800
+Subject: crypto: hisilicon/qm - Add the err memory release process to qm
+ uninit
+
+From: Chenghai Huang <huangchenghai2@huawei.com>
+
+[ Upstream commit c9ccfd5e0ff0dd929ce86d1b5f3c6a414110947a ]
+
+When the qm uninit command is executed, the err data needs to
+be released to prevent memory leakage. The error information
+release operation and uacce_remove are integrated in
+qm_remove_uacce.
+
+So add the qm_remove_uacce to qm uninit to avoid err memory
+leakage.
+
+Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/hisilicon/qm.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
+index 92f0a1d9b4a6b..13e413533f082 100644
+--- a/drivers/crypto/hisilicon/qm.c
++++ b/drivers/crypto/hisilicon/qm.c
+@@ -2893,12 +2893,9 @@ void hisi_qm_uninit(struct hisi_qm *qm)
+       hisi_qm_set_state(qm, QM_NOT_READY);
+       up_write(&qm->qps_lock);
++      qm_remove_uacce(qm);
+       qm_irqs_unregister(qm);
+       hisi_qm_pci_uninit(qm);
+-      if (qm->use_sva) {
+-              uacce_remove(qm->uacce);
+-              qm->uacce = NULL;
+-      }
+ }
+ EXPORT_SYMBOL_GPL(hisi_qm_uninit);
+-- 
+2.43.0
+
diff --git a/queue-6.9/crypto-hisilicon-sec-fix-memory-leak-for-sec-resourc.patch b/queue-6.9/crypto-hisilicon-sec-fix-memory-leak-for-sec-resourc.patch
new file mode 100644 (file)
index 0000000..e8a64fd
--- /dev/null
@@ -0,0 +1,42 @@
+From c3a03d6f647b960c8c34d53d3382335b9376bde1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Apr 2024 15:59:58 +0800
+Subject: crypto: hisilicon/sec - Fix memory leak for sec resource release
+
+From: Chenghai Huang <huangchenghai2@huawei.com>
+
+[ Upstream commit bba4250757b4ae1680fea435a358d8093f254094 ]
+
+The AIV is one of the SEC resources. When releasing resources,
+it need to release the AIV resources at the same time.
+Otherwise, memory leakage occurs.
+
+The aiv resource release is added to the sec resource release
+function.
+
+Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/hisilicon/sec2/sec_crypto.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+index 93a972fcbf638..0558f98e221f6 100644
+--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c
++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+@@ -481,8 +481,10 @@ static void sec_alg_resource_free(struct sec_ctx *ctx,
+       if (ctx->pbuf_supported)
+               sec_free_pbuf_resource(dev, qp_ctx->res);
+-      if (ctx->alg_type == SEC_AEAD)
++      if (ctx->alg_type == SEC_AEAD) {
+               sec_free_mac_resource(dev, qp_ctx->res);
++              sec_free_aiv_resource(dev, qp_ctx->res);
++      }
+ }
+ static int sec_alloc_qp_ctx_resource(struct sec_ctx *ctx, struct sec_qp_ctx *qp_ctx)
+-- 
+2.43.0
+
diff --git a/queue-6.9/cxl-add-post-reset-warning-if-reset-results-in-loss-.patch b/queue-6.9/cxl-add-post-reset-warning-if-reset-results-in-loss-.patch
new file mode 100644 (file)
index 0000000..3bba8d2
--- /dev/null
@@ -0,0 +1,130 @@
+From c22893bb2a4154b6fa83ce584c6fae79dee7afbf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 May 2024 09:57:34 -0700
+Subject: cxl: Add post-reset warning if reset results in loss of previously
+ committed HDM decoders
+
+From: Dave Jiang <dave.jiang@intel.com>
+
+[ Upstream commit 934edcd436dca0447e0d3691a908394ba16d06c3 ]
+
+Secondary Bus Reset (SBR) is equivalent to a device being hot removed and
+inserted again. Doing a SBR on a CXL type 3 device is problematic if the
+exported device memory is part of system memory that cannot be offlined.
+The event is equivalent to violently ripping out that range of memory from
+the kernel. While the hardware requires the "Unmask SBR" bit set in the
+Port Control Extensions register and the kernel currently does not unmask
+it, user can unmask this bit via setpci or similar tool.
+
+The driver does not have a way to detect whether a reset coming from the
+PCI subsystem is a Function Level Reset (FLR) or SBR. The only way to
+detect is to note if a decoder is marked as enabled in software but the
+decoder control register indicates it's not committed.
+
+Add a helper function to find discrepancy between the decoder software
+state versus the hardware register state.
+
+Suggested-by: Dan Williams <dan.j.williams@intel.com>
+Link: https://lore.kernel.org/r/20240502165851.1948523-6-dave.jiang@intel.com
+Signed-off-by: Dave Jiang <dave.jiang@intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/core/pci.c | 29 +++++++++++++++++++++++++++++
+ drivers/cxl/cxl.h      |  2 ++
+ drivers/cxl/pci.c      | 22 ++++++++++++++++++++++
+ 3 files changed, 53 insertions(+)
+
+diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
+index 0df09bd794088..2773f05adb7d2 100644
+--- a/drivers/cxl/core/pci.c
++++ b/drivers/cxl/core/pci.c
+@@ -1045,3 +1045,32 @@ long cxl_pci_get_latency(struct pci_dev *pdev)
+       return cxl_flit_size(pdev) * MEGA / bw;
+ }
++
++static int __cxl_endpoint_decoder_reset_detected(struct device *dev, void *data)
++{
++      struct cxl_port *port = data;
++      struct cxl_decoder *cxld;
++      struct cxl_hdm *cxlhdm;
++      void __iomem *hdm;
++      u32 ctrl;
++
++      if (!is_endpoint_decoder(dev))
++              return 0;
++
++      cxld = to_cxl_decoder(dev);
++      if ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)
++              return 0;
++
++      cxlhdm = dev_get_drvdata(&port->dev);
++      hdm = cxlhdm->regs.hdm_decoder;
++      ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(cxld->id));
++
++      return !FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl);
++}
++
++bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port)
++{
++      return device_for_each_child(&port->dev, port,
++                                   __cxl_endpoint_decoder_reset_detected);
++}
++EXPORT_SYMBOL_NS_GPL(cxl_endpoint_decoder_reset_detected, CXL);
+diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
+index 036d17db68e00..72fa477407689 100644
+--- a/drivers/cxl/cxl.h
++++ b/drivers/cxl/cxl.h
+@@ -891,6 +891,8 @@ void cxl_coordinates_combine(struct access_coordinate *out,
+                            struct access_coordinate *c1,
+                            struct access_coordinate *c2);
++bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port);
++
+ /*
+  * Unit test builds overrides this to __weak, find the 'strong' version
+  * of these symbols in tools/testing/cxl/.
+diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
+index 2ff361e756d66..659f9d46b154c 100644
+--- a/drivers/cxl/pci.c
++++ b/drivers/cxl/pci.c
+@@ -957,11 +957,33 @@ static void cxl_error_resume(struct pci_dev *pdev)
+                dev->driver ? "successful" : "failed");
+ }
++static void cxl_reset_done(struct pci_dev *pdev)
++{
++      struct cxl_dev_state *cxlds = pci_get_drvdata(pdev);
++      struct cxl_memdev *cxlmd = cxlds->cxlmd;
++      struct device *dev = &pdev->dev;
++
++      /*
++       * FLR does not expect to touch the HDM decoders and related
++       * registers.  SBR, however, will wipe all device configurations.
++       * Issue a warning if there was an active decoder before the reset
++       * that no longer exists.
++       */
++      guard(device)(&cxlmd->dev);
++      if (cxlmd->endpoint &&
++          cxl_endpoint_decoder_reset_detected(cxlmd->endpoint)) {
++              dev_crit(dev, "SBR happened without memory regions removal.\n");
++              dev_crit(dev, "System may be unstable if regions hosted system memory.\n");
++              add_taint(TAINT_USER, LOCKDEP_STILL_OK);
++      }
++}
++
+ static const struct pci_error_handlers cxl_error_handlers = {
+       .error_detected = cxl_error_detected,
+       .slot_reset     = cxl_slot_reset,
+       .resume         = cxl_error_resume,
+       .cor_error_detected     = cxl_cor_error_detected,
++      .reset_done     = cxl_reset_done,
+ };
+ static struct pci_driver cxl_pci_driver = {
+-- 
+2.43.0
+
diff --git a/queue-6.9/devlink-use-kvzalloc-to-allocate-devlink-instance-re.patch b/queue-6.9/devlink-use-kvzalloc-to-allocate-devlink-instance-re.patch
new file mode 100644 (file)
index 0000000..538af04
--- /dev/null
@@ -0,0 +1,86 @@
+From c4415ce313c2ddf2a8ea8a84211e0d7e084fca0a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Mar 2024 16:21:28 +0800
+Subject: devlink: use kvzalloc() to allocate devlink instance resources
+
+From: Jian Wen <wenjianhn@gmail.com>
+
+[ Upstream commit 730fffce4fd2eb7a0be2d0b6cd7e55e9194d76d5 ]
+
+During live migration of a virtual machine, the SR-IOV VF need to be
+re-registered. It may fail when the memory is badly fragmented.
+
+The related log is as follows.
+
+    kernel: hv_netvsc 6045bdaa-c0d1-6045-bdaa-c0d16045bdaa eth0: VF slot 1 added
+...
+    kernel: kworker/0:0: page allocation failure: order:7, mode:0x40dc0(GFP_KERNEL|__GFP_COMP|__GFP_ZERO), nodemask=(null),cpuset=/,mems_allowed=0
+    kernel: CPU: 0 PID: 24006 Comm: kworker/0:0 Tainted: G            E     5.4...x86_64 #1
+    kernel: Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS 090008  12/07/2018
+    kernel: Workqueue: events work_for_cpu_fn
+    kernel: Call Trace:
+    kernel: dump_stack+0x8b/0xc8
+    kernel: warn_alloc+0xff/0x170
+    kernel: __alloc_pages_slowpath+0x92c/0xb2b
+    kernel: ? get_page_from_freelist+0x1d4/0x1140
+    kernel: __alloc_pages_nodemask+0x2f9/0x320
+    kernel: alloc_pages_current+0x6a/0xb0
+    kernel: kmalloc_order+0x1e/0x70
+    kernel: kmalloc_order_trace+0x26/0xb0
+    kernel: ? __switch_to_asm+0x34/0x70
+    kernel: __kmalloc+0x276/0x280
+    kernel: ? _raw_spin_unlock_irqrestore+0x1e/0x40
+    kernel: devlink_alloc+0x29/0x110
+    kernel: mlx5_devlink_alloc+0x1a/0x20 [mlx5_core]
+    kernel: init_one+0x1d/0x650 [mlx5_core]
+    kernel: local_pci_probe+0x46/0x90
+    kernel: work_for_cpu_fn+0x1a/0x30
+    kernel: process_one_work+0x16d/0x390
+    kernel: worker_thread+0x1d3/0x3f0
+    kernel: kthread+0x105/0x140
+    kernel: ? max_active_store+0x80/0x80
+    kernel: ? kthread_bind+0x20/0x20
+    kernel: ret_from_fork+0x3a/0x50
+
+Signed-off-by: Jian Wen <wenjian1@xiaomi.com>
+Link: https://lore.kernel.org/r/20240327082128.942818-1-wenjian1@xiaomi.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/devlink/core.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/devlink/core.c b/net/devlink/core.c
+index 7f0b093208d75..f49cd83f1955f 100644
+--- a/net/devlink/core.c
++++ b/net/devlink/core.c
+@@ -314,7 +314,7 @@ static void devlink_release(struct work_struct *work)
+       mutex_destroy(&devlink->lock);
+       lockdep_unregister_key(&devlink->lock_key);
+       put_device(devlink->dev);
+-      kfree(devlink);
++      kvfree(devlink);
+ }
+ void devlink_put(struct devlink *devlink)
+@@ -420,7 +420,7 @@ struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
+       if (!devlink_reload_actions_valid(ops))
+               return NULL;
+-      devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
++      devlink = kvzalloc(struct_size(devlink, priv, priv_size), GFP_KERNEL);
+       if (!devlink)
+               return NULL;
+@@ -455,7 +455,7 @@ struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
+       return devlink;
+ err_xa_alloc:
+-      kfree(devlink);
++      kvfree(devlink);
+       return NULL;
+ }
+ EXPORT_SYMBOL_GPL(devlink_alloc_ns);
+-- 
+2.43.0
+
diff --git a/queue-6.9/drm-amd-display-exit-idle-optimizations-before-hdcp-.patch b/queue-6.9/drm-amd-display-exit-idle-optimizations-before-hdcp-.patch
new file mode 100644 (file)
index 0000000..747de8a
--- /dev/null
@@ -0,0 +1,88 @@
+From 5ba8662aea142c261e8d93287f9c7be18adae5da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Feb 2024 16:51:59 -0500
+Subject: drm/amd/display: Exit idle optimizations before HDCP execution
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+[ Upstream commit f30a3bea92bdab398531129d187629fb1d28f598 ]
+
+[WHY]
+PSP can access DCN registers during command submission and we need
+to ensure that DCN is not in PG before doing so.
+
+[HOW]
+Add a callback to DM to lock and notify DC for idle optimization exit.
+It can't be DC directly because of a potential race condition with the
+link protection thread and the rest of DM operation.
+
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Charlene Liu <charlene.liu@amd.com>
+Acked-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c    | 10 ++++++++++
+ drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h |  8 ++++++++
+ 2 files changed, 18 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c
+index 5e01c6e24cbc8..9a5a1726acaf8 100644
+--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c
++++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c
+@@ -88,6 +88,14 @@ static uint8_t is_cp_desired_hdcp2(struct mod_hdcp *hdcp)
+                       !hdcp->connection.is_hdcp2_revoked;
+ }
++static void exit_idle_optimizations(struct mod_hdcp *hdcp)
++{
++      struct mod_hdcp_dm *dm = &hdcp->config.dm;
++
++      if (dm->funcs.exit_idle_optimizations)
++              dm->funcs.exit_idle_optimizations(dm->handle);
++}
++
+ static enum mod_hdcp_status execution(struct mod_hdcp *hdcp,
+               struct mod_hdcp_event_context *event_ctx,
+               union mod_hdcp_transition_input *input)
+@@ -543,6 +551,8 @@ enum mod_hdcp_status mod_hdcp_process_event(struct mod_hdcp *hdcp,
+       memset(&event_ctx, 0, sizeof(struct mod_hdcp_event_context));
+       event_ctx.event = event;
++      exit_idle_optimizations(hdcp);
++
+       /* execute and transition */
+       exec_status = execution(hdcp, &event_ctx, &hdcp->auth.trans_input);
+       trans_status = transition(
+diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h b/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h
+index a4d344a4db9e1..cdb17b093f2b8 100644
+--- a/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h
++++ b/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h
+@@ -156,6 +156,13 @@ struct mod_hdcp_ddc {
+       } funcs;
+ };
++struct mod_hdcp_dm {
++      void *handle;
++      struct {
++              void (*exit_idle_optimizations)(void *handle);
++      } funcs;
++};
++
+ struct mod_hdcp_psp {
+       void *handle;
+       void *funcs;
+@@ -272,6 +279,7 @@ struct mod_hdcp_display_query {
+ struct mod_hdcp_config {
+       struct mod_hdcp_psp psp;
+       struct mod_hdcp_ddc ddc;
++      struct mod_hdcp_dm dm;
+       uint8_t index;
+ };
+-- 
+2.43.0
+
diff --git a/queue-6.9/drm-amd-display-workaround-register-access-in-idle-r.patch b/queue-6.9/drm-amd-display-workaround-register-access-in-idle-r.patch
new file mode 100644 (file)
index 0000000..75b2346
--- /dev/null
@@ -0,0 +1,84 @@
+From 583d21803548c89b0a0d74caa69b38a644a24dd2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Feb 2024 16:52:40 -0500
+Subject: drm/amd/display: Workaround register access in idle race with cursor
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+[ Upstream commit b5b6d6251579a29dafdad25f4bc7f3ff7bfd2c86 ]
+
+[Why]
+Cursor update can be pre-empted by a request for setting target flip
+submission.
+
+This causes an issue where we're in the middle of the exit sequence
+trying to log to DM, but the pre-emption starts another DMCUB
+command submission that requires being out of idle.
+
+The DC lock aqusition can fail, and depending on the DM/OS interface
+it's possible that the function inserted into this thread must not fail.
+
+This means that lock aqusition must be skipped and exit *must* occur.
+
+[How]
+Modify when we consider idle as active. Consider it exited only once
+the exit has fully finished.
+
+Consider it as entered prior to actual notification.
+
+Since we're on the same core/thread the cached values are coherent
+and we'll see that we still need to exit. Once the cursor update resumes
+it'll continue doing the double exit but this won't cause a functional
+issue, just a (potential) redundant operation.
+
+Reviewed-by: Duncan Ma <duncan.ma@amd.com>
+Acked-by: Wayne Lin <wayne.lin@amd.com>
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 23 +++++++++++++++-----
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+index 6083b1dcf050a..a72e849eced3f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
++++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+@@ -1340,16 +1340,27 @@ void dc_dmub_srv_apply_idle_power_optimizations(const struct dc *dc, bool allow_
+        * Powering up the hardware requires notifying PMFW and DMCUB.
+        * Clearing the driver idle allow requires a DMCUB command.
+        * DMCUB commands requires the DMCUB to be powered up and restored.
+-       *
+-       * Exit out early to prevent an infinite loop of DMCUB commands
+-       * triggering exit low power - use software state to track this.
+        */
+-      dc_dmub_srv->idle_allowed = allow_idle;
+-      if (!allow_idle)
++      if (!allow_idle) {
+               dc_dmub_srv_exit_low_power_state(dc);
+-      else
++              /*
++               * Idle is considered fully exited only after the sequence above
++               * fully completes. If we have a race of two threads exiting
++               * at the same time then it's safe to perform the sequence
++               * twice as long as we're not re-entering.
++               *
++               * Infinite command submission is avoided by using the
++               * dm_execute_dmub_cmd submission instead of the "wake" helpers.
++               */
++              dc_dmub_srv->idle_allowed = false;
++      } else {
++              /* Consider idle as notified prior to the actual submission to
++               * prevent multiple entries. */
++              dc_dmub_srv->idle_allowed = true;
++
+               dc_dmub_srv_notify_idle(dc, allow_idle);
++      }
+ }
+ bool dc_wake_and_execute_dmub_cmd(const struct dc_context *ctx, union dmub_rb_cmd *cmd,
+-- 
+2.43.0
+
diff --git a/queue-6.9/drm-lima-add-mask-irq-callback-to-gp-and-pp.patch b/queue-6.9/drm-lima-add-mask-irq-callback-to-gp-and-pp.patch
new file mode 100644 (file)
index 0000000..a909f00
--- /dev/null
@@ -0,0 +1,145 @@
+From 11fe8f45ad1a51d7c946df515f65e28fdb0014f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Apr 2024 17:29:49 +0200
+Subject: drm/lima: add mask irq callback to gp and pp
+
+From: Erico Nunes <nunes.erico@gmail.com>
+
+[ Upstream commit 49c13b4d2dd4a831225746e758893673f6ae961c ]
+
+This is needed because we want to reset those devices in device-agnostic
+code such as lima_sched.
+In particular, masking irqs will be useful before a hard reset to
+prevent race conditions.
+
+Signed-off-by: Erico Nunes <nunes.erico@gmail.com>
+Signed-off-by: Qiang Yu <yuq825@gmail.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240405152951.1531555-2-nunes.erico@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/lima/lima_bcast.c | 12 ++++++++++++
+ drivers/gpu/drm/lima/lima_bcast.h |  3 +++
+ drivers/gpu/drm/lima/lima_gp.c    |  8 ++++++++
+ drivers/gpu/drm/lima/lima_pp.c    | 18 ++++++++++++++++++
+ drivers/gpu/drm/lima/lima_sched.h |  1 +
+ 5 files changed, 42 insertions(+)
+
+diff --git a/drivers/gpu/drm/lima/lima_bcast.c b/drivers/gpu/drm/lima/lima_bcast.c
+index fbc43f243c54d..6d000504e1a4e 100644
+--- a/drivers/gpu/drm/lima/lima_bcast.c
++++ b/drivers/gpu/drm/lima/lima_bcast.c
+@@ -43,6 +43,18 @@ void lima_bcast_suspend(struct lima_ip *ip)
+ }
++int lima_bcast_mask_irq(struct lima_ip *ip)
++{
++      bcast_write(LIMA_BCAST_BROADCAST_MASK, 0);
++      bcast_write(LIMA_BCAST_INTERRUPT_MASK, 0);
++      return 0;
++}
++
++int lima_bcast_reset(struct lima_ip *ip)
++{
++      return lima_bcast_hw_init(ip);
++}
++
+ int lima_bcast_init(struct lima_ip *ip)
+ {
+       int i;
+diff --git a/drivers/gpu/drm/lima/lima_bcast.h b/drivers/gpu/drm/lima/lima_bcast.h
+index 465ee587bceb2..cd08841e47879 100644
+--- a/drivers/gpu/drm/lima/lima_bcast.h
++++ b/drivers/gpu/drm/lima/lima_bcast.h
+@@ -13,4 +13,7 @@ void lima_bcast_fini(struct lima_ip *ip);
+ void lima_bcast_enable(struct lima_device *dev, int num_pp);
++int lima_bcast_mask_irq(struct lima_ip *ip);
++int lima_bcast_reset(struct lima_ip *ip);
++
+ #endif
+diff --git a/drivers/gpu/drm/lima/lima_gp.c b/drivers/gpu/drm/lima/lima_gp.c
+index 6b354e2fb61d4..e15295071533b 100644
+--- a/drivers/gpu/drm/lima/lima_gp.c
++++ b/drivers/gpu/drm/lima/lima_gp.c
+@@ -233,6 +233,13 @@ static void lima_gp_task_mmu_error(struct lima_sched_pipe *pipe)
+       lima_sched_pipe_task_done(pipe);
+ }
++static void lima_gp_task_mask_irq(struct lima_sched_pipe *pipe)
++{
++      struct lima_ip *ip = pipe->processor[0];
++
++      gp_write(LIMA_GP_INT_MASK, 0);
++}
++
+ static int lima_gp_task_recover(struct lima_sched_pipe *pipe)
+ {
+       struct lima_ip *ip = pipe->processor[0];
+@@ -365,6 +372,7 @@ int lima_gp_pipe_init(struct lima_device *dev)
+       pipe->task_error = lima_gp_task_error;
+       pipe->task_mmu_error = lima_gp_task_mmu_error;
+       pipe->task_recover = lima_gp_task_recover;
++      pipe->task_mask_irq = lima_gp_task_mask_irq;
+       return 0;
+ }
+diff --git a/drivers/gpu/drm/lima/lima_pp.c b/drivers/gpu/drm/lima/lima_pp.c
+index d0d2db0ef1ce8..a4a2ffe6527c2 100644
+--- a/drivers/gpu/drm/lima/lima_pp.c
++++ b/drivers/gpu/drm/lima/lima_pp.c
+@@ -429,6 +429,9 @@ static void lima_pp_task_error(struct lima_sched_pipe *pipe)
+               lima_pp_hard_reset(ip);
+       }
++
++      if (pipe->bcast_processor)
++              lima_bcast_reset(pipe->bcast_processor);
+ }
+ static void lima_pp_task_mmu_error(struct lima_sched_pipe *pipe)
+@@ -437,6 +440,20 @@ static void lima_pp_task_mmu_error(struct lima_sched_pipe *pipe)
+               lima_sched_pipe_task_done(pipe);
+ }
++static void lima_pp_task_mask_irq(struct lima_sched_pipe *pipe)
++{
++      int i;
++
++      for (i = 0; i < pipe->num_processor; i++) {
++              struct lima_ip *ip = pipe->processor[i];
++
++              pp_write(LIMA_PP_INT_MASK, 0);
++      }
++
++      if (pipe->bcast_processor)
++              lima_bcast_mask_irq(pipe->bcast_processor);
++}
++
+ static struct kmem_cache *lima_pp_task_slab;
+ static int lima_pp_task_slab_refcnt;
+@@ -468,6 +485,7 @@ int lima_pp_pipe_init(struct lima_device *dev)
+       pipe->task_fini = lima_pp_task_fini;
+       pipe->task_error = lima_pp_task_error;
+       pipe->task_mmu_error = lima_pp_task_mmu_error;
++      pipe->task_mask_irq = lima_pp_task_mask_irq;
+       return 0;
+ }
+diff --git a/drivers/gpu/drm/lima/lima_sched.h b/drivers/gpu/drm/lima/lima_sched.h
+index 6bd4f3b701091..85b23ba901d53 100644
+--- a/drivers/gpu/drm/lima/lima_sched.h
++++ b/drivers/gpu/drm/lima/lima_sched.h
+@@ -80,6 +80,7 @@ struct lima_sched_pipe {
+       void (*task_error)(struct lima_sched_pipe *pipe);
+       void (*task_mmu_error)(struct lima_sched_pipe *pipe);
+       int (*task_recover)(struct lima_sched_pipe *pipe);
++      void (*task_mask_irq)(struct lima_sched_pipe *pipe);
+       struct work_struct recover_work;
+ };
+-- 
+2.43.0
+
diff --git a/queue-6.9/drm-lima-include-pp-bcast-irq-in-timeout-handler-che.patch b/queue-6.9/drm-lima-include-pp-bcast-irq-in-timeout-handler-che.patch
new file mode 100644 (file)
index 0000000..39a7543
--- /dev/null
@@ -0,0 +1,40 @@
+From a1d9bfe2adc180678aacd1c7a985590101c63f67 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Apr 2024 17:29:50 +0200
+Subject: drm/lima: include pp bcast irq in timeout handler check
+
+From: Erico Nunes <nunes.erico@gmail.com>
+
+[ Upstream commit d8100caf40a35904d27ce446fb2088b54277997a ]
+
+In commit 53cb55b20208 ("drm/lima: handle spurious timeouts due to high
+irq latency") a check was added to detect an unexpectedly high interrupt
+latency timeout.
+With further investigation it was noted that on Mali-450 the pp bcast
+irq may also be a trigger of race conditions against the timeout
+handler, so add it to this check too.
+
+Signed-off-by: Erico Nunes <nunes.erico@gmail.com>
+Signed-off-by: Qiang Yu <yuq825@gmail.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240405152951.1531555-3-nunes.erico@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/lima/lima_sched.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c
+index 00b19adfc8881..66841503a6183 100644
+--- a/drivers/gpu/drm/lima/lima_sched.c
++++ b/drivers/gpu/drm/lima/lima_sched.c
+@@ -422,6 +422,8 @@ static enum drm_gpu_sched_stat lima_sched_timedout_job(struct drm_sched_job *job
+        */
+       for (i = 0; i < pipe->num_processor; i++)
+               synchronize_irq(pipe->processor[i]->irq);
++      if (pipe->bcast_processor)
++              synchronize_irq(pipe->bcast_processor->irq);
+       if (dma_fence_is_signaled(task->fence)) {
+               DRM_WARN("%s unexpectedly high interrupt latency\n", lima_ip_name(ip));
+-- 
+2.43.0
+
diff --git a/queue-6.9/drm-lima-mask-irqs-in-timeout-path-before-hard-reset.patch b/queue-6.9/drm-lima-mask-irqs-in-timeout-path-before-hard-reset.patch
new file mode 100644 (file)
index 0000000..986fc85
--- /dev/null
@@ -0,0 +1,63 @@
+From b4ad08ed3d1a679f5cf8b27e0743e3fa7ef3a1cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Apr 2024 17:29:51 +0200
+Subject: drm/lima: mask irqs in timeout path before hard reset
+
+From: Erico Nunes <nunes.erico@gmail.com>
+
+[ Upstream commit a421cc7a6a001b70415aa4f66024fa6178885a14 ]
+
+There is a race condition in which a rendering job might take just long
+enough to trigger the drm sched job timeout handler but also still
+complete before the hard reset is done by the timeout handler.
+This runs into race conditions not expected by the timeout handler.
+In some very specific cases it currently may result in a refcount
+imbalance on lima_pm_idle, with a stack dump such as:
+
+[10136.669170] WARNING: CPU: 0 PID: 0 at drivers/gpu/drm/lima/lima_devfreq.c:205 lima_devfreq_record_idle+0xa0/0xb0
+...
+[10136.669459] pc : lima_devfreq_record_idle+0xa0/0xb0
+...
+[10136.669628] Call trace:
+[10136.669634]  lima_devfreq_record_idle+0xa0/0xb0
+[10136.669646]  lima_sched_pipe_task_done+0x5c/0xb0
+[10136.669656]  lima_gp_irq_handler+0xa8/0x120
+[10136.669666]  __handle_irq_event_percpu+0x48/0x160
+[10136.669679]  handle_irq_event+0x4c/0xc0
+
+We can prevent that race condition entirely by masking the irqs at the
+beginning of the timeout handler, at which point we give up on waiting
+for that job entirely.
+The irqs will be enabled again at the next hard reset which is already
+done as a recovery by the timeout handler.
+
+Signed-off-by: Erico Nunes <nunes.erico@gmail.com>
+Reviewed-by: Qiang Yu <yuq825@gmail.com>
+Signed-off-by: Qiang Yu <yuq825@gmail.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240405152951.1531555-4-nunes.erico@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/lima/lima_sched.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c
+index 66841503a6183..bbf3f8feab944 100644
+--- a/drivers/gpu/drm/lima/lima_sched.c
++++ b/drivers/gpu/drm/lima/lima_sched.c
+@@ -430,6 +430,13 @@ static enum drm_gpu_sched_stat lima_sched_timedout_job(struct drm_sched_job *job
+               return DRM_GPU_SCHED_STAT_NOMINAL;
+       }
++      /*
++       * The task might still finish while this timeout handler runs.
++       * To prevent a race condition on its completion, mask all irqs
++       * on the running core until the next hard reset completes.
++       */
++      pipe->task_mask_irq(pipe);
++
+       if (!pipe->error)
+               DRM_ERROR("%s job timeout\n", lima_ip_name(ip));
+-- 
+2.43.0
+
diff --git a/queue-6.9/drop_monitor-replace-spin_lock-by-raw_spin_lock.patch b/queue-6.9/drop_monitor-replace-spin_lock-by-raw_spin_lock.patch
new file mode 100644 (file)
index 0000000..5a1d36b
--- /dev/null
@@ -0,0 +1,155 @@
+From 0bf1bac942a8f6eff7e2192d87461cbb7ca66d38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Apr 2024 11:13:46 -0300
+Subject: drop_monitor: replace spin_lock by raw_spin_lock
+
+From: Wander Lairson Costa <wander@redhat.com>
+
+[ Upstream commit f1e197a665c2148ebc25fe09c53689e60afea195 ]
+
+trace_drop_common() is called with preemption disabled, and it acquires
+a spin_lock. This is problematic for RT kernels because spin_locks are
+sleeping locks in this configuration, which causes the following splat:
+
+BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48
+in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 449, name: rcuc/47
+preempt_count: 1, expected: 0
+RCU nest depth: 2, expected: 2
+5 locks held by rcuc/47/449:
+ #0: ff1100086ec30a60 ((softirq_ctrl.lock)){+.+.}-{2:2}, at: __local_bh_disable_ip+0x105/0x210
+ #1: ffffffffb394a280 (rcu_read_lock){....}-{1:2}, at: rt_spin_lock+0xbf/0x130
+ #2: ffffffffb394a280 (rcu_read_lock){....}-{1:2}, at: __local_bh_disable_ip+0x11c/0x210
+ #3: ffffffffb394a160 (rcu_callback){....}-{0:0}, at: rcu_do_batch+0x360/0xc70
+ #4: ff1100086ee07520 (&data->lock){+.+.}-{2:2}, at: trace_drop_common.constprop.0+0xb5/0x290
+irq event stamp: 139909
+hardirqs last  enabled at (139908): [<ffffffffb1df2b33>] _raw_spin_unlock_irqrestore+0x63/0x80
+hardirqs last disabled at (139909): [<ffffffffb19bd03d>] trace_drop_common.constprop.0+0x26d/0x290
+softirqs last  enabled at (139892): [<ffffffffb07a1083>] __local_bh_enable_ip+0x103/0x170
+softirqs last disabled at (139898): [<ffffffffb0909b33>] rcu_cpu_kthread+0x93/0x1f0
+Preemption disabled at:
+[<ffffffffb1de786b>] rt_mutex_slowunlock+0xab/0x2e0
+CPU: 47 PID: 449 Comm: rcuc/47 Not tainted 6.9.0-rc2-rt1+ #7
+Hardware name: Dell Inc. PowerEdge R650/0Y2G81, BIOS 1.6.5 04/15/2022
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x8c/0xd0
+ dump_stack+0x14/0x20
+ __might_resched+0x21e/0x2f0
+ rt_spin_lock+0x5e/0x130
+ ? trace_drop_common.constprop.0+0xb5/0x290
+ ? skb_queue_purge_reason.part.0+0x1bf/0x230
+ trace_drop_common.constprop.0+0xb5/0x290
+ ? preempt_count_sub+0x1c/0xd0
+ ? _raw_spin_unlock_irqrestore+0x4a/0x80
+ ? __pfx_trace_drop_common.constprop.0+0x10/0x10
+ ? rt_mutex_slowunlock+0x26a/0x2e0
+ ? skb_queue_purge_reason.part.0+0x1bf/0x230
+ ? __pfx_rt_mutex_slowunlock+0x10/0x10
+ ? skb_queue_purge_reason.part.0+0x1bf/0x230
+ trace_kfree_skb_hit+0x15/0x20
+ trace_kfree_skb+0xe9/0x150
+ kfree_skb_reason+0x7b/0x110
+ skb_queue_purge_reason.part.0+0x1bf/0x230
+ ? __pfx_skb_queue_purge_reason.part.0+0x10/0x10
+ ? mark_lock.part.0+0x8a/0x520
+...
+
+trace_drop_common() also disables interrupts, but this is a minor issue
+because we could easily replace it with a local_lock.
+
+Replace the spin_lock with raw_spin_lock to avoid sleeping in atomic
+context.
+
+Signed-off-by: Wander Lairson Costa <wander@redhat.com>
+Reported-by: Hu Chunyu <chuhu@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/drop_monitor.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
+index b0f221d658be8..430ed18f8584c 100644
+--- a/net/core/drop_monitor.c
++++ b/net/core/drop_monitor.c
+@@ -74,7 +74,7 @@ struct net_dm_hw_entries {
+ };
+ struct per_cpu_dm_data {
+-      spinlock_t              lock;   /* Protects 'skb', 'hw_entries' and
++      raw_spinlock_t          lock;   /* Protects 'skb', 'hw_entries' and
+                                        * 'send_timer'
+                                        */
+       union {
+@@ -168,9 +168,9 @@ static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data)
+ err:
+       mod_timer(&data->send_timer, jiffies + HZ / 10);
+ out:
+-      spin_lock_irqsave(&data->lock, flags);
++      raw_spin_lock_irqsave(&data->lock, flags);
+       swap(data->skb, skb);
+-      spin_unlock_irqrestore(&data->lock, flags);
++      raw_spin_unlock_irqrestore(&data->lock, flags);
+       if (skb) {
+               struct nlmsghdr *nlh = (struct nlmsghdr *)skb->data;
+@@ -225,7 +225,7 @@ static void trace_drop_common(struct sk_buff *skb, void *location)
+       local_irq_save(flags);
+       data = this_cpu_ptr(&dm_cpu_data);
+-      spin_lock(&data->lock);
++      raw_spin_lock(&data->lock);
+       dskb = data->skb;
+       if (!dskb)
+@@ -259,7 +259,7 @@ static void trace_drop_common(struct sk_buff *skb, void *location)
+       }
+ out:
+-      spin_unlock_irqrestore(&data->lock, flags);
++      raw_spin_unlock_irqrestore(&data->lock, flags);
+ }
+ static void trace_kfree_skb_hit(void *ignore, struct sk_buff *skb,
+@@ -314,9 +314,9 @@ net_dm_hw_reset_per_cpu_data(struct per_cpu_dm_data *hw_data)
+               mod_timer(&hw_data->send_timer, jiffies + HZ / 10);
+       }
+-      spin_lock_irqsave(&hw_data->lock, flags);
++      raw_spin_lock_irqsave(&hw_data->lock, flags);
+       swap(hw_data->hw_entries, hw_entries);
+-      spin_unlock_irqrestore(&hw_data->lock, flags);
++      raw_spin_unlock_irqrestore(&hw_data->lock, flags);
+       return hw_entries;
+ }
+@@ -448,7 +448,7 @@ net_dm_hw_trap_summary_probe(void *ignore, const struct devlink *devlink,
+               return;
+       hw_data = this_cpu_ptr(&dm_hw_cpu_data);
+-      spin_lock_irqsave(&hw_data->lock, flags);
++      raw_spin_lock_irqsave(&hw_data->lock, flags);
+       hw_entries = hw_data->hw_entries;
+       if (!hw_entries)
+@@ -477,7 +477,7 @@ net_dm_hw_trap_summary_probe(void *ignore, const struct devlink *devlink,
+       }
+ out:
+-      spin_unlock_irqrestore(&hw_data->lock, flags);
++      raw_spin_unlock_irqrestore(&hw_data->lock, flags);
+ }
+ static const struct net_dm_alert_ops net_dm_alert_summary_ops = {
+@@ -1673,7 +1673,7 @@ static struct notifier_block dropmon_net_notifier = {
+ static void __net_dm_cpu_data_init(struct per_cpu_dm_data *data)
+ {
+-      spin_lock_init(&data->lock);
++      raw_spin_lock_init(&data->lock);
+       skb_queue_head_init(&data->drop_queue);
+       u64_stats_init(&data->stats.syncp);
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.9/ext4-do-not-create-ea-inode-under-buffer-lock.patch b/queue-6.9/ext4-do-not-create-ea-inode-under-buffer-lock.patch
new file mode 100644 (file)
index 0000000..9113513
--- /dev/null
@@ -0,0 +1,242 @@
+From beae47de49acaf691da5d3fc2804c82e66bbb411 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Mar 2024 17:26:50 +0100
+Subject: ext4: do not create EA inode under buffer lock
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 0a46ef234756dca04623b7591e8ebb3440622f0b ]
+
+ext4_xattr_set_entry() creates new EA inodes while holding buffer lock
+on the external xattr block. This is problematic as it nests all the
+allocation locking (which acquires locks on other buffers) under the
+buffer lock. This can even deadlock when the filesystem is corrupted and
+e.g. quota file is setup to contain xattr block as data block. Move the
+allocation of EA inode out of ext4_xattr_set_entry() into the callers.
+
+Reported-by: syzbot+a43d4f48b8397d0e41a9@syzkaller.appspotmail.com
+Signed-off-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20240321162657.27420-2-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/xattr.c | 113 +++++++++++++++++++++++-------------------------
+ 1 file changed, 53 insertions(+), 60 deletions(-)
+
+diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+index 9fdd134220736..78f06f86c3835 100644
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -1619,6 +1619,7 @@ static struct inode *ext4_xattr_inode_lookup_create(handle_t *handle,
+ static int ext4_xattr_set_entry(struct ext4_xattr_info *i,
+                               struct ext4_xattr_search *s,
+                               handle_t *handle, struct inode *inode,
++                              struct inode *new_ea_inode,
+                               bool is_block)
+ {
+       struct ext4_xattr_entry *last, *next;
+@@ -1626,7 +1627,6 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i,
+       size_t min_offs = s->end - s->base, name_len = strlen(i->name);
+       int in_inode = i->in_inode;
+       struct inode *old_ea_inode = NULL;
+-      struct inode *new_ea_inode = NULL;
+       size_t old_size, new_size;
+       int ret;
+@@ -1711,38 +1711,11 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i,
+                       old_ea_inode = NULL;
+                       goto out;
+               }
+-      }
+-      if (i->value && in_inode) {
+-              WARN_ON_ONCE(!i->value_len);
+-
+-              new_ea_inode = ext4_xattr_inode_lookup_create(handle, inode,
+-                                      i->value, i->value_len);
+-              if (IS_ERR(new_ea_inode)) {
+-                      ret = PTR_ERR(new_ea_inode);
+-                      new_ea_inode = NULL;
+-                      goto out;
+-              }
+-      }
+-      if (old_ea_inode) {
+               /* We are ready to release ref count on the old_ea_inode. */
+               ret = ext4_xattr_inode_dec_ref(handle, old_ea_inode);
+-              if (ret) {
+-                      /* Release newly required ref count on new_ea_inode. */
+-                      if (new_ea_inode) {
+-                              int err;
+-
+-                              err = ext4_xattr_inode_dec_ref(handle,
+-                                                             new_ea_inode);
+-                              if (err)
+-                                      ext4_warning_inode(new_ea_inode,
+-                                                "dec ref new_ea_inode err=%d",
+-                                                err);
+-                              ext4_xattr_inode_free_quota(inode, new_ea_inode,
+-                                                          i->value_len);
+-                      }
++              if (ret)
+                       goto out;
+-              }
+               ext4_xattr_inode_free_quota(inode, old_ea_inode,
+                                           le32_to_cpu(here->e_value_size));
+@@ -1866,7 +1839,6 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i,
+       ret = 0;
+ out:
+       iput(old_ea_inode);
+-      iput(new_ea_inode);
+       return ret;
+ }
+@@ -1929,9 +1901,21 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
+       size_t old_ea_inode_quota = 0;
+       unsigned int ea_ino;
+-
+ #define header(x) ((struct ext4_xattr_header *)(x))
++      /* If we need EA inode, prepare it before locking the buffer */
++      if (i->value && i->in_inode) {
++              WARN_ON_ONCE(!i->value_len);
++
++              ea_inode = ext4_xattr_inode_lookup_create(handle, inode,
++                                      i->value, i->value_len);
++              if (IS_ERR(ea_inode)) {
++                      error = PTR_ERR(ea_inode);
++                      ea_inode = NULL;
++                      goto cleanup;
++              }
++      }
++
+       if (s->base) {
+               int offset = (char *)s->here - bs->bh->b_data;
+@@ -1940,6 +1924,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
+                                                     EXT4_JTR_NONE);
+               if (error)
+                       goto cleanup;
++
+               lock_buffer(bs->bh);
+               if (header(s->base)->h_refcount == cpu_to_le32(1)) {
+@@ -1966,7 +1951,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
+                       }
+                       ea_bdebug(bs->bh, "modifying in-place");
+                       error = ext4_xattr_set_entry(i, s, handle, inode,
+-                                                   true /* is_block */);
++                                           ea_inode, true /* is_block */);
+                       ext4_xattr_block_csum_set(inode, bs->bh);
+                       unlock_buffer(bs->bh);
+                       if (error == -EFSCORRUPTED)
+@@ -2034,29 +2019,13 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
+               s->end = s->base + sb->s_blocksize;
+       }
+-      error = ext4_xattr_set_entry(i, s, handle, inode, true /* is_block */);
++      error = ext4_xattr_set_entry(i, s, handle, inode, ea_inode,
++                                   true /* is_block */);
+       if (error == -EFSCORRUPTED)
+               goto bad_block;
+       if (error)
+               goto cleanup;
+-      if (i->value && s->here->e_value_inum) {
+-              /*
+-               * A ref count on ea_inode has been taken as part of the call to
+-               * ext4_xattr_set_entry() above. We would like to drop this
+-               * extra ref but we have to wait until the xattr block is
+-               * initialized and has its own ref count on the ea_inode.
+-               */
+-              ea_ino = le32_to_cpu(s->here->e_value_inum);
+-              error = ext4_xattr_inode_iget(inode, ea_ino,
+-                                            le32_to_cpu(s->here->e_hash),
+-                                            &ea_inode);
+-              if (error) {
+-                      ea_inode = NULL;
+-                      goto cleanup;
+-              }
+-      }
+-
+ inserted:
+       if (!IS_LAST_ENTRY(s->first)) {
+               new_bh = ext4_xattr_block_cache_find(inode, header(s->base),
+@@ -2198,17 +2167,16 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
+ cleanup:
+       if (ea_inode) {
+-              int error2;
+-
+-              error2 = ext4_xattr_inode_dec_ref(handle, ea_inode);
+-              if (error2)
+-                      ext4_warning_inode(ea_inode, "dec ref error=%d",
+-                                         error2);
++              if (error) {
++                      int error2;
+-              /* If there was an error, revert the quota charge. */
+-              if (error)
++                      error2 = ext4_xattr_inode_dec_ref(handle, ea_inode);
++                      if (error2)
++                              ext4_warning_inode(ea_inode, "dec ref error=%d",
++                                                 error2);
+                       ext4_xattr_inode_free_quota(inode, ea_inode,
+                                                   i_size_read(ea_inode));
++              }
+               iput(ea_inode);
+       }
+       if (ce)
+@@ -2266,14 +2234,38 @@ int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
+ {
+       struct ext4_xattr_ibody_header *header;
+       struct ext4_xattr_search *s = &is->s;
++      struct inode *ea_inode = NULL;
+       int error;
+       if (!EXT4_INODE_HAS_XATTR_SPACE(inode))
+               return -ENOSPC;
+-      error = ext4_xattr_set_entry(i, s, handle, inode, false /* is_block */);
+-      if (error)
++      /* If we need EA inode, prepare it before locking the buffer */
++      if (i->value && i->in_inode) {
++              WARN_ON_ONCE(!i->value_len);
++
++              ea_inode = ext4_xattr_inode_lookup_create(handle, inode,
++                                      i->value, i->value_len);
++              if (IS_ERR(ea_inode))
++                      return PTR_ERR(ea_inode);
++      }
++      error = ext4_xattr_set_entry(i, s, handle, inode, ea_inode,
++                                   false /* is_block */);
++      if (error) {
++              if (ea_inode) {
++                      int error2;
++
++                      error2 = ext4_xattr_inode_dec_ref(handle, ea_inode);
++                      if (error2)
++                              ext4_warning_inode(ea_inode, "dec ref error=%d",
++                                                 error2);
++
++                      ext4_xattr_inode_free_quota(inode, ea_inode,
++                                                  i_size_read(ea_inode));
++                      iput(ea_inode);
++              }
+               return error;
++      }
+       header = IHDR(inode, ext4_raw_inode(&is->iloc));
+       if (!IS_LAST_ENTRY(s->first)) {
+               header->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC);
+@@ -2282,6 +2274,7 @@ int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
+               header->h_magic = cpu_to_le32(0);
+               ext4_clear_inode_state(inode, EXT4_STATE_XATTR);
+       }
++      iput(ea_inode);
+       return 0;
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.9/ext4-fix-uninitialized-ratelimit_state-lock-access-i.patch b/queue-6.9/ext4-fix-uninitialized-ratelimit_state-lock-access-i.patch
new file mode 100644 (file)
index 0000000..044310f
--- /dev/null
@@ -0,0 +1,139 @@
+From 88701995e373ff9b570b229a1fc7d16b8e1ef943 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jan 2024 21:37:30 +0800
+Subject: ext4: fix uninitialized ratelimit_state->lock access in
+ __ext4_fill_super()
+
+From: Baokun Li <libaokun1@huawei.com>
+
+[ Upstream commit b4b4fda34e535756f9e774fb2d09c4537b7dfd1c ]
+
+In the following concurrency we will access the uninitialized rs->lock:
+
+ext4_fill_super
+  ext4_register_sysfs
+   // sysfs registered msg_ratelimit_interval_ms
+                             // Other processes modify rs->interval to
+                             // non-zero via msg_ratelimit_interval_ms
+  ext4_orphan_cleanup
+    ext4_msg(sb, KERN_INFO, "Errors on filesystem, "
+      __ext4_msg
+        ___ratelimit(&(EXT4_SB(sb)->s_msg_ratelimit_state)
+          if (!rs->interval)  // do nothing if interval is 0
+            return 1;
+          raw_spin_trylock_irqsave(&rs->lock, flags)
+            raw_spin_trylock(lock)
+              _raw_spin_trylock
+                __raw_spin_trylock
+                  spin_acquire(&lock->dep_map, 0, 1, _RET_IP_)
+                    lock_acquire
+                      __lock_acquire
+                        register_lock_class
+                          assign_lock_key
+                            dump_stack();
+  ratelimit_state_init(&sbi->s_msg_ratelimit_state, 5 * HZ, 10);
+    raw_spin_lock_init(&rs->lock);
+    // init rs->lock here
+
+and get the following dump_stack:
+
+=========================================================
+INFO: trying to register non-static key.
+The code is fine but needs lockdep annotation, or maybe
+you didn't initialize this object before use?
+turning off the locking correctness validator.
+CPU: 12 PID: 753 Comm: mount Tainted: G E 6.7.0-rc6-next-20231222 #504
+[...]
+Call Trace:
+ dump_stack_lvl+0xc5/0x170
+ dump_stack+0x18/0x30
+ register_lock_class+0x740/0x7c0
+ __lock_acquire+0x69/0x13a0
+ lock_acquire+0x120/0x450
+ _raw_spin_trylock+0x98/0xd0
+ ___ratelimit+0xf6/0x220
+ __ext4_msg+0x7f/0x160 [ext4]
+ ext4_orphan_cleanup+0x665/0x740 [ext4]
+ __ext4_fill_super+0x21ea/0x2b10 [ext4]
+ ext4_fill_super+0x14d/0x360 [ext4]
+[...]
+=========================================================
+
+Normally interval is 0 until s_msg_ratelimit_state is initialized, so
+___ratelimit() does nothing. But registering sysfs precedes initializing
+rs->lock, so it is possible to change rs->interval to a non-zero value
+via the msg_ratelimit_interval_ms interface of sysfs while rs->lock is
+uninitialized, and then a call to ext4_msg triggers the problem by
+accessing an uninitialized rs->lock. Therefore register sysfs after all
+initializations are complete to avoid such problems.
+
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20240102133730.1098120-1-libaokun1@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/super.c | 22 ++++++++++------------
+ 1 file changed, 10 insertions(+), 12 deletions(-)
+
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 044135796f2b6..4b368f4dbc45a 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -5551,19 +5551,15 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
+       if (err)
+               goto failed_mount6;
+-      err = ext4_register_sysfs(sb);
+-      if (err)
+-              goto failed_mount7;
+-
+       err = ext4_init_orphan_info(sb);
+       if (err)
+-              goto failed_mount8;
++              goto failed_mount7;
+ #ifdef CONFIG_QUOTA
+       /* Enable quota usage during mount. */
+       if (ext4_has_feature_quota(sb) && !sb_rdonly(sb)) {
+               err = ext4_enable_quotas(sb);
+               if (err)
+-                      goto failed_mount9;
++                      goto failed_mount8;
+       }
+ #endif  /* CONFIG_QUOTA */
+@@ -5589,7 +5585,7 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
+               ext4_msg(sb, KERN_INFO, "recovery complete");
+               err = ext4_mark_recovery_complete(sb, es);
+               if (err)
+-                      goto failed_mount10;
++                      goto failed_mount9;
+       }
+       if (test_opt(sb, DISCARD) && !bdev_max_discard_sectors(sb->s_bdev))
+@@ -5606,15 +5602,17 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
+       atomic_set(&sbi->s_warning_count, 0);
+       atomic_set(&sbi->s_msg_count, 0);
++      /* Register sysfs after all initializations are complete. */
++      err = ext4_register_sysfs(sb);
++      if (err)
++              goto failed_mount9;
++
+       return 0;
+-failed_mount10:
++failed_mount9:
+       ext4_quotas_off(sb, EXT4_MAXQUOTAS);
+-failed_mount9: __maybe_unused
++failed_mount8: __maybe_unused
+       ext4_release_orphan_info(sb);
+-failed_mount8:
+-      ext4_unregister_sysfs(sb);
+-      kobject_put(&sbi->s_kobj);
+ failed_mount7:
+       ext4_unregister_li_request(sb);
+ failed_mount6:
+-- 
+2.43.0
+
diff --git a/queue-6.9/f2fs-don-t-set-ro-when-shutting-down-f2fs.patch b/queue-6.9/f2fs-don-t-set-ro-when-shutting-down-f2fs.patch
new file mode 100644 (file)
index 0000000..50cc457
--- /dev/null
@@ -0,0 +1,61 @@
+From 9a5d04de8af3870b424beb070dfe275c65c553f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Apr 2024 23:07:53 +0000
+Subject: f2fs: don't set RO when shutting down f2fs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+
+[ Upstream commit 3bdb7f161697e2d5123b89fe1778ef17a44858e7 ]
+
+Shutdown does not check the error of thaw_super due to readonly, which
+causes a deadlock like below.
+
+f2fs_ioc_shutdown(F2FS_GOING_DOWN_FULLSYNC)        issue_discard_thread
+ - bdev_freeze
+  - freeze_super
+ - f2fs_stop_checkpoint()
+  - f2fs_handle_critical_error                     - sb_start_write
+    - set RO                                         - waiting
+ - bdev_thaw
+  - thaw_super_locked
+    - return -EINVAL, if sb_rdonly()
+ - f2fs_stop_discard_thread
+  -> wait for kthread_stop(discard_thread);
+
+Reported-by: "Light Hsieh (謝明燈)" <Light.Hsieh@mediatek.com>
+Reviewed-by: Daeho Jeong <daehojeong@google.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/super.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index e4c795a711f0f..2f75a7dfc311d 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -4129,9 +4129,15 @@ void f2fs_handle_critical_error(struct f2fs_sb_info *sbi, unsigned char reason,
+       if (shutdown)
+               set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
+-      /* continue filesystem operators if errors=continue */
+-      if (continue_fs || f2fs_readonly(sb))
++      /*
++       * Continue filesystem operators if errors=continue. Should not set
++       * RO by shutdown, since RO bypasses thaw_super which can hang the
++       * system.
++       */
++      if (continue_fs || f2fs_readonly(sb) || shutdown) {
++              f2fs_warn(sbi, "Stopped filesystem due to reason: %d", reason);
+               return;
++      }
+       f2fs_warn(sbi, "Remounting filesystem read-only");
+       /*
+-- 
+2.43.0
+
diff --git a/queue-6.9/f2fs-fix-to-detect-inconsistent-nat-entry-during-tru.patch b/queue-6.9/f2fs-fix-to-detect-inconsistent-nat-entry-during-tru.patch
new file mode 100644 (file)
index 0000000..d7e4448
--- /dev/null
@@ -0,0 +1,71 @@
+From deeb3102f02310f6d207ee0fd505976bc9479386 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Mar 2024 22:59:55 +0800
+Subject: f2fs: fix to detect inconsistent nat entry during truncation
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 92c556ed6318e13c16746495a8d4513129eb9b0f ]
+
+As Roman Smirnov reported as below:
+
+"
+There is a possible bug in f2fs_truncate_inode_blocks():
+
+    if (err < 0 && err != -ENOENT)
+                       goto fail;
+        ...
+        offset[1] = 0;
+        offset[0]++;
+        nofs += err;
+
+If err = -ENOENT then nofs will sum with an error code,
+which is strange behaviour. Also if nofs < ENOENT this will
+cause an overflow. err will be equal to -ENOENT with the
+following call stack:
+
+truncate_nodes()
+  f2fs_get_node_page()
+     __get_node_page()
+        read_node_page()
+"
+
+If nat is corrupted, truncate_nodes() may return -ENOENT, and
+f2fs_truncate_inode_blocks() doesn't handle such error correctly,
+fix it.
+
+Reported-by: Roman Smirnov <r.smirnov@omp.ru>
+Closes: https://lore.kernel.org/linux-f2fs-devel/085b27fd2b364a3c8c3a9ca77363e246@omp.ru
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/node.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
+index 7df5ad84cb5ea..15c9a9f5750bc 100644
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -1187,7 +1187,17 @@ int f2fs_truncate_inode_blocks(struct inode *inode, pgoff_t from)
+               default:
+                       BUG();
+               }
+-              if (err < 0 && err != -ENOENT)
++              if (err == -ENOENT) {
++                      set_sbi_flag(F2FS_P_SB(page), SBI_NEED_FSCK);
++                      f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
++                      f2fs_err_ratelimited(sbi,
++                              "truncate node fail, ino:%lu, nid:%u, "
++                              "offset[0]:%d, offset[1]:%d, nofs:%d",
++                              inode->i_ino, dn.nid, offset[0],
++                              offset[1], nofs);
++                      err = 0;
++              }
++              if (err < 0)
+                       goto fail;
+               if (offset[1] == 0 &&
+                               ri->i_nid[offset[0] - NODE_DIR1_BLOCK]) {
+-- 
+2.43.0
+
diff --git a/queue-6.9/f2fs-remove-clear-sb_inlinecrypt-flag-in-default_opt.patch b/queue-6.9/f2fs-remove-clear-sb_inlinecrypt-flag-in-default_opt.patch
new file mode 100644 (file)
index 0000000..89fedd6
--- /dev/null
@@ -0,0 +1,49 @@
+From be70614d87628a3d26a2c9d05842bba1b19657a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Mar 2024 14:10:43 +0800
+Subject: f2fs: remove clear SB_INLINECRYPT flag in default_options
+
+From: Yunlei He <heyunlei@oppo.com>
+
+[ Upstream commit ac5eecf481c29942eb9a862e758c0c8b68090c33 ]
+
+In f2fs_remount, SB_INLINECRYPT flag will be clear and re-set.
+If create new file or open file during this gap, these files
+will not use inlinecrypt. Worse case, it may lead to data
+corruption if wrappedkey_v0 is enable.
+
+Thread A:                               Thread B:
+
+-f2fs_remount                          -f2fs_file_open or f2fs_new_inode
+  -default_options
+       <- clear SB_INLINECRYPT flag
+
+                                          -fscrypt_select_encryption_impl
+
+  -parse_options
+       <- set SB_INLINECRYPT again
+
+Signed-off-by: Yunlei He <heyunlei@oppo.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/super.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index a4bc26dfdb1af..e4c795a711f0f 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -2132,8 +2132,6 @@ static void default_options(struct f2fs_sb_info *sbi, bool remount)
+       F2FS_OPTION(sbi).memory_mode = MEMORY_MODE_NORMAL;
+       F2FS_OPTION(sbi).errors = MOUNT_ERRORS_CONTINUE;
+-      sbi->sb->s_flags &= ~SB_INLINECRYPT;
+-
+       set_opt(sbi, INLINE_XATTR);
+       set_opt(sbi, INLINE_DATA);
+       set_opt(sbi, INLINE_DENTRY);
+-- 
+2.43.0
+
diff --git a/queue-6.9/fs-writeback-bail-out-if-there-is-no-more-inodes-for.patch b/queue-6.9/fs-writeback-bail-out-if-there-is-no-more-inodes-for.patch
new file mode 100644 (file)
index 0000000..a50c2ab
--- /dev/null
@@ -0,0 +1,63 @@
+From 390625218b45316aed191f37c64be43b406377f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Feb 2024 17:19:54 +0800
+Subject: fs/writeback: bail out if there is no more inodes for IO and queued
+ once
+
+From: Kemeng Shi <shikemeng@huaweicloud.com>
+
+[ Upstream commit d92109891f21cf367caa2cc6dff11a4411d917f4 ]
+
+For case there is no more inodes for IO in io list from last wb_writeback,
+We may bail out early even there is inode in dirty list should be written
+back. Only bail out when we queued once to avoid missing dirtied inode.
+
+This is from code reading...
+
+Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
+Link: https://lore.kernel.org/r/20240228091958.288260-3-shikemeng@huaweicloud.com
+Reviewed-by: Jan Kara <jack@suse.cz>
+[brauner@kernel.org: fold in memory corruption fix from Jan in [1]]
+Link: https://lore.kernel.org/r/20240405132346.bid7gibby3lxxhez@quack3 [1]
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fs-writeback.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
+index e4f17c53ddfcf..d31853032a931 100644
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -2069,6 +2069,7 @@ static long wb_writeback(struct bdi_writeback *wb,
+       struct inode *inode;
+       long progress;
+       struct blk_plug plug;
++      bool queued = false;
+       blk_start_plug(&plug);
+       for (;;) {
+@@ -2111,8 +2112,10 @@ static long wb_writeback(struct bdi_writeback *wb,
+                       dirtied_before = jiffies;
+               trace_writeback_start(wb, work);
+-              if (list_empty(&wb->b_io))
++              if (list_empty(&wb->b_io)) {
+                       queue_io(wb, work, dirtied_before);
++                      queued = true;
++              }
+               if (work->sb)
+                       progress = writeback_sb_inodes(work->sb, wb, work);
+               else
+@@ -2127,7 +2130,7 @@ static long wb_writeback(struct bdi_writeback *wb,
+                * mean the overall work is done. So we keep looping as long
+                * as made some progress on cleaning pages or inodes.
+                */
+-              if (progress) {
++              if (progress || !queued) {
+                       spin_unlock(&wb->list_lock);
+                       continue;
+               }
+-- 
+2.43.0
+
diff --git a/queue-6.9/hid-add-quirk-for-logitech-casa-touchpad.patch b/queue-6.9/hid-add-quirk-for-logitech-casa-touchpad.patch
new file mode 100644 (file)
index 0000000..83aed1f
--- /dev/null
@@ -0,0 +1,56 @@
+From 09574bae016081cf3b951f155a385ff003aae726 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Apr 2024 18:08:05 +0000
+Subject: HID: Add quirk for Logitech Casa touchpad
+
+From: Sean O'Brien <seobrien@chromium.org>
+
+[ Upstream commit dd2c345a94cfa3873cc20db87387ee509c345c1b ]
+
+This device sometimes doesn't send touch release signals when moving
+from >=4 fingers to <4 fingers. Using MT_QUIRK_NOT_SEEN_MEANS_UP instead
+of MT_QUIRK_ALWAYS_VALID makes sure that no touches become stuck.
+
+MT_QUIRK_FORCE_MULTI_INPUT is not necessary for this device, but does no
+harm.
+
+Signed-off-by: Sean O'Brien <seobrien@chromium.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-ids.h        | 1 +
+ drivers/hid/hid-multitouch.c | 6 ++++++
+ 2 files changed, 7 insertions(+)
+
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index 8376fb5e2d0b4..68b0f39deaa9a 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -823,6 +823,7 @@
+ #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e
+ #define USB_DEVICE_ID_LOGITECH_T651   0xb00c
+ #define USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD        0xb309
++#define USB_DEVICE_ID_LOGITECH_CASA_TOUCHPAD  0xbb00
+ #define USB_DEVICE_ID_LOGITECH_C007   0xc007
+ #define USB_DEVICE_ID_LOGITECH_C077   0xc077
+ #define USB_DEVICE_ID_LOGITECH_RECEIVER       0xc101
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index 04a014cd2a2f6..56fc78841f245 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -2081,6 +2081,12 @@ static const struct hid_device_id mt_devices[] = {
+                          USB_VENDOR_ID_LENOVO,
+                          USB_DEVICE_ID_LENOVO_X12_TAB) },
++      /* Logitech devices */
++      { .driver_data = MT_CLS_NSMU,
++              HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH_WIN_8,
++                      USB_VENDOR_ID_LOGITECH,
++                      USB_DEVICE_ID_LOGITECH_CASA_TOUCHPAD) },
++
+       /* MosArt panels */
+       { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
+               MT_USB_DEVICE(USB_VENDOR_ID_ASUS,
+-- 
+2.43.0
+
diff --git a/queue-6.9/hid-asus-fix-more-n-key-report-descriptors-if-n-key-.patch b/queue-6.9/hid-asus-fix-more-n-key-report-descriptors-if-n-key-.patch
new file mode 100644 (file)
index 0000000..cad7b8b
--- /dev/null
@@ -0,0 +1,101 @@
+From ed1bc62a63bf7669628486883e1d5adc0a76539a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Apr 2024 21:03:59 +1200
+Subject: HID: asus: fix more n-key report descriptors if n-key quirked
+
+From: Luke D. Jones <luke@ljones.dev>
+
+[ Upstream commit 59d2f5b7392e988a391e6924e177c1a68d50223d ]
+
+Adjusts the report descriptor for N-Key devices to
+make the output count 0x01 which completely avoids
+the need for a block of filtering.
+
+Signed-off-by: Luke D. Jones <luke@ljones.dev>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-asus.c | 51 ++++++++++++++++++++----------------------
+ 1 file changed, 24 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
+index 78cdfb8b9a7ae..d6d8a028623a7 100644
+--- a/drivers/hid/hid-asus.c
++++ b/drivers/hid/hid-asus.c
+@@ -335,36 +335,20 @@ static int asus_raw_event(struct hid_device *hdev,
+       if (drvdata->quirks & QUIRK_MEDION_E1239T)
+               return asus_e1239t_event(drvdata, data, size);
+-      if (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT) {
++      /*
++       * Skip these report ID, the device emits a continuous stream associated
++       * with the AURA mode it is in which looks like an 'echo'.
++       */
++      if (report->id == FEATURE_KBD_LED_REPORT_ID1 || report->id == FEATURE_KBD_LED_REPORT_ID2)
++              return -1;
++      if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD) {
+               /*
+-               * Skip these report ID, the device emits a continuous stream associated
+-               * with the AURA mode it is in which looks like an 'echo'.
++               * G713 and G733 send these codes on some keypresses, depending on
++               * the key pressed it can trigger a shutdown event if not caught.
+               */
+-              if (report->id == FEATURE_KBD_LED_REPORT_ID1 ||
+-                              report->id == FEATURE_KBD_LED_REPORT_ID2) {
++              if (data[0] == 0x02 && data[1] == 0x30) {
+                       return -1;
+-              /* Additional report filtering */
+-              } else if (report->id == FEATURE_KBD_REPORT_ID) {
+-                      /*
+-                       * G14 and G15 send these codes on some keypresses with no
+-                       * discernable reason for doing so. We'll filter them out to avoid
+-                       * unmapped warning messages later.
+-                      */
+-                      if (data[1] == 0xea || data[1] == 0xec || data[1] == 0x02 ||
+-                                      data[1] == 0x8a || data[1] == 0x9e) {
+-                              return -1;
+-                      }
+               }
+-              if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD) {
+-                      /*
+-                       * G713 and G733 send these codes on some keypresses, depending on
+-                       * the key pressed it can trigger a shutdown event if not caught.
+-                      */
+-                      if(data[0] == 0x02 && data[1] == 0x30) {
+-                              return -1;
+-                      }
+-              }
+-
+       }
+       if (drvdata->quirks & QUIRK_ROG_CLAYMORE_II_KEYBOARD) {
+@@ -1250,6 +1234,19 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+               rdesc[205] = 0x01;
+       }
++      /* match many more n-key devices */
++      if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD) {
++              for (int i = 0; i < *rsize + 1; i++) {
++                      /* offset to the count from 0x5a report part always 14 */
++                      if (rdesc[i] == 0x85 && rdesc[i + 1] == 0x5a &&
++                          rdesc[i + 14] == 0x95 && rdesc[i + 15] == 0x05) {
++                              hid_info(hdev, "Fixing up Asus N-Key report descriptor\n");
++                              rdesc[i + 15] = 0x01;
++                              break;
++                      }
++              }
++      }
++
+       return rdesc;
+ }
+@@ -1319,4 +1316,4 @@ static struct hid_driver asus_driver = {
+ };
+ module_hid_driver(asus_driver);
+-MODULE_LICENSE("GPL");
+\ No newline at end of file
++MODULE_LICENSE("GPL");
+-- 
+2.43.0
+
diff --git a/queue-6.9/i2c-lpi2c-avoid-calling-clk_get_rate-during-transfer.patch b/queue-6.9/i2c-lpi2c-avoid-calling-clk_get_rate-during-transfer.patch
new file mode 100644 (file)
index 0000000..8d2efe3
--- /dev/null
@@ -0,0 +1,75 @@
+From 865235dcddaa1b2049681a69a8015e5a9629b46b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Apr 2024 13:36:29 +0200
+Subject: i2c: lpi2c: Avoid calling clk_get_rate during transfer
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit 4268254a39484fc11ba991ae148bacbe75d9cc0a ]
+
+Instead of repeatedly calling clk_get_rate for each transfer, lock
+the clock rate and cache the value.
+A deadlock has been observed while adding tlv320aic32x4 audio codec to
+the system. When this clock provider adds its clock, the clk mutex is
+locked already, it needs to access i2c, which in return needs the mutex
+for clk_get_rate as well.
+
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Reviewed-by: Andi Shyti <andi.shyti@kernel.org>
+Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-imx-lpi2c.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c
+index 6d72e4e126dde..36e8f6196a87b 100644
+--- a/drivers/i2c/busses/i2c-imx-lpi2c.c
++++ b/drivers/i2c/busses/i2c-imx-lpi2c.c
+@@ -99,6 +99,7 @@ struct lpi2c_imx_struct {
+       __u8                    *rx_buf;
+       __u8                    *tx_buf;
+       struct completion       complete;
++      unsigned long           rate_per;
+       unsigned int            msglen;
+       unsigned int            delivered;
+       unsigned int            block_data;
+@@ -212,9 +213,7 @@ static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx)
+       lpi2c_imx_set_mode(lpi2c_imx);
+-      clk_rate = clk_get_rate(lpi2c_imx->clks[0].clk);
+-      if (!clk_rate)
+-              return -EINVAL;
++      clk_rate = lpi2c_imx->rate_per;
+       if (lpi2c_imx->mode == HS || lpi2c_imx->mode == ULTRA_FAST)
+               filt = 0;
+@@ -611,6 +610,20 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
+       if (ret)
+               return ret;
++      /*
++       * Lock the parent clock rate to avoid getting parent clock upon
++       * each transfer
++       */
++      ret = devm_clk_rate_exclusive_get(&pdev->dev, lpi2c_imx->clks[0].clk);
++      if (ret)
++              return dev_err_probe(&pdev->dev, ret,
++                                   "can't lock I2C peripheral clock rate\n");
++
++      lpi2c_imx->rate_per = clk_get_rate(lpi2c_imx->clks[0].clk);
++      if (!lpi2c_imx->rate_per)
++              return dev_err_probe(&pdev->dev, -EINVAL,
++                                   "can't get I2C peripheral clock rate\n");
++
+       pm_runtime_set_autosuspend_delay(&pdev->dev, I2C_PM_TIMEOUT);
+       pm_runtime_use_autosuspend(&pdev->dev);
+       pm_runtime_get_noresume(&pdev->dev);
+-- 
+2.43.0
+
diff --git a/queue-6.9/io_uring-sqpoll-work-around-a-potential-audit-memory.patch b/queue-6.9/io_uring-sqpoll-work-around-a-potential-audit-memory.patch
new file mode 100644 (file)
index 0000000..4b60159
--- /dev/null
@@ -0,0 +1,66 @@
+From 568b5fba320c91d86c0a06bf4c523b5bd71bf942 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Mar 2024 07:38:38 -0600
+Subject: io_uring/sqpoll: work around a potential audit memory leak
+
+From: Jens Axboe <axboe@kernel.dk>
+
+[ Upstream commit c4ce0ab27646f4206a9eb502d6fe45cb080e1cae ]
+
+kmemleak complains that there's a memory leak related to connect
+handling:
+
+unreferenced object 0xffff0001093bdf00 (size 128):
+comm "iou-sqp-455", pid 457, jiffies 4294894164
+hex dump (first 32 bytes):
+02 00 fa ea 7f 00 00 01 00 00 00 00 00 00 00 00  ................
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+backtrace (crc 2e481b1a):
+[<00000000c0a26af4>] kmemleak_alloc+0x30/0x38
+[<000000009c30bb45>] kmalloc_trace+0x228/0x358
+[<000000009da9d39f>] __audit_sockaddr+0xd0/0x138
+[<0000000089a93e34>] move_addr_to_kernel+0x1a0/0x1f8
+[<000000000b4e80e6>] io_connect_prep+0x1ec/0x2d4
+[<00000000abfbcd99>] io_submit_sqes+0x588/0x1e48
+[<00000000e7c25e07>] io_sq_thread+0x8a4/0x10e4
+[<00000000d999b491>] ret_from_fork+0x10/0x20
+
+which can can happen if:
+
+1) The command type does something on the prep side that triggers an
+   audit call.
+2) The thread hasn't done any operations before this that triggered
+   an audit call inside ->issue(), where we have audit_uring_entry()
+   and audit_uring_exit().
+
+Work around this by issuing a blanket NOP operation before the SQPOLL
+does anything.
+
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/sqpoll.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/io_uring/sqpoll.c b/io_uring/sqpoll.c
+index 158ab09c605ba..b3722e5275e77 100644
+--- a/io_uring/sqpoll.c
++++ b/io_uring/sqpoll.c
+@@ -293,6 +293,14 @@ static int io_sq_thread(void *data)
+               sqd->sq_cpu = raw_smp_processor_id();
+       }
++      /*
++       * Force audit context to get setup, in case we do prep side async
++       * operations that would trigger an audit call before any issue side
++       * audit has been done.
++       */
++      audit_uring_entry(IORING_OP_NOP);
++      audit_uring_exit(true, 0);
++
+       mutex_lock(&sqd->lock);
+       while (1) {
+               bool cap_entries, sqt_spin = false;
+-- 
+2.43.0
+
diff --git a/queue-6.9/iommu-arm-smmu-v3-free-msis-in-case-of-enomem.patch b/queue-6.9/iommu-arm-smmu-v3-free-msis-in-case-of-enomem.patch
new file mode 100644 (file)
index 0000000..57866b1
--- /dev/null
@@ -0,0 +1,40 @@
+From 4ce693f5b91a678f3cfb7eb03204db902b0b752d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Apr 2024 12:37:59 +0700
+Subject: iommu/arm-smmu-v3: Free MSIs in case of ENOMEM
+
+From: Aleksandr Aprelkov <aaprelkov@usergate.com>
+
+[ Upstream commit 80fea979dd9d48d67c5b48d2f690c5da3e543ebd ]
+
+If devm_add_action() returns -ENOMEM, then MSIs are allocated but not
+not freed on teardown. Use devm_add_action_or_reset() instead to keep
+the static analyser happy.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Signed-off-by: Aleksandr Aprelkov <aaprelkov@usergate.com>
+Link: https://lore.kernel.org/r/20240403053759.643164-1-aaprelkov@usergate.com
+[will: Tweak commit message, remove warning message]
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+index 41f93c3ab160d..3afec8714cf28 100644
+--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
++++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+@@ -3402,7 +3402,7 @@ static void arm_smmu_setup_msis(struct arm_smmu_device *smmu)
+       smmu->priq.q.irq = msi_get_virq(dev, PRIQ_MSI_INDEX);
+       /* Add callback to free MSIs on teardown */
+-      devm_add_action(dev, arm_smmu_free_msis, dev);
++      devm_add_action_or_reset(dev, arm_smmu_free_msis, dev);
+ }
+ static void arm_smmu_setup_unique_irqs(struct arm_smmu_device *smmu)
+-- 
+2.43.0
+
diff --git a/queue-6.9/kprobe-ftrace-bail-out-if-ftrace-was-killed.patch b/queue-6.9/kprobe-ftrace-bail-out-if-ftrace-was-killed.patch
new file mode 100644 (file)
index 0000000..843d544
--- /dev/null
@@ -0,0 +1,226 @@
+From 6837850d5a6bfea744116f96cdc7efe4251144f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 May 2024 09:29:56 -0700
+Subject: kprobe/ftrace: bail out if ftrace was killed
+
+From: Stephen Brennan <stephen.s.brennan@oracle.com>
+
+[ Upstream commit 1a7d0890dd4a502a202aaec792a6c04e6e049547 ]
+
+If an error happens in ftrace, ftrace_kill() will prevent disarming
+kprobes. Eventually, the ftrace_ops associated with the kprobes will be
+freed, yet the kprobes will still be active, and when triggered, they
+will use the freed memory, likely resulting in a page fault and panic.
+
+This behavior can be reproduced quite easily, by creating a kprobe and
+then triggering a ftrace_kill(). For simplicity, we can simulate an
+ftrace error with a kernel module like [1]:
+
+[1]: https://github.com/brenns10/kernel_stuff/tree/master/ftrace_killer
+
+  sudo perf probe --add commit_creds
+  sudo perf trace -e probe:commit_creds
+  # In another terminal
+  make
+  sudo insmod ftrace_killer.ko  # calls ftrace_kill(), simulating bug
+  # Back to perf terminal
+  # ctrl-c
+  sudo perf probe --del commit_creds
+
+After a short period, a page fault and panic would occur as the kprobe
+continues to execute and uses the freed ftrace_ops. While ftrace_kill()
+is supposed to be used only in extreme circumstances, it is invoked in
+FTRACE_WARN_ON() and so there are many places where an unexpected bug
+could be triggered, yet the system may continue operating, possibly
+without the administrator noticing. If ftrace_kill() does not panic the
+system, then we should do everything we can to continue operating,
+rather than leave a ticking time bomb.
+
+Link: https://lore.kernel.org/all/20240501162956.229427-1-stephen.s.brennan@oracle.com/
+
+Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
+Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Acked-by: Guo Ren <guoren@kernel.org>
+Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/csky/kernel/probes/ftrace.c     | 3 +++
+ arch/loongarch/kernel/ftrace_dyn.c   | 3 +++
+ arch/parisc/kernel/ftrace.c          | 3 +++
+ arch/powerpc/kernel/kprobes-ftrace.c | 3 +++
+ arch/riscv/kernel/probes/ftrace.c    | 3 +++
+ arch/s390/kernel/ftrace.c            | 3 +++
+ arch/x86/kernel/kprobes/ftrace.c     | 3 +++
+ include/linux/kprobes.h              | 7 +++++++
+ kernel/kprobes.c                     | 6 ++++++
+ kernel/trace/ftrace.c                | 1 +
+ 10 files changed, 35 insertions(+)
+
+diff --git a/arch/csky/kernel/probes/ftrace.c b/arch/csky/kernel/probes/ftrace.c
+index 834cffcfbce32..7ba4b98076de1 100644
+--- a/arch/csky/kernel/probes/ftrace.c
++++ b/arch/csky/kernel/probes/ftrace.c
+@@ -12,6 +12,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
+       struct kprobe_ctlblk *kcb;
+       struct pt_regs *regs;
++      if (unlikely(kprobe_ftrace_disabled))
++              return;
++
+       bit = ftrace_test_recursion_trylock(ip, parent_ip);
+       if (bit < 0)
+               return;
+diff --git a/arch/loongarch/kernel/ftrace_dyn.c b/arch/loongarch/kernel/ftrace_dyn.c
+index 73858c9029cc9..bff058317062e 100644
+--- a/arch/loongarch/kernel/ftrace_dyn.c
++++ b/arch/loongarch/kernel/ftrace_dyn.c
+@@ -287,6 +287,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
+       struct kprobe *p;
+       struct kprobe_ctlblk *kcb;
++      if (unlikely(kprobe_ftrace_disabled))
++              return;
++
+       bit = ftrace_test_recursion_trylock(ip, parent_ip);
+       if (bit < 0)
+               return;
+diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c
+index 621a4b386ae4f..c91f9c2e61ed2 100644
+--- a/arch/parisc/kernel/ftrace.c
++++ b/arch/parisc/kernel/ftrace.c
+@@ -206,6 +206,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
+       struct kprobe *p;
+       int bit;
++      if (unlikely(kprobe_ftrace_disabled))
++              return;
++
+       bit = ftrace_test_recursion_trylock(ip, parent_ip);
+       if (bit < 0)
+               return;
+diff --git a/arch/powerpc/kernel/kprobes-ftrace.c b/arch/powerpc/kernel/kprobes-ftrace.c
+index 072ebe7f290ba..f8208c027148f 100644
+--- a/arch/powerpc/kernel/kprobes-ftrace.c
++++ b/arch/powerpc/kernel/kprobes-ftrace.c
+@@ -21,6 +21,9 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,
+       struct pt_regs *regs;
+       int bit;
++      if (unlikely(kprobe_ftrace_disabled))
++              return;
++
+       bit = ftrace_test_recursion_trylock(nip, parent_nip);
+       if (bit < 0)
+               return;
+diff --git a/arch/riscv/kernel/probes/ftrace.c b/arch/riscv/kernel/probes/ftrace.c
+index 7142ec42e889f..a69dfa610aa85 100644
+--- a/arch/riscv/kernel/probes/ftrace.c
++++ b/arch/riscv/kernel/probes/ftrace.c
+@@ -11,6 +11,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
+       struct kprobe_ctlblk *kcb;
+       int bit;
++      if (unlikely(kprobe_ftrace_disabled))
++              return;
++
+       bit = ftrace_test_recursion_trylock(ip, parent_ip);
+       if (bit < 0)
+               return;
+diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c
+index c46381ea04ecb..7f6f8c438c265 100644
+--- a/arch/s390/kernel/ftrace.c
++++ b/arch/s390/kernel/ftrace.c
+@@ -296,6 +296,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
+       struct kprobe *p;
+       int bit;
++      if (unlikely(kprobe_ftrace_disabled))
++              return;
++
+       bit = ftrace_test_recursion_trylock(ip, parent_ip);
+       if (bit < 0)
+               return;
+diff --git a/arch/x86/kernel/kprobes/ftrace.c b/arch/x86/kernel/kprobes/ftrace.c
+index dd2ec14adb77b..15af7e98e161a 100644
+--- a/arch/x86/kernel/kprobes/ftrace.c
++++ b/arch/x86/kernel/kprobes/ftrace.c
+@@ -21,6 +21,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
+       struct kprobe_ctlblk *kcb;
+       int bit;
++      if (unlikely(kprobe_ftrace_disabled))
++              return;
++
+       bit = ftrace_test_recursion_trylock(ip, parent_ip);
+       if (bit < 0)
+               return;
+diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
+index 0ff44d6633e33..5fcbc254d1864 100644
+--- a/include/linux/kprobes.h
++++ b/include/linux/kprobes.h
+@@ -378,11 +378,15 @@ static inline void wait_for_kprobe_optimizer(void) { }
+ extern void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
+                                 struct ftrace_ops *ops, struct ftrace_regs *fregs);
+ extern int arch_prepare_kprobe_ftrace(struct kprobe *p);
++/* Set when ftrace has been killed: kprobes on ftrace must be disabled for safety */
++extern bool kprobe_ftrace_disabled __read_mostly;
++extern void kprobe_ftrace_kill(void);
+ #else
+ static inline int arch_prepare_kprobe_ftrace(struct kprobe *p)
+ {
+       return -EINVAL;
+ }
++static inline void kprobe_ftrace_kill(void) {}
+ #endif /* CONFIG_KPROBES_ON_FTRACE */
+ /* Get the kprobe at this addr (if any) - called with preemption disabled */
+@@ -495,6 +499,9 @@ static inline void kprobe_flush_task(struct task_struct *tk)
+ static inline void kprobe_free_init_mem(void)
+ {
+ }
++static inline void kprobe_ftrace_kill(void)
++{
++}
+ static inline int disable_kprobe(struct kprobe *kp)
+ {
+       return -EOPNOTSUPP;
+diff --git a/kernel/kprobes.c b/kernel/kprobes.c
+index 65adc815fc6e6..166ebf81dc450 100644
+--- a/kernel/kprobes.c
++++ b/kernel/kprobes.c
+@@ -1068,6 +1068,7 @@ static struct ftrace_ops kprobe_ipmodify_ops __read_mostly = {
+ static int kprobe_ipmodify_enabled;
+ static int kprobe_ftrace_enabled;
++bool kprobe_ftrace_disabled;
+ static int __arm_kprobe_ftrace(struct kprobe *p, struct ftrace_ops *ops,
+                              int *cnt)
+@@ -1136,6 +1137,11 @@ static int disarm_kprobe_ftrace(struct kprobe *p)
+               ipmodify ? &kprobe_ipmodify_ops : &kprobe_ftrace_ops,
+               ipmodify ? &kprobe_ipmodify_enabled : &kprobe_ftrace_enabled);
+ }
++
++void kprobe_ftrace_kill()
++{
++      kprobe_ftrace_disabled = true;
++}
+ #else /* !CONFIG_KPROBES_ON_FTRACE */
+ static inline int arm_kprobe_ftrace(struct kprobe *p)
+ {
+diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
+index 1e12df9bb531b..2e11236722366 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -7902,6 +7902,7 @@ void ftrace_kill(void)
+       ftrace_disabled = 1;
+       ftrace_enabled = 0;
+       ftrace_trace_function = ftrace_stub;
++      kprobe_ftrace_kill();
+ }
+ /**
+-- 
+2.43.0
+
diff --git a/queue-6.9/kselftest-arm64-add-a-null-pointer-check.patch b/queue-6.9/kselftest-arm64-add-a-null-pointer-check.patch
new file mode 100644 (file)
index 0000000..a64dad0
--- /dev/null
@@ -0,0 +1,48 @@
+From 9c204d4a99f1ab6037549da063accbe784d9c974 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Apr 2024 16:21:02 +0800
+Subject: kselftest: arm64: Add a null pointer check
+
+From: Kunwu Chan <chentao@kylinos.cn>
+
+[ Upstream commit 80164282b3620a3cb73de6ffda5592743e448d0e ]
+
+There is a 'malloc' call, which can be unsuccessful.
+This patch will add the malloc failure checking
+to avoid possible null dereference and give more information
+about test fail reasons.
+
+Signed-off-by: Kunwu Chan <chentao@kylinos.cn>
+Reviewed-by: Muhammad Usama Anjum <usama.anjum@collabora.com>
+Link: https://lore.kernel.org/r/20240423082102.2018886-1-chentao@kylinos.cn
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/arm64/tags/tags_test.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/tools/testing/selftests/arm64/tags/tags_test.c b/tools/testing/selftests/arm64/tags/tags_test.c
+index 5701163460ef7..955f87c1170d7 100644
+--- a/tools/testing/selftests/arm64/tags/tags_test.c
++++ b/tools/testing/selftests/arm64/tags/tags_test.c
+@@ -6,6 +6,7 @@
+ #include <stdint.h>
+ #include <sys/prctl.h>
+ #include <sys/utsname.h>
++#include "../../kselftest.h"
+ #define SHIFT_TAG(tag)                ((uint64_t)(tag) << 56)
+ #define SET_TAG(ptr, tag)     (((uint64_t)(ptr) & ~SHIFT_TAG(0xff)) | \
+@@ -21,6 +22,9 @@ int main(void)
+       if (prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) == 0)
+               tbi_enabled = 1;
+       ptr = (struct utsname *)malloc(sizeof(*ptr));
++      if (!ptr)
++              ksft_exit_fail_msg("Failed to allocate utsname buffer\n");
++
+       if (tbi_enabled)
+               tag = 0x42;
+       ptr = (struct utsname *)SET_TAG(ptr, tag);
+-- 
+2.43.0
+
diff --git a/queue-6.9/media-intel-ipu6-fix-build-with-acpi.patch b/queue-6.9/media-intel-ipu6-fix-build-with-acpi.patch
new file mode 100644 (file)
index 0000000..aaf9a7e
--- /dev/null
@@ -0,0 +1,263 @@
+From 7b50c58577a70319ec9e3470446e74670c215574 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 May 2024 14:08:13 +0100
+Subject: media: intel/ipu6: Fix build with !ACPI
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ricardo Ribalda <ribalda@chromium.org>
+
+[ Upstream commit 8810e055b57543f3465cf3c15ba4980f9f14a84e ]
+
+Modify the code so it can be compiled tested in configurations that do
+not have ACPI enabled.
+
+It fixes the following errors:
+drivers/media/pci/intel/ipu-bridge.c:103:30: error: implicit declaration of function ‘acpi_device_handle’; did you mean ‘acpi_fwnode_handle’? [-Werror=implicit-function-declaration]
+drivers/media/pci/intel/ipu-bridge.c:103:30: warning: initialization of ‘acpi_handle’ {aka ‘void *’} from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
+drivers/media/pci/intel/ipu-bridge.c:110:17: error: implicit declaration of function ‘for_each_acpi_dev_match’ [-Werror=implicit-function-declaration]
+drivers/media/pci/intel/ipu-bridge.c:110:74: error: expected ‘;’ before ‘for_each_acpi_consumer_dev’
+drivers/media/pci/intel/ipu-bridge.c:104:29: warning: unused variable ‘consumer’ [-Wunused-variable]
+drivers/media/pci/intel/ipu-bridge.c:103:21: warning: unused variable ‘handle’ [-Wunused-variable]
+drivers/media/pci/intel/ipu-bridge.c:166:38: error: invalid use of undefined type ‘struct acpi_device’
+drivers/media/pci/intel/ipu-bridge.c:185:43: error: invalid use of undefined type ‘struct acpi_device’
+drivers/media/pci/intel/ipu-bridge.c:191:30: error: invalid use of undefined type ‘struct acpi_device’
+drivers/media/pci/intel/ipu-bridge.c:196:30: error: invalid use of undefined type ‘struct acpi_device’
+drivers/media/pci/intel/ipu-bridge.c:202:30: error: invalid use of undefined type ‘struct acpi_device’
+drivers/media/pci/intel/ipu-bridge.c:223:31: error: invalid use of undefined type ‘struct acpi_device’
+drivers/media/pci/intel/ipu-bridge.c:236:18: error: implicit declaration of function ‘acpi_get_physical_device_location’ [-Werror=implicit-function-declaration]
+drivers/media/pci/intel/ipu-bridge.c:236:56: error: invalid use of undefined type ‘struct acpi_device’
+drivers/media/pci/intel/ipu-bridge.c:238:31: error: invalid use of undefined type ‘struct acpi_device’
+drivers/media/pci/intel/ipu-bridge.c:256:31: error: invalid use of undefined type ‘struct acpi_device’
+drivers/media/pci/intel/ipu-bridge.c:275:31: error: invalid use of undefined type ‘struct acpi_device’
+drivers/media/pci/intel/ipu-bridge.c:280:30: error: invalid use of undefined type ‘struct acpi_device’
+drivers/media/pci/intel/ipu-bridge.c:469:26: error: implicit declaration of function ‘acpi_device_hid’; did you mean ‘dmi_device_id’? [-Werror=implicit-function-declaration]
+drivers/media/pci/intel/ipu-bridge.c:468:74: warning: format ‘%s’ expects argument of type ‘char *’, but argument 4 has type ‘int’ [-Wformat=]
+drivers/media/pci/intel/ipu-bridge.c:637:58: error: expected ‘;’ before ‘{’ token
+drivers/media/pci/intel/ipu-bridge.c:696:1: warning: label ‘err_put_adev’ defined but not used [-Wunused-label]
+drivers/media/pci/intel/ipu-bridge.c:693:1: warning: label ‘err_put_ivsc’ defined but not used [-Wunused-label]
+drivers/media/pci/intel/ipu-bridge.c:691:1: warning: label ‘err_free_swnodes’ defined but not used [-Wunused-label]
+drivers/media/pci/intel/ipu-bridge.c:632:40: warning: unused variable ‘primary’ [-Wunused-variable]
+drivers/media/pci/intel/ipu-bridge.c:632:31: warning: unused variable ‘fwnode’ [-Wunused-variable]
+drivers/media/pci/intel/ipu-bridge.c:733:73: error: expected ‘;’ before ‘{’ token
+drivers/media/pci/intel/ipu-bridge.c:725:24: warning: unused variable ‘csi_dev’ [-Wunused-variable]
+drivers/media/pci/intel/ipu-bridge.c:724:43: warning: unused variable ‘adev’ [-Wunused-variable]
+drivers/media/pci/intel/ipu-bridge.c:599:12: warning: ‘ipu_bridge_instantiate_ivsc’ defined but not used [-Wunused-function]
+drivers/media/pci/intel/ipu-bridge.c:444:13: warning: ‘ipu_bridge_create_connection_swnodes’ defined but not used [-Wunused-function]
+drivers/media/pci/intel/ipu-bridge.c:297:13: warning: ‘ipu_bridge_create_fwnode_properties’ defined but not used [-Wunused-function]
+drivers/media/pci/intel/ipu-bridge.c:155:12: warning: ‘ipu_bridge_check_ivsc_dev’ defined but not used [-Wunused-function]
+
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/intel/ipu-bridge.c | 66 ++++++++++++++++++++--------
+ 1 file changed, 47 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/media/pci/intel/ipu-bridge.c b/drivers/media/pci/intel/ipu-bridge.c
+index e994db4f4d914..61750cc98d705 100644
+--- a/drivers/media/pci/intel/ipu-bridge.c
++++ b/drivers/media/pci/intel/ipu-bridge.c
+@@ -15,6 +15,8 @@
+ #include <media/ipu-bridge.h>
+ #include <media/v4l2-fwnode.h>
++#define ADEV_DEV(adev) ACPI_PTR(&((adev)->dev))
++
+ /*
+  * 92335fcf-3203-4472-af93-7b4453ac29da
+  *
+@@ -87,6 +89,7 @@ static const char * const ipu_vcm_types[] = {
+       "lc898212axb",
+ };
++#if IS_ENABLED(CONFIG_ACPI)
+ /*
+  * Used to figure out IVSC acpi device by ipu_bridge_get_ivsc_acpi_dev()
+  * instead of device and driver match to probe IVSC device.
+@@ -100,13 +103,13 @@ static const struct acpi_device_id ivsc_acpi_ids[] = {
+ static struct acpi_device *ipu_bridge_get_ivsc_acpi_dev(struct acpi_device *adev)
+ {
+-      acpi_handle handle = acpi_device_handle(adev);
+-      struct acpi_device *consumer, *ivsc_adev;
+       unsigned int i;
+       for (i = 0; i < ARRAY_SIZE(ivsc_acpi_ids); i++) {
+               const struct acpi_device_id *acpi_id = &ivsc_acpi_ids[i];
++              struct acpi_device *consumer, *ivsc_adev;
++              acpi_handle handle = acpi_device_handle(adev);
+               for_each_acpi_dev_match(ivsc_adev, acpi_id->id, NULL, -1)
+                       /* camera sensor depends on IVSC in DSDT if exist */
+                       for_each_acpi_consumer_dev(ivsc_adev, consumer)
+@@ -118,6 +121,12 @@ static struct acpi_device *ipu_bridge_get_ivsc_acpi_dev(struct acpi_device *adev
+       return NULL;
+ }
++#else
++static struct acpi_device *ipu_bridge_get_ivsc_acpi_dev(struct acpi_device *adev)
++{
++      return NULL;
++}
++#endif
+ static int ipu_bridge_match_ivsc_dev(struct device *dev, const void *adev)
+ {
+@@ -163,7 +172,7 @@ static int ipu_bridge_check_ivsc_dev(struct ipu_sensor *sensor,
+               csi_dev = ipu_bridge_get_ivsc_csi_dev(adev);
+               if (!csi_dev) {
+                       acpi_dev_put(adev);
+-                      dev_err(&adev->dev, "Failed to find MEI CSI dev\n");
++                      dev_err(ADEV_DEV(adev), "Failed to find MEI CSI dev\n");
+                       return -ENODEV;
+               }
+@@ -182,24 +191,25 @@ static int ipu_bridge_read_acpi_buffer(struct acpi_device *adev, char *id,
+       acpi_status status;
+       int ret = 0;
+-      status = acpi_evaluate_object(adev->handle, id, NULL, &buffer);
++      status = acpi_evaluate_object(ACPI_PTR(adev->handle),
++                                    id, NULL, &buffer);
+       if (ACPI_FAILURE(status))
+               return -ENODEV;
+       obj = buffer.pointer;
+       if (!obj) {
+-              dev_err(&adev->dev, "Couldn't locate ACPI buffer\n");
++              dev_err(ADEV_DEV(adev), "Couldn't locate ACPI buffer\n");
+               return -ENODEV;
+       }
+       if (obj->type != ACPI_TYPE_BUFFER) {
+-              dev_err(&adev->dev, "Not an ACPI buffer\n");
++              dev_err(ADEV_DEV(adev), "Not an ACPI buffer\n");
+               ret = -ENODEV;
+               goto out_free_buff;
+       }
+       if (obj->buffer.length > size) {
+-              dev_err(&adev->dev, "Given buffer is too small\n");
++              dev_err(ADEV_DEV(adev), "Given buffer is too small\n");
+               ret = -EINVAL;
+               goto out_free_buff;
+       }
+@@ -220,7 +230,7 @@ static u32 ipu_bridge_parse_rotation(struct acpi_device *adev,
+       case IPU_SENSOR_ROTATION_INVERTED:
+               return 180;
+       default:
+-              dev_warn(&adev->dev,
++              dev_warn(ADEV_DEV(adev),
+                        "Unknown rotation %d. Assume 0 degree rotation\n",
+                        ssdb->degree);
+               return 0;
+@@ -230,12 +240,14 @@ static u32 ipu_bridge_parse_rotation(struct acpi_device *adev,
+ static enum v4l2_fwnode_orientation ipu_bridge_parse_orientation(struct acpi_device *adev)
+ {
+       enum v4l2_fwnode_orientation orientation;
+-      struct acpi_pld_info *pld;
+-      acpi_status status;
++      struct acpi_pld_info *pld = NULL;
++      acpi_status status = AE_ERROR;
++#if IS_ENABLED(CONFIG_ACPI)
+       status = acpi_get_physical_device_location(adev->handle, &pld);
++#endif
+       if (ACPI_FAILURE(status)) {
+-              dev_warn(&adev->dev, "_PLD call failed, using default orientation\n");
++              dev_warn(ADEV_DEV(adev), "_PLD call failed, using default orientation\n");
+               return V4L2_FWNODE_ORIENTATION_EXTERNAL;
+       }
+@@ -253,7 +265,8 @@ static enum v4l2_fwnode_orientation ipu_bridge_parse_orientation(struct acpi_dev
+               orientation = V4L2_FWNODE_ORIENTATION_EXTERNAL;
+               break;
+       default:
+-              dev_warn(&adev->dev, "Unknown _PLD panel val %d\n", pld->panel);
++              dev_warn(ADEV_DEV(adev), "Unknown _PLD panel val %d\n",
++                       pld->panel);
+               orientation = V4L2_FWNODE_ORIENTATION_EXTERNAL;
+               break;
+       }
+@@ -272,12 +285,12 @@ int ipu_bridge_parse_ssdb(struct acpi_device *adev, struct ipu_sensor *sensor)
+               return ret;
+       if (ssdb.vcmtype > ARRAY_SIZE(ipu_vcm_types)) {
+-              dev_warn(&adev->dev, "Unknown VCM type %d\n", ssdb.vcmtype);
++              dev_warn(ADEV_DEV(adev), "Unknown VCM type %d\n", ssdb.vcmtype);
+               ssdb.vcmtype = 0;
+       }
+       if (ssdb.lanes > IPU_MAX_LANES) {
+-              dev_err(&adev->dev, "Number of lanes in SSDB is invalid\n");
++              dev_err(ADEV_DEV(adev), "Number of lanes in SSDB is invalid\n");
+               return -EINVAL;
+       }
+@@ -465,8 +478,14 @@ static void ipu_bridge_create_connection_swnodes(struct ipu_bridge *bridge,
+                                               sensor->ipu_properties);
+       if (sensor->csi_dev) {
++              const char *device_hid = "";
++
++#if IS_ENABLED(CONFIG_ACPI)
++              device_hid = acpi_device_hid(sensor->ivsc_adev);
++#endif
++
+               snprintf(sensor->ivsc_name, sizeof(sensor->ivsc_name), "%s-%u",
+-                       acpi_device_hid(sensor->ivsc_adev), sensor->link);
++                       device_hid, sensor->link);
+               nodes[SWNODE_IVSC_HID] = NODE_SENSOR(sensor->ivsc_name,
+                                                    sensor->ivsc_properties);
+@@ -631,11 +650,15 @@ static int ipu_bridge_connect_sensor(const struct ipu_sensor_config *cfg,
+ {
+       struct fwnode_handle *fwnode, *primary;
+       struct ipu_sensor *sensor;
+-      struct acpi_device *adev;
++      struct acpi_device *adev = NULL;
+       int ret;
++#if IS_ENABLED(CONFIG_ACPI)
+       for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) {
+-              if (!adev->status.enabled)
++#else
++      while (true) {
++#endif
++              if (!ACPI_PTR(adev->status.enabled))
+                       continue;
+               if (bridge->n_sensors >= IPU_MAX_PORTS) {
+@@ -671,7 +694,7 @@ static int ipu_bridge_connect_sensor(const struct ipu_sensor_config *cfg,
+                       goto err_free_swnodes;
+               }
+-              sensor->adev = acpi_dev_get(adev);
++              sensor->adev = ACPI_PTR(acpi_dev_get(adev));
+               primary = acpi_fwnode_handle(adev);
+               primary->secondary = fwnode;
+@@ -727,11 +750,16 @@ static int ipu_bridge_ivsc_is_ready(void)
+       unsigned int i;
+       for (i = 0; i < ARRAY_SIZE(ipu_supported_sensors); i++) {
++#if IS_ENABLED(CONFIG_ACPI)
+               const struct ipu_sensor_config *cfg =
+                       &ipu_supported_sensors[i];
+               for_each_acpi_dev_match(sensor_adev, cfg->hid, NULL, -1) {
+-                      if (!sensor_adev->status.enabled)
++#else
++              while (true) {
++                      sensor_adev = NULL;
++#endif
++                      if (!ACPI_PTR(sensor_adev->status.enabled))
+                               continue;
+                       adev = ipu_bridge_get_ivsc_acpi_dev(sensor_adev);
+-- 
+2.43.0
+
diff --git a/queue-6.9/media-mtk-vcodec-potential-null-pointer-deference-in.patch b/queue-6.9/media-mtk-vcodec-potential-null-pointer-deference-in.patch
new file mode 100644 (file)
index 0000000..b212c9b
--- /dev/null
@@ -0,0 +1,36 @@
+From 54a7099c1a776c742678a925b91bacb7f7723c14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Jan 2024 02:35:06 +0000
+Subject: media: mtk-vcodec: potential null pointer deference in SCP
+
+From: Fullway Wang <fullwaywang@outlook.com>
+
+[ Upstream commit 53dbe08504442dc7ba4865c09b3bbf5fe849681b ]
+
+The return value of devm_kzalloc() needs to be checked to avoid
+NULL pointer deference. This is similar to CVE-2022-3113.
+
+Link: https://lore.kernel.org/linux-media/PH7PR20MB5925094DAE3FD750C7E39E01BF712@PH7PR20MB5925.namprd20.prod.outlook.com
+Signed-off-by: Fullway Wang <fullwaywang@outlook.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../media/platform/mediatek/vcodec/common/mtk_vcodec_fw_scp.c   | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_scp.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_scp.c
+index 6bbe55de6ce9a..ff23b225db705 100644
+--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_scp.c
++++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_scp.c
+@@ -79,6 +79,8 @@ struct mtk_vcodec_fw *mtk_vcodec_fw_scp_init(void *priv, enum mtk_vcodec_fw_use
+       }
+       fw = devm_kzalloc(&plat_dev->dev, sizeof(*fw), GFP_KERNEL);
++      if (!fw)
++              return ERR_PTR(-ENOMEM);
+       fw->type = SCP;
+       fw->ops = &mtk_vcodec_rproc_msg;
+       fw->scp = scp;
+-- 
+2.43.0
+
diff --git a/queue-6.9/mips-octeon-add-pcie-link-status-check.patch b/queue-6.9/mips-octeon-add-pcie-link-status-check.patch
new file mode 100644 (file)
index 0000000..e27e7a9
--- /dev/null
@@ -0,0 +1,55 @@
+From 7264b262bc2e36cd302e94fff26cc43ebeb3e8c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Mar 2024 23:22:00 +0800
+Subject: MIPS: Octeon: Add PCIe link status check
+
+From: Songyang Li <leesongyang@outlook.com>
+
+[ Upstream commit 29b83a64df3b42c88c0338696feb6fdcd7f1f3b7 ]
+
+The standard PCIe configuration read-write interface is used to
+access the configuration space of the peripheral PCIe devices
+of the mips processor after the PCIe link surprise down, it can
+generate kernel panic caused by "Data bus error". So it is
+necessary to add PCIe link status check for system protection.
+When the PCIe link is down or in training, assigning a value
+of 0 to the configuration address can prevent read-write behavior
+to the configuration space of peripheral PCIe devices, thereby
+preventing kernel panic.
+
+Signed-off-by: Songyang Li <leesongyang@outlook.com>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/pci/pcie-octeon.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+ mode change 100644 => 100755 arch/mips/pci/pcie-octeon.c
+
+diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c
+old mode 100644
+new mode 100755
+index 2583e318e8c6b..b080c7c6cc463
+--- a/arch/mips/pci/pcie-octeon.c
++++ b/arch/mips/pci/pcie-octeon.c
+@@ -230,12 +230,18 @@ static inline uint64_t __cvmx_pcie_build_config_addr(int pcie_port, int bus,
+ {
+       union cvmx_pcie_address pcie_addr;
+       union cvmx_pciercx_cfg006 pciercx_cfg006;
++      union cvmx_pciercx_cfg032 pciercx_cfg032;
+       pciercx_cfg006.u32 =
+           cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG006(pcie_port));
+       if ((bus <= pciercx_cfg006.s.pbnum) && (dev != 0))
+               return 0;
++      pciercx_cfg032.u32 =
++              cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
++      if ((pciercx_cfg032.s.dlla == 0) || (pciercx_cfg032.s.lt == 1))
++              return 0;
++
+       pcie_addr.u64 = 0;
+       pcie_addr.config.upper = 2;
+       pcie_addr.config.io = 1;
+-- 
+2.43.0
+
diff --git a/queue-6.9/net-dsa-realtek-do-not-assert-reset-on-remove.patch b/queue-6.9/net-dsa-realtek-do-not-assert-reset-on-remove.patch
new file mode 100644 (file)
index 0000000..edbfb3e
--- /dev/null
@@ -0,0 +1,55 @@
+From 5dba3bf5592ab87e26d5a8d3a17fcd8a5b1fcfbd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Apr 2024 02:11:29 -0300
+Subject: net: dsa: realtek: do not assert reset on remove
+
+From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
+
+[ Upstream commit 4f580e9aced1816398c1c64f178302a22b8ea6e2 ]
+
+The necessity of asserting the reset on removal was previously
+questioned, as DSA's own cleanup methods should suffice to prevent
+traffic leakage[1].
+
+When a driver has subdrivers controlled by devres, they will be
+unregistered after the main driver's .remove is executed. If it asserts
+a reset, the subdrivers will be unable to communicate with the hardware
+during their cleanup. For LEDs, this means that they will fail to turn
+off, resulting in a timeout error.
+
+[1] https://lore.kernel.org/r/20240123215606.26716-9-luizluca@gmail.com/
+
+Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/realtek/rtl83xx.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/dsa/realtek/rtl83xx.c b/drivers/net/dsa/realtek/rtl83xx.c
+index d2e876805393b..a9c1702431efb 100644
+--- a/drivers/net/dsa/realtek/rtl83xx.c
++++ b/drivers/net/dsa/realtek/rtl83xx.c
+@@ -290,16 +290,13 @@ EXPORT_SYMBOL_NS_GPL(rtl83xx_shutdown, REALTEK_DSA);
+  * rtl83xx_remove() - Cleanup a realtek switch driver
+  * @priv: realtek_priv pointer
+  *
+- * If a method is provided, this function asserts the hard reset of the switch
+- * in order to avoid leaking traffic when the driver is gone.
++ * Placehold for common cleanup procedures.
+  *
+- * Context: Might sleep if priv->gdev->chip->can_sleep.
++ * Context: Any
+  * Return: nothing
+  */
+ void rtl83xx_remove(struct realtek_priv *priv)
+ {
+-      /* leave the device reset asserted */
+-      rtl83xx_reset_assert(priv);
+ }
+ EXPORT_SYMBOL_NS_GPL(rtl83xx_remove, REALTEK_DSA);
+-- 
+2.43.0
+
diff --git a/queue-6.9/net-dsa-realtek-keep-default-led-state-in-rtl8366rb.patch b/queue-6.9/net-dsa-realtek-keep-default-led-state-in-rtl8366rb.patch
new file mode 100644 (file)
index 0000000..d1a3480
--- /dev/null
@@ -0,0 +1,193 @@
+From 89df554405ea9235ac421c284eb9d337b80fdff6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Apr 2024 02:11:28 -0300
+Subject: net: dsa: realtek: keep default LED state in rtl8366rb
+
+From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
+
+[ Upstream commit 5edc6585aafefa3d44fb8a84adf241d90227f7a3 ]
+
+This switch family supports four LEDs for each of its six ports. Each
+LED group is composed of one of these four LEDs from all six ports. LED
+groups can be configured to display hardware information, such as link
+activity, or manually controlled through a bitmap in registers
+RTL8366RB_LED_0_1_CTRL_REG and RTL8366RB_LED_2_3_CTRL_REG.
+
+After a reset, the default LED group configuration for groups 0 to 3
+indicates, respectively, link activity, link at 1000M, 100M, and 10M, or
+RTL8366RB_LED_CTRL_REG as 0x5432. These configurations are commonly used
+for LED indications. However, the driver was replacing that
+configuration to use manually controlled LEDs (RTL8366RB_LED_FORCE)
+without providing a way for the OS to control them. The default
+configuration is deemed more useful than fixed, uncontrollable turned-on
+LEDs.
+
+The driver was enabling/disabling LEDs during port_enable/disable.
+However, these events occur when the port is administratively controlled
+(up or down) and are not related to link presence. Additionally, when a
+port N was disabled, the driver was turning off all LEDs for group N,
+not only the corresponding LED for port N in any of those 4 groups. In
+such cases, if port 0 was brought down, the LEDs for all ports in LED
+group 0 would be turned off. As another side effect, the driver was
+wrongly warning that port 5 didn't have an LED ("no LED for port 5").
+Since showing the administrative state of ports is not an orthodox way
+to use LEDs, it was not worth it to fix it and all this code was
+dropped.
+
+The code to disable LEDs was simplified only changing each LED group to
+the RTL8366RB_LED_OFF state. Registers RTL8366RB_LED_0_1_CTRL_REG and
+RTL8366RB_LED_2_3_CTRL_REG are only used when the corresponding LED
+group is configured with RTL8366RB_LED_FORCE and they don't need to be
+cleaned. The code still references an LED controlled by
+RTL8366RB_INTERRUPT_CONTROL_REG, but as of now, no test device has
+actually used it. Also, some magic numbers were replaced by macros.
+
+Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/realtek/rtl8366rb.c | 87 +++++++----------------------
+ 1 file changed, 20 insertions(+), 67 deletions(-)
+
+diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c
+index e10ae94cf7711..5ccb1a3a149d8 100644
+--- a/drivers/net/dsa/realtek/rtl8366rb.c
++++ b/drivers/net/dsa/realtek/rtl8366rb.c
+@@ -185,7 +185,12 @@
+ #define RTL8366RB_LED_BLINKRATE_222MS         0x0004
+ #define RTL8366RB_LED_BLINKRATE_446MS         0x0005
++/* LED trigger event for each group */
+ #define RTL8366RB_LED_CTRL_REG                        0x0431
++#define RTL8366RB_LED_CTRL_OFFSET(led_group)  \
++      (4 * (led_group))
++#define RTL8366RB_LED_CTRL_MASK(led_group)    \
++      (0xf << RTL8366RB_LED_CTRL_OFFSET(led_group))
+ #define RTL8366RB_LED_OFF                     0x0
+ #define RTL8366RB_LED_DUP_COL                 0x1
+ #define RTL8366RB_LED_LINK_ACT                        0x2
+@@ -202,6 +207,11 @@
+ #define RTL8366RB_LED_LINK_TX                 0xd
+ #define RTL8366RB_LED_MASTER                  0xe
+ #define RTL8366RB_LED_FORCE                   0xf
++
++/* The RTL8366RB_LED_X_X registers are used to manually set the LED state only
++ * when the corresponding LED group in RTL8366RB_LED_CTRL_REG is
++ * RTL8366RB_LED_FORCE. Otherwise, it is ignored.
++ */
+ #define RTL8366RB_LED_0_1_CTRL_REG            0x0432
+ #define RTL8366RB_LED_1_OFFSET                        6
+ #define RTL8366RB_LED_2_3_CTRL_REG            0x0433
+@@ -1001,28 +1011,20 @@ static int rtl8366rb_setup(struct dsa_switch *ds)
+        */
+       if (priv->leds_disabled) {
+               /* Turn everything off */
+-              regmap_update_bits(priv->map,
+-                                 RTL8366RB_LED_0_1_CTRL_REG,
+-                                 0x0FFF, 0);
+-              regmap_update_bits(priv->map,
+-                                 RTL8366RB_LED_2_3_CTRL_REG,
+-                                 0x0FFF, 0);
+               regmap_update_bits(priv->map,
+                                  RTL8366RB_INTERRUPT_CONTROL_REG,
+                                  RTL8366RB_P4_RGMII_LED,
+                                  0);
+-              val = RTL8366RB_LED_OFF;
+-      } else {
+-              /* TODO: make this configurable per LED */
+-              val = RTL8366RB_LED_FORCE;
+-      }
+-      for (i = 0; i < 4; i++) {
+-              ret = regmap_update_bits(priv->map,
+-                                       RTL8366RB_LED_CTRL_REG,
+-                                       0xf << (i * 4),
+-                                       val << (i * 4));
+-              if (ret)
+-                      return ret;
++
++              for (i = 0; i < RTL8366RB_NUM_LEDGROUPS; i++) {
++                      val = RTL8366RB_LED_OFF << RTL8366RB_LED_CTRL_OFFSET(i);
++                      ret = regmap_update_bits(priv->map,
++                                               RTL8366RB_LED_CTRL_REG,
++                                               RTL8366RB_LED_CTRL_MASK(i),
++                                               val);
++                      if (ret)
++                              return ret;
++              }
+       }
+       ret = rtl8366_reset_vlan(priv);
+@@ -1167,52 +1169,6 @@ rtl8366rb_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode,
+       }
+ }
+-static void rb8366rb_set_port_led(struct realtek_priv *priv,
+-                                int port, bool enable)
+-{
+-      u16 val = enable ? 0x3f : 0;
+-      int ret;
+-
+-      if (priv->leds_disabled)
+-              return;
+-
+-      switch (port) {
+-      case 0:
+-              ret = regmap_update_bits(priv->map,
+-                                       RTL8366RB_LED_0_1_CTRL_REG,
+-                                       0x3F, val);
+-              break;
+-      case 1:
+-              ret = regmap_update_bits(priv->map,
+-                                       RTL8366RB_LED_0_1_CTRL_REG,
+-                                       0x3F << RTL8366RB_LED_1_OFFSET,
+-                                       val << RTL8366RB_LED_1_OFFSET);
+-              break;
+-      case 2:
+-              ret = regmap_update_bits(priv->map,
+-                                       RTL8366RB_LED_2_3_CTRL_REG,
+-                                       0x3F, val);
+-              break;
+-      case 3:
+-              ret = regmap_update_bits(priv->map,
+-                                       RTL8366RB_LED_2_3_CTRL_REG,
+-                                       0x3F << RTL8366RB_LED_3_OFFSET,
+-                                       val << RTL8366RB_LED_3_OFFSET);
+-              break;
+-      case 4:
+-              ret = regmap_update_bits(priv->map,
+-                                       RTL8366RB_INTERRUPT_CONTROL_REG,
+-                                       RTL8366RB_P4_RGMII_LED,
+-                                       enable ? RTL8366RB_P4_RGMII_LED : 0);
+-              break;
+-      default:
+-              dev_err(priv->dev, "no LED for port %d\n", port);
+-              return;
+-      }
+-      if (ret)
+-              dev_err(priv->dev, "error updating LED on port %d\n", port);
+-}
+-
+ static int
+ rtl8366rb_port_enable(struct dsa_switch *ds, int port,
+                     struct phy_device *phy)
+@@ -1226,7 +1182,6 @@ rtl8366rb_port_enable(struct dsa_switch *ds, int port,
+       if (ret)
+               return ret;
+-      rb8366rb_set_port_led(priv, port, true);
+       return 0;
+ }
+@@ -1241,8 +1196,6 @@ rtl8366rb_port_disable(struct dsa_switch *ds, int port)
+                                BIT(port));
+       if (ret)
+               return;
+-
+-      rb8366rb_set_port_led(priv, port, false);
+ }
+ static int
+-- 
+2.43.0
+
diff --git a/queue-6.9/net-ena-add-validation-for-completion-descriptors-co.patch b/queue-6.9/net-ena-add-validation-for-completion-descriptors-co.patch
new file mode 100644 (file)
index 0000000..2c79554
--- /dev/null
@@ -0,0 +1,139 @@
+From c3c21d4d1582b4e05afb311eb65a207fc0ad0036 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 May 2024 13:46:35 +0000
+Subject: net: ena: Add validation for completion descriptors consistency
+
+From: David Arinzon <darinzon@amazon.com>
+
+[ Upstream commit b37b98a3a0c1198bafe8c2d9ce0bc845b4e7a9a7 ]
+
+Validate that `first` flag is set only for the first
+descriptor in multi-buffer packets.
+In case of an invalid descriptor, a reset will occur.
+A new reset reason for RX data corruption has been added.
+
+Signed-off-by: Shahar Itzko <itzko@amazon.com>
+Signed-off-by: David Arinzon <darinzon@amazon.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/20240512134637.25299-4-darinzon@amazon.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/amazon/ena/ena_eth_com.c | 37 ++++++++++++++-----
+ drivers/net/ethernet/amazon/ena/ena_netdev.c  |  2 +
+ .../net/ethernet/amazon/ena/ena_regs_defs.h   |  1 +
+ 3 files changed, 30 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/amazon/ena/ena_eth_com.c b/drivers/net/ethernet/amazon/ena/ena_eth_com.c
+index 933e619b3a313..4c6e07aa4bbb5 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_eth_com.c
++++ b/drivers/net/ethernet/amazon/ena/ena_eth_com.c
+@@ -229,30 +229,43 @@ static struct ena_eth_io_rx_cdesc_base *
+               idx * io_cq->cdesc_entry_size_in_bytes);
+ }
+-static u16 ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq,
+-                                         u16 *first_cdesc_idx)
++static int ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq,
++                                  u16 *first_cdesc_idx,
++                                  u16 *num_descs)
+ {
++      u16 count = io_cq->cur_rx_pkt_cdesc_count, head_masked;
+       struct ena_eth_io_rx_cdesc_base *cdesc;
+-      u16 count = 0, head_masked;
+       u32 last = 0;
+       do {
++              u32 status;
++
+               cdesc = ena_com_get_next_rx_cdesc(io_cq);
+               if (!cdesc)
+                       break;
++              status = READ_ONCE(cdesc->status);
+               ena_com_cq_inc_head(io_cq);
++              if (unlikely((status & ENA_ETH_IO_RX_CDESC_BASE_FIRST_MASK) >>
++                  ENA_ETH_IO_RX_CDESC_BASE_FIRST_SHIFT && count != 0)) {
++                      struct ena_com_dev *dev = ena_com_io_cq_to_ena_dev(io_cq);
++
++                      netdev_err(dev->net_device,
++                                 "First bit is on in descriptor #%d on q_id: %d, req_id: %u\n",
++                                 count, io_cq->qid, cdesc->req_id);
++                      return -EFAULT;
++              }
+               count++;
+-              last = (READ_ONCE(cdesc->status) & ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK) >>
+-                     ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT;
++              last = (status & ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK) >>
++                      ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT;
+       } while (!last);
+       if (last) {
+               *first_cdesc_idx = io_cq->cur_rx_pkt_cdesc_start_idx;
+-              count += io_cq->cur_rx_pkt_cdesc_count;
+               head_masked = io_cq->head & (io_cq->q_depth - 1);
++              *num_descs = count;
+               io_cq->cur_rx_pkt_cdesc_count = 0;
+               io_cq->cur_rx_pkt_cdesc_start_idx = head_masked;
+@@ -260,11 +273,11 @@ static u16 ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq,
+                          "ENA q_id: %d packets were completed. first desc idx %u descs# %d\n",
+                          io_cq->qid, *first_cdesc_idx, count);
+       } else {
+-              io_cq->cur_rx_pkt_cdesc_count += count;
+-              count = 0;
++              io_cq->cur_rx_pkt_cdesc_count = count;
++              *num_descs = 0;
+       }
+-      return count;
++      return 0;
+ }
+ static int ena_com_create_meta(struct ena_com_io_sq *io_sq,
+@@ -539,10 +552,14 @@ int ena_com_rx_pkt(struct ena_com_io_cq *io_cq,
+       u16 cdesc_idx = 0;
+       u16 nb_hw_desc;
+       u16 i = 0;
++      int rc;
+       WARN(io_cq->direction != ENA_COM_IO_QUEUE_DIRECTION_RX, "wrong Q type");
+-      nb_hw_desc = ena_com_cdesc_rx_pkt_get(io_cq, &cdesc_idx);
++      rc = ena_com_cdesc_rx_pkt_get(io_cq, &cdesc_idx, &nb_hw_desc);
++      if (unlikely(rc != 0))
++              return -EFAULT;
++
+       if (nb_hw_desc == 0) {
+               ena_rx_ctx->descs = nb_hw_desc;
+               return 0;
+diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+index be5acfa41ee0c..8db05f7544f90 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -1347,6 +1347,8 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
+       if (rc == -ENOSPC) {
+               ena_increase_stat(&rx_ring->rx_stats.bad_desc_num, 1, &rx_ring->syncp);
+               ena_reset_device(adapter, ENA_REGS_RESET_TOO_MANY_RX_DESCS);
++      } else if (rc == -EFAULT) {
++              ena_reset_device(adapter, ENA_REGS_RESET_RX_DESCRIPTOR_MALFORMED);
+       } else {
+               ena_increase_stat(&rx_ring->rx_stats.bad_req_id, 1,
+                                 &rx_ring->syncp);
+diff --git a/drivers/net/ethernet/amazon/ena/ena_regs_defs.h b/drivers/net/ethernet/amazon/ena/ena_regs_defs.h
+index 2c3d6a77ea79f..a2efebafd686a 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_regs_defs.h
++++ b/drivers/net/ethernet/amazon/ena/ena_regs_defs.h
+@@ -22,6 +22,7 @@ enum ena_regs_reset_reason_types {
+       ENA_REGS_RESET_GENERIC                      = 13,
+       ENA_REGS_RESET_MISS_INTERRUPT               = 14,
+       ENA_REGS_RESET_SUSPECTED_POLL_STARVATION    = 15,
++      ENA_REGS_RESET_RX_DESCRIPTOR_MALFORMED      = 16,
+ };
+ /* ena_registers offsets */
+-- 
+2.43.0
+
diff --git a/queue-6.9/net-sched-fix-false-lockdep-warning-on-qdisc-root-lo.patch b/queue-6.9/net-sched-fix-false-lockdep-warning-on-qdisc-root-lo.patch
new file mode 100644 (file)
index 0000000..a34487d
--- /dev/null
@@ -0,0 +1,192 @@
+From 6d9d6ba46a520909b541a58e38bac96959ae1716 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Apr 2024 15:50:11 +0200
+Subject: net/sched: fix false lockdep warning on qdisc root lock
+
+From: Davide Caratti <dcaratti@redhat.com>
+
+[ Upstream commit af0cb3fa3f9ed258d14abab0152e28a0f9593084 ]
+
+Xiumei and Christoph reported the following lockdep splat, complaining of
+the qdisc root lock being taken twice:
+
+ ============================================
+ WARNING: possible recursive locking detected
+ 6.7.0-rc3+ #598 Not tainted
+ --------------------------------------------
+ swapper/2/0 is trying to acquire lock:
+ ffff888177190110 (&sch->q.lock){+.-.}-{2:2}, at: __dev_queue_xmit+0x1560/0x2e70
+
+ but task is already holding lock:
+ ffff88811995a110 (&sch->q.lock){+.-.}-{2:2}, at: __dev_queue_xmit+0x1560/0x2e70
+
+ other info that might help us debug this:
+  Possible unsafe locking scenario:
+
+        CPU0
+        ----
+   lock(&sch->q.lock);
+   lock(&sch->q.lock);
+
+  *** DEADLOCK ***
+
+  May be due to missing lock nesting notation
+
+ 5 locks held by swapper/2/0:
+  #0: ffff888135a09d98 ((&in_dev->mr_ifc_timer)){+.-.}-{0:0}, at: call_timer_fn+0x11a/0x510
+  #1: ffffffffaaee5260 (rcu_read_lock){....}-{1:2}, at: ip_finish_output2+0x2c0/0x1ed0
+  #2: ffffffffaaee5200 (rcu_read_lock_bh){....}-{1:2}, at: __dev_queue_xmit+0x209/0x2e70
+  #3: ffff88811995a110 (&sch->q.lock){+.-.}-{2:2}, at: __dev_queue_xmit+0x1560/0x2e70
+  #4: ffffffffaaee5200 (rcu_read_lock_bh){....}-{1:2}, at: __dev_queue_xmit+0x209/0x2e70
+
+ stack backtrace:
+ CPU: 2 PID: 0 Comm: swapper/2 Not tainted 6.7.0-rc3+ #598
+ Hardware name: Red Hat KVM, BIOS 1.13.0-2.module+el8.3.0+7353+9de0a3cc 04/01/2014
+ Call Trace:
+  <IRQ>
+  dump_stack_lvl+0x4a/0x80
+  __lock_acquire+0xfdd/0x3150
+  lock_acquire+0x1ca/0x540
+  _raw_spin_lock+0x34/0x80
+  __dev_queue_xmit+0x1560/0x2e70
+  tcf_mirred_act+0x82e/0x1260 [act_mirred]
+  tcf_action_exec+0x161/0x480
+  tcf_classify+0x689/0x1170
+  prio_enqueue+0x316/0x660 [sch_prio]
+  dev_qdisc_enqueue+0x46/0x220
+  __dev_queue_xmit+0x1615/0x2e70
+  ip_finish_output2+0x1218/0x1ed0
+  __ip_finish_output+0x8b3/0x1350
+  ip_output+0x163/0x4e0
+  igmp_ifc_timer_expire+0x44b/0x930
+  call_timer_fn+0x1a2/0x510
+  run_timer_softirq+0x54d/0x11a0
+  __do_softirq+0x1b3/0x88f
+  irq_exit_rcu+0x18f/0x1e0
+  sysvec_apic_timer_interrupt+0x6f/0x90
+  </IRQ>
+
+This happens when TC does a mirred egress redirect from the root qdisc of
+device A to the root qdisc of device B. As long as these two locks aren't
+protecting the same qdisc, they can be acquired in chain: add a per-qdisc
+lockdep key to silence false warnings.
+This dynamic key should safely replace the static key we have in sch_htb:
+it was added to allow enqueueing to the device "direct qdisc" while still
+holding the qdisc root lock.
+
+v2: don't use static keys anymore in HTB direct qdiscs (thanks Eric Dumazet)
+
+CC: Maxim Mikityanskiy <maxim@isovalent.com>
+CC: Xiumei Mu <xmu@redhat.com>
+Reported-by: Christoph Paasch <cpaasch@apple.com>
+Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/451
+Signed-off-by: Davide Caratti <dcaratti@redhat.com>
+Link: https://lore.kernel.org/r/7dc06d6158f72053cf877a82e2a7a5bd23692faa.1713448007.git.dcaratti@redhat.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sch_generic.h |  1 +
+ net/sched/sch_generic.c   |  3 +++
+ net/sched/sch_htb.c       | 22 +++-------------------
+ 3 files changed, 7 insertions(+), 19 deletions(-)
+
+diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
+index 41ca14e81d55f..0014b9ee5e381 100644
+--- a/include/net/sch_generic.h
++++ b/include/net/sch_generic.h
+@@ -128,6 +128,7 @@ struct Qdisc {
+       struct rcu_head         rcu;
+       netdevice_tracker       dev_tracker;
++      struct lock_class_key   root_lock_key;
+       /* private data */
+       long privdata[] ____cacheline_aligned;
+ };
+diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
+index 10b1491d55809..ad43e75c9b701 100644
+--- a/net/sched/sch_generic.c
++++ b/net/sched/sch_generic.c
+@@ -946,7 +946,9 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
+       __skb_queue_head_init(&sch->gso_skb);
+       __skb_queue_head_init(&sch->skb_bad_txq);
+       gnet_stats_basic_sync_init(&sch->bstats);
++      lockdep_register_key(&sch->root_lock_key);
+       spin_lock_init(&sch->q.lock);
++      lockdep_set_class(&sch->q.lock, &sch->root_lock_key);
+       if (ops->static_flags & TCQ_F_CPUSTATS) {
+               sch->cpu_bstats =
+@@ -1069,6 +1071,7 @@ static void __qdisc_destroy(struct Qdisc *qdisc)
+       if (ops->destroy)
+               ops->destroy(qdisc);
++      lockdep_unregister_key(&qdisc->root_lock_key);
+       module_put(ops->owner);
+       netdev_put(dev, &qdisc->dev_tracker);
+diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
+index 93e6fb56f3b58..ff3de37874e4b 100644
+--- a/net/sched/sch_htb.c
++++ b/net/sched/sch_htb.c
+@@ -1039,13 +1039,6 @@ static void htb_work_func(struct work_struct *work)
+       rcu_read_unlock();
+ }
+-static void htb_set_lockdep_class_child(struct Qdisc *q)
+-{
+-      static struct lock_class_key child_key;
+-
+-      lockdep_set_class(qdisc_lock(q), &child_key);
+-}
+-
+ static int htb_offload(struct net_device *dev, struct tc_htb_qopt_offload *opt)
+ {
+       return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_HTB, opt);
+@@ -1132,7 +1125,6 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt,
+                       return -ENOMEM;
+               }
+-              htb_set_lockdep_class_child(qdisc);
+               q->direct_qdiscs[ntx] = qdisc;
+               qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
+       }
+@@ -1468,7 +1460,6 @@ static int htb_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
+       }
+       if (q->offload) {
+-              htb_set_lockdep_class_child(new);
+               /* One ref for cl->leaf.q, the other for dev_queue->qdisc. */
+               qdisc_refcount_inc(new);
+               old_q = htb_graft_helper(dev_queue, new);
+@@ -1733,11 +1724,8 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg,
+               new_q = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops,
+                                         cl->parent->common.classid,
+                                         NULL);
+-              if (q->offload) {
+-                      if (new_q)
+-                              htb_set_lockdep_class_child(new_q);
++              if (q->offload)
+                       htb_parent_to_leaf_offload(sch, dev_queue, new_q);
+-              }
+       }
+       sch_tree_lock(sch);
+@@ -1947,13 +1935,9 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
+               new_q = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops,
+                                         classid, NULL);
+               if (q->offload) {
+-                      if (new_q) {
+-                              htb_set_lockdep_class_child(new_q);
+-                              /* One ref for cl->leaf.q, the other for
+-                               * dev_queue->qdisc.
+-                               */
++                      /* One ref for cl->leaf.q, the other for dev_queue->qdisc. */
++                      if (new_q)
+                               qdisc_refcount_inc(new_q);
+-                      }
+                       old_q = htb_graft_helper(dev_queue, new_q);
+                       /* No qdisc_put needed. */
+                       WARN_ON(!(old_q->flags & TCQ_F_BUILTIN));
+-- 
+2.43.0
+
diff --git a/queue-6.9/net-sfp-add-quirk-for-ats-sfp-ge-t-1000base-tx-modul.patch b/queue-6.9/net-sfp-add-quirk-for-ats-sfp-ge-t-1000base-tx-modul.patch
new file mode 100644 (file)
index 0000000..e2e9916
--- /dev/null
@@ -0,0 +1,45 @@
+From 4fb9531c6226aab7b27ebc29db59404ffda28ca0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Apr 2024 11:00:25 +0200
+Subject: net: sfp: add quirk for ATS SFP-GE-T 1000Base-TX module
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Daniel Golle <daniel@makrotopia.org>
+
+[ Upstream commit 0805d67bc0ef95411228e802f31975cfb7555056 ]
+
+Add quirk for ATS SFP-GE-T 1000Base-TX module.
+
+This copper module comes with broken TX_FAULT indicator which must be
+ignored for it to work.
+
+Co-authored-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+[ rebased on top of net-next ]
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Link: https://lore.kernel.org/r/20240423090025.29231-1-kabel@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/sfp.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
+index 6e42d4034b520..52b71c7e78351 100644
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -508,6 +508,9 @@ static const struct sfp_quirk sfp_quirks[] = {
+       SFP_QUIRK_F("Walsun", "HXSX-ATRC-1", sfp_fixup_fs_10gt),
+       SFP_QUIRK_F("Walsun", "HXSX-ATRI-1", sfp_fixup_fs_10gt),
++      // OEM SFP-GE-T is a 1000Base-T module with broken TX_FAULT indicator
++      SFP_QUIRK_F("OEM", "SFP-GE-T", sfp_fixup_ignore_tx_fault),
++
+       SFP_QUIRK_F("OEM", "SFP-10G-T", sfp_fixup_rollball_cc),
+       SFP_QUIRK_M("OEM", "SFP-2.5G-T", sfp_quirk_oem_2_5g),
+       SFP_QUIRK_F("OEM", "RTSFP-10", sfp_fixup_rollball_cc),
+-- 
+2.43.0
+
diff --git a/queue-6.9/net-sfp-enhance-quirk-for-fibrestore-2.5g-copper-sfp.patch b/queue-6.9/net-sfp-enhance-quirk-for-fibrestore-2.5g-copper-sfp.patch
new file mode 100644 (file)
index 0000000..540f1e3
--- /dev/null
@@ -0,0 +1,87 @@
+From 4249b1207e83a4e6c502424c616edf36d8786f3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Apr 2024 10:50:39 +0200
+Subject: net: sfp: enhance quirk for Fibrestore 2.5G copper SFP module
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marek Behún <kabel@kernel.org>
+
+[ Upstream commit cd4a32e60061789676f7f018a94fcc9ec56732a0 ]
+
+Enhance the quirk for Fibrestore 2.5G copper SFP module. The original
+commit e27aca3760c0 ("net: sfp: add quirk for FS's 2.5G copper SFP")
+introducing the quirk says that the PHY is inaccessible, but that is
+not true.
+
+The module uses Rollball protocol to talk to the PHY, and needs a 4
+second wait before probing it, same as FS 10G module.
+
+The PHY inside the module is Realtek RTL8221B-VB-CG PHY. The realtek
+driver recently gained support to set it up via clause 45 accesses.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Link: https://lore.kernel.org/r/20240423085039.26957-2-kabel@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/sfp.c | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
+index d999d9baadb26..6e42d4034b520 100644
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -385,18 +385,23 @@ static void sfp_fixup_rollball(struct sfp *sfp)
+       sfp->phy_t_retry = msecs_to_jiffies(1000);
+ }
+-static void sfp_fixup_fs_10gt(struct sfp *sfp)
++static void sfp_fixup_fs_2_5gt(struct sfp *sfp)
+ {
+-      sfp_fixup_10gbaset_30m(sfp);
+       sfp_fixup_rollball(sfp);
+-      /* The RollBall fixup is not enough for FS modules, the AQR chip inside
++      /* The RollBall fixup is not enough for FS modules, the PHY chip inside
+        * them does not return 0xffff for PHY ID registers in all MMDs for the
+        * while initializing. They need a 4 second wait before accessing PHY.
+        */
+       sfp->module_t_wait = msecs_to_jiffies(4000);
+ }
++static void sfp_fixup_fs_10gt(struct sfp *sfp)
++{
++      sfp_fixup_10gbaset_30m(sfp);
++      sfp_fixup_fs_2_5gt(sfp);
++}
++
+ static void sfp_fixup_halny_gsfp(struct sfp *sfp)
+ {
+       /* Ignore the TX_FAULT and LOS signals on this module.
+@@ -472,6 +477,10 @@ static const struct sfp_quirk sfp_quirks[] = {
+       // Rollball protocol to talk to the PHY.
+       SFP_QUIRK_F("FS", "SFP-10G-T", sfp_fixup_fs_10gt),
++      // Fiberstore SFP-2.5G-T uses Rollball protocol to talk to the PHY and
++      // needs 4 sec wait before probing the PHY.
++      SFP_QUIRK_F("FS", "SFP-2.5G-T", sfp_fixup_fs_2_5gt),
++
+       // Fiberstore GPON-ONU-34-20BI can operate at 2500base-X, but report 1.2GBd
+       // NRZ in their EEPROM
+       SFP_QUIRK("FS", "GPON-ONU-34-20BI", sfp_quirk_2500basex,
+@@ -488,9 +497,6 @@ static const struct sfp_quirk sfp_quirks[] = {
+       SFP_QUIRK("HUAWEI", "MA5671A", sfp_quirk_2500basex,
+                 sfp_fixup_ignore_tx_fault),
+-      // FS 2.5G Base-T
+-      SFP_QUIRK_M("FS", "SFP-2.5G-T", sfp_quirk_oem_2_5g),
+-
+       // Lantech 8330-262D-E can operate at 2500base-X, but incorrectly report
+       // 2500MBd NRZ in their EEPROM
+       SFP_QUIRK_M("Lantech", "8330-262D-E", sfp_quirk_2500basex),
+-- 
+2.43.0
+
diff --git a/queue-6.9/netpoll-fix-race-condition-in-netpoll_owner_active.patch b/queue-6.9/netpoll-fix-race-condition-in-netpoll_owner_active.patch
new file mode 100644 (file)
index 0000000..0b271fe
--- /dev/null
@@ -0,0 +1,52 @@
+From 012fdd51663039743b7f249e659915221150919e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Apr 2024 03:04:33 -0700
+Subject: netpoll: Fix race condition in netpoll_owner_active
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit c2e6a872bde9912f1a7579639c5ca3adf1003916 ]
+
+KCSAN detected a race condition in netpoll:
+
+       BUG: KCSAN: data-race in net_rx_action / netpoll_send_skb
+       write (marked) to 0xffff8881164168b0 of 4 bytes by interrupt on cpu 10:
+       net_rx_action (./include/linux/netpoll.h:90 net/core/dev.c:6712 net/core/dev.c:6822)
+<snip>
+       read to 0xffff8881164168b0 of 4 bytes by task 1 on cpu 2:
+       netpoll_send_skb (net/core/netpoll.c:319 net/core/netpoll.c:345 net/core/netpoll.c:393)
+       netpoll_send_udp (net/core/netpoll.c:?)
+<snip>
+       value changed: 0x0000000a -> 0xffffffff
+
+This happens because netpoll_owner_active() needs to check if the
+current CPU is the owner of the lock, touching napi->poll_owner
+non atomically. The ->poll_owner field contains the current CPU holding
+the lock.
+
+Use an atomic read to check if the poll owner is the current CPU.
+
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Link: https://lore.kernel.org/r/20240429100437.3487432-1-leitao@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/netpoll.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/core/netpoll.c b/net/core/netpoll.c
+index 543007f159f99..55bcacf67df3b 100644
+--- a/net/core/netpoll.c
++++ b/net/core/netpoll.c
+@@ -316,7 +316,7 @@ static int netpoll_owner_active(struct net_device *dev)
+       struct napi_struct *napi;
+       list_for_each_entry_rcu(napi, &dev->napi_list, dev_list) {
+-              if (napi->poll_owner == smp_processor_id())
++              if (READ_ONCE(napi->poll_owner) == smp_processor_id())
+                       return 1;
+       }
+       return 0;
+-- 
+2.43.0
+
diff --git a/queue-6.9/opp-fix-required_opp_tables-for-multiple-genpds-usin.patch b/queue-6.9/opp-fix-required_opp_tables-for-multiple-genpds-usin.patch
new file mode 100644 (file)
index 0000000..d1c66ed
--- /dev/null
@@ -0,0 +1,140 @@
+From 082bfb0917ea0d0d962442767ef6ef7f1da5dfa1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Apr 2024 15:53:58 +0530
+Subject: OPP: Fix required_opp_tables for multiple genpds using same table
+
+From: Viresh Kumar <viresh.kumar@linaro.org>
+
+[ Upstream commit 2a56c462fe5a2ee61d38e2d7b772bee56115a00c ]
+
+The required_opp_tables parsing is not perfect, as the OPP core does the
+parsing solely based on the DT node pointers.
+
+The core sets the required_opp_tables entry to the first OPP table in
+the "opp_tables" list, that matches with the node pointer.
+
+If the target DT OPP table is used by multiple devices and they all
+create separate instances of 'struct opp_table' from it, then it is
+possible that the required_opp_tables entry may be set to the incorrect
+sibling device.
+
+Unfortunately, there is no clear way to initialize the right values
+during the initial parsing and we need to do this at a later point of
+time.
+
+Cross check the OPP table again while the genpds are attached and fix
+them if required.
+
+Also add a new API for the genpd core to fetch the device pointer for
+the genpd.
+
+Cc: Thorsten Leemhuis <regressions@leemhuis.info>
+Reported-by: Vladimir Lypak <vladimir.lypak@gmail.com>
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218682
+Co-developed-by: Vladimir Lypak <vladimir.lypak@gmail.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/opp/core.c        | 31 ++++++++++++++++++++++++++++++-
+ drivers/pmdomain/core.c   | 10 ++++++++++
+ include/linux/pm_domain.h |  6 ++++++
+ 3 files changed, 46 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/opp/core.c b/drivers/opp/core.c
+index e233734b72205..cb4611fe1b5b2 100644
+--- a/drivers/opp/core.c
++++ b/drivers/opp/core.c
+@@ -2394,7 +2394,8 @@ static void _opp_detach_genpd(struct opp_table *opp_table)
+ static int _opp_attach_genpd(struct opp_table *opp_table, struct device *dev,
+                       const char * const *names, struct device ***virt_devs)
+ {
+-      struct device *virt_dev;
++      struct device *virt_dev, *gdev;
++      struct opp_table *genpd_table;
+       int index = 0, ret = -EINVAL;
+       const char * const *name = names;
+@@ -2427,6 +2428,34 @@ static int _opp_attach_genpd(struct opp_table *opp_table, struct device *dev,
+                       goto err;
+               }
++              /*
++               * The required_opp_tables parsing is not perfect, as the OPP
++               * core does the parsing solely based on the DT node pointers.
++               * The core sets the required_opp_tables entry to the first OPP
++               * table in the "opp_tables" list, that matches with the node
++               * pointer.
++               *
++               * If the target DT OPP table is used by multiple devices and
++               * they all create separate instances of 'struct opp_table' from
++               * it, then it is possible that the required_opp_tables entry
++               * may be set to the incorrect sibling device.
++               *
++               * Cross check it again and fix if required.
++               */
++              gdev = dev_to_genpd_dev(virt_dev);
++              if (IS_ERR(gdev))
++                      return PTR_ERR(gdev);
++
++              genpd_table = _find_opp_table(gdev);
++              if (!IS_ERR(genpd_table)) {
++                      if (genpd_table != opp_table->required_opp_tables[index]) {
++                              dev_pm_opp_put_opp_table(opp_table->required_opp_tables[index]);
++                              opp_table->required_opp_tables[index] = genpd_table;
++                      } else {
++                              dev_pm_opp_put_opp_table(genpd_table);
++                      }
++              }
++
+               /*
+                * Add the virtual genpd device as a user of the OPP table, so
+                * we can call dev_pm_opp_set_opp() on it directly.
+diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
+index 4215ffd9b11c5..c40eda92a85a7 100644
+--- a/drivers/pmdomain/core.c
++++ b/drivers/pmdomain/core.c
+@@ -184,6 +184,16 @@ static struct generic_pm_domain *dev_to_genpd(struct device *dev)
+       return pd_to_genpd(dev->pm_domain);
+ }
++struct device *dev_to_genpd_dev(struct device *dev)
++{
++      struct generic_pm_domain *genpd = dev_to_genpd(dev);
++
++      if (IS_ERR(genpd))
++              return ERR_CAST(genpd);
++
++      return &genpd->dev;
++}
++
+ static int genpd_stop_dev(const struct generic_pm_domain *genpd,
+                         struct device *dev)
+ {
+diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
+index 772d3280d35fa..f24546a3d3db3 100644
+--- a/include/linux/pm_domain.h
++++ b/include/linux/pm_domain.h
+@@ -260,6 +260,7 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
+ int pm_genpd_init(struct generic_pm_domain *genpd,
+                 struct dev_power_governor *gov, bool is_off);
+ int pm_genpd_remove(struct generic_pm_domain *genpd);
++struct device *dev_to_genpd_dev(struct device *dev);
+ int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state);
+ int dev_pm_genpd_add_notifier(struct device *dev, struct notifier_block *nb);
+ int dev_pm_genpd_remove_notifier(struct device *dev);
+@@ -307,6 +308,11 @@ static inline int pm_genpd_remove(struct generic_pm_domain *genpd)
+       return -EOPNOTSUPP;
+ }
++static inline struct device *dev_to_genpd_dev(struct device *dev)
++{
++      return ERR_PTR(-EOPNOTSUPP);
++}
++
+ static inline int dev_pm_genpd_set_performance_state(struct device *dev,
+                                                    unsigned int state)
+ {
+-- 
+2.43.0
+
diff --git a/queue-6.9/padata-disable-bh-when-taking-works-lock-on-mt-path.patch b/queue-6.9/padata-disable-bh-when-taking-works-lock-on-mt-path.patch
new file mode 100644 (file)
index 0000000..15e089b
--- /dev/null
@@ -0,0 +1,62 @@
+From 244ea3a2bc70e57915195bb3947503f0eca4a3e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Apr 2024 17:36:18 +0800
+Subject: padata: Disable BH when taking works lock on MT path
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit 58329c4312031603bb1786b44265c26d5065fe72 ]
+
+As the old padata code can execute in softirq context, disable
+softirqs for the new padata_do_mutithreaded code too as otherwise
+lockdep will get antsy.
+
+Reported-by: syzbot+0cb5bb0f4bf9e79db3b3@syzkaller.appspotmail.com
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Acked-by: Daniel Jordan <daniel.m.jordan@oracle.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/padata.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/kernel/padata.c b/kernel/padata.c
+index e3f639ff16707..53f4bc9127127 100644
+--- a/kernel/padata.c
++++ b/kernel/padata.c
+@@ -106,7 +106,7 @@ static int __init padata_work_alloc_mt(int nworks, void *data,
+ {
+       int i;
+-      spin_lock(&padata_works_lock);
++      spin_lock_bh(&padata_works_lock);
+       /* Start at 1 because the current task participates in the job. */
+       for (i = 1; i < nworks; ++i) {
+               struct padata_work *pw = padata_work_alloc();
+@@ -116,7 +116,7 @@ static int __init padata_work_alloc_mt(int nworks, void *data,
+               padata_work_init(pw, padata_mt_helper, data, 0);
+               list_add(&pw->pw_list, head);
+       }
+-      spin_unlock(&padata_works_lock);
++      spin_unlock_bh(&padata_works_lock);
+       return i;
+ }
+@@ -134,12 +134,12 @@ static void __init padata_works_free(struct list_head *works)
+       if (list_empty(works))
+               return;
+-      spin_lock(&padata_works_lock);
++      spin_lock_bh(&padata_works_lock);
+       list_for_each_entry_safe(cur, next, works, pw_list) {
+               list_del(&cur->pw_list);
+               padata_work_free(cur);
+       }
+-      spin_unlock(&padata_works_lock);
++      spin_unlock_bh(&padata_works_lock);
+ }
+ static void padata_parallel_worker(struct work_struct *parallel_work)
+-- 
+2.43.0
+
diff --git a/queue-6.9/pci-do-not-wait-for-disconnected-devices-when-resumi.patch b/queue-6.9/pci-do-not-wait-for-disconnected-devices-when-resumi.patch
new file mode 100644 (file)
index 0000000..5d63d92
--- /dev/null
@@ -0,0 +1,93 @@
+From f173be21e0a998da319361a4ae8338efde810f95 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Feb 2024 15:23:21 +0200
+Subject: PCI: Do not wait for disconnected devices when resuming
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 6613443ffc49d03e27f0404978f685c4eac43fba ]
+
+On runtime resume, pci_dev_wait() is called:
+
+  pci_pm_runtime_resume()
+    pci_pm_bridge_power_up_actions()
+      pci_bridge_wait_for_secondary_bus()
+        pci_dev_wait()
+
+While a device is runtime suspended along with its PCI hierarchy, the
+device could get disconnected. In such case, the link will not come up no
+matter how long pci_dev_wait() waits for it.
+
+Besides the above mentioned case, there could be other ways to get the
+device disconnected while pci_dev_wait() is waiting for the link to come
+up.
+
+Make pci_dev_wait() exit if the device is already disconnected to avoid
+unnecessary delay.
+
+The use cases of pci_dev_wait() boil down to two:
+
+  1. Waiting for the device after reset
+  2. pci_bridge_wait_for_secondary_bus()
+
+The callers in both cases seem to benefit from propagating the
+disconnection as error even if device disconnection would be more
+analoguous to the case where there is no device in the first place which
+return 0 from pci_dev_wait(). In the case 2, it results in unnecessary
+marking of the devices disconnected again but that is just harmless extra
+work.
+
+Also make sure compiler does not become too clever with dev->error_state
+and use READ_ONCE() to force a fetch for the up-to-date value.
+
+Link: https://lore.kernel.org/r/20240208132322.4811-1-ilpo.jarvinen@linux.intel.com
+Reported-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci.c   | 5 +++++
+ include/linux/pci.h | 7 ++++++-
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index e4bb5f92a5f6e..cbbf197df80f1 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -1277,6 +1277,11 @@ static int pci_dev_wait(struct pci_dev *dev, char *reset_type, int timeout)
+       for (;;) {
+               u32 id;
++              if (pci_dev_is_disconnected(dev)) {
++                      pci_dbg(dev, "disconnected; not waiting\n");
++                      return -ENOTTY;
++              }
++
+               pci_read_config_dword(dev, PCI_COMMAND, &id);
+               if (!PCI_POSSIBLE_ERROR(id))
+                       break;
+diff --git a/include/linux/pci.h b/include/linux/pci.h
+index 16493426a04ff..6f9c5ed5eb3ba 100644
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -2519,7 +2519,12 @@ static inline struct pci_dev *pcie_find_root_port(struct pci_dev *dev)
+ static inline bool pci_dev_is_disconnected(const struct pci_dev *dev)
+ {
+-      return dev->error_state == pci_channel_io_perm_failure;
++      /*
++       * error_state is set in pci_dev_set_io_state() using xchg/cmpxchg()
++       * and read w/o common lock. READ_ONCE() ensures compiler cannot cache
++       * the value (e.g. inside the loop in pci_dev_wait()).
++       */
++      return READ_ONCE(dev->error_state) == pci_channel_io_perm_failure;
+ }
+ void pci_request_acs(void);
+-- 
+2.43.0
+
diff --git a/queue-6.9/pci-pm-avoid-d3cold-for-hp-pavilion-17-pc-1972-pcie-.patch b/queue-6.9/pci-pm-avoid-d3cold-for-hp-pavilion-17-pc-1972-pcie-.patch
new file mode 100644 (file)
index 0000000..33e9e7d
--- /dev/null
@@ -0,0 +1,71 @@
+From 583d4fcc031bf7cd4de430acf8287cdbb8bff244 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 10:37:09 -0600
+Subject: PCI/PM: Avoid D3cold for HP Pavilion 17 PC/1972 PCIe Ports
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit 256df20c590bf0e4d63ac69330cf23faddac3e08 ]
+
+Hewlett-Packard HP Pavilion 17 Notebook PC/1972 is an Intel Ivy Bridge
+system with a muxless AMD Radeon dGPU.  Attempting to use the dGPU fails
+with the following sequence:
+
+  ACPI Error: Aborting method \AMD3._ON due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/psparse-529)
+  radeon 0000:01:00.0: not ready 1023ms after resume; waiting
+  radeon 0000:01:00.0: not ready 2047ms after resume; waiting
+  radeon 0000:01:00.0: not ready 4095ms after resume; waiting
+  radeon 0000:01:00.0: not ready 8191ms after resume; waiting
+  radeon 0000:01:00.0: not ready 16383ms after resume; waiting
+  radeon 0000:01:00.0: not ready 32767ms after resume; waiting
+  radeon 0000:01:00.0: not ready 65535ms after resume; giving up
+  radeon 0000:01:00.0: Unable to change power state from D3cold to D0, device inaccessible
+
+The issue is that the Root Port the dGPU is connected to can't handle the
+transition from D3cold to D0 so the dGPU can't properly exit runtime PM.
+
+The existing logic in pci_bridge_d3_possible() checks for systems that are
+newer than 2015 to decide that D3 is safe.  This would nominally work for
+an Ivy Bridge system (which was discontinued in 2015), but this system
+appears to have continued to receive BIOS updates until 2017 and so this
+existing logic doesn't appropriately capture it.
+
+Add the system to bridge_d3_blacklist to prevent D3cold from being used.
+
+Link: https://lore.kernel.org/r/20240307163709.323-1-mario.limonciello@amd.com
+Reported-by: Eric Heintzmann <heintzmann.eric@free.fr>
+Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3229
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Eric Heintzmann <heintzmann.eric@free.fr>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index 70b8c87055cb6..e4bb5f92a5f6e 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -2962,6 +2962,18 @@ static const struct dmi_system_id bridge_d3_blacklist[] = {
+                       DMI_MATCH(DMI_BOARD_VERSION, "Continental Z2"),
+               },
+       },
++      {
++              /*
++               * Changing power state of root port dGPU is connected fails
++               * https://gitlab.freedesktop.org/drm/amd/-/issues/3229
++               */
++              .ident = "Hewlett-Packard HP Pavilion 17 Notebook PC/1972",
++              .matches = {
++                      DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
++                      DMI_MATCH(DMI_BOARD_NAME, "1972"),
++                      DMI_MATCH(DMI_BOARD_VERSION, "95.33"),
++              },
++      },
+ #endif
+       { }
+ };
+-- 
+2.43.0
+
diff --git a/queue-6.9/platform-chrome-cros_usbpd_logger-provide-id-table-f.patch b/queue-6.9/platform-chrome-cros_usbpd_logger-provide-id-table-f.patch
new file mode 100644 (file)
index 0000000..0c422e9
--- /dev/null
@@ -0,0 +1,64 @@
+From 681203ef3664967131594b65c9157ba649da38f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Mar 2024 15:56:18 +0800
+Subject: platform/chrome: cros_usbpd_logger: provide ID table for avoiding
+ fallback match
+
+From: Tzung-Bi Shih <tzungbi@kernel.org>
+
+[ Upstream commit e0e59c5335a0a038058a080474c34fe04debff33 ]
+
+Instead of using fallback driver name match, provide ID table[1] for the
+primary match.
+
+[1]: https://elixir.bootlin.com/linux/v6.8/source/drivers/base/platform.c#L1353
+
+Reviewed-by: Benson Leung <bleung@chromium.org>
+Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
+Link: https://lore.kernel.org/r/20240329075630.2069474-7-tzungbi@kernel.org
+Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/chrome/cros_usbpd_logger.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/platform/chrome/cros_usbpd_logger.c b/drivers/platform/chrome/cros_usbpd_logger.c
+index f618757f8b321..930c2f47269f6 100644
+--- a/drivers/platform/chrome/cros_usbpd_logger.c
++++ b/drivers/platform/chrome/cros_usbpd_logger.c
+@@ -7,6 +7,7 @@
+ #include <linux/ktime.h>
+ #include <linux/math64.h>
++#include <linux/mod_devicetable.h>
+ #include <linux/module.h>
+ #include <linux/platform_data/cros_ec_commands.h>
+ #include <linux/platform_data/cros_ec_proto.h>
+@@ -249,6 +250,12 @@ static int __maybe_unused cros_usbpd_logger_suspend(struct device *dev)
+ static SIMPLE_DEV_PM_OPS(cros_usbpd_logger_pm_ops, cros_usbpd_logger_suspend,
+                        cros_usbpd_logger_resume);
++static const struct platform_device_id cros_usbpd_logger_id[] = {
++      { DRV_NAME, 0 },
++      {}
++};
++MODULE_DEVICE_TABLE(platform, cros_usbpd_logger_id);
++
+ static struct platform_driver cros_usbpd_logger_driver = {
+       .driver = {
+               .name = DRV_NAME,
+@@ -256,10 +263,10 @@ static struct platform_driver cros_usbpd_logger_driver = {
+       },
+       .probe = cros_usbpd_logger_probe,
+       .remove_new = cros_usbpd_logger_remove,
++      .id_table = cros_usbpd_logger_id,
+ };
+ module_platform_driver(cros_usbpd_logger_driver);
+ MODULE_LICENSE("GPL v2");
+ MODULE_DESCRIPTION("Logging driver for ChromeOS EC USBPD Charger.");
+-MODULE_ALIAS("platform:" DRV_NAME);
+-- 
+2.43.0
+
diff --git a/queue-6.9/platform-chrome-cros_usbpd_notify-provide-id-table-f.patch b/queue-6.9/platform-chrome-cros_usbpd_notify-provide-id-table-f.patch
new file mode 100644 (file)
index 0000000..c46ff2a
--- /dev/null
@@ -0,0 +1,65 @@
+From 273920d9730c1a157a4f607eb3927b329cc10171 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Mar 2024 15:56:19 +0800
+Subject: platform/chrome: cros_usbpd_notify: provide ID table for avoiding
+ fallback match
+
+From: Tzung-Bi Shih <tzungbi@kernel.org>
+
+[ Upstream commit 8ad3b9652ed6a115c56214a0eab06952818b3ddf ]
+
+Instead of using fallback driver name match, provide ID table[1] for the
+primary match.
+
+[1]: https://elixir.bootlin.com/linux/v6.8/source/drivers/base/platform.c#L1353
+
+Reviewed-by: Benson Leung <bleung@chromium.org>
+Acked-by: Prashant Malani <pmalani@chromium.org>
+Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
+Link: https://lore.kernel.org/r/20240329075630.2069474-8-tzungbi@kernel.org
+Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/chrome/cros_usbpd_notify.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/platform/chrome/cros_usbpd_notify.c b/drivers/platform/chrome/cros_usbpd_notify.c
+index aacad022f21df..c83f81d86483c 100644
+--- a/drivers/platform/chrome/cros_usbpd_notify.c
++++ b/drivers/platform/chrome/cros_usbpd_notify.c
+@@ -6,6 +6,7 @@
+  */
+ #include <linux/acpi.h>
++#include <linux/mod_devicetable.h>
+ #include <linux/module.h>
+ #include <linux/platform_data/cros_ec_proto.h>
+ #include <linux/platform_data/cros_usbpd_notify.h>
+@@ -218,12 +219,19 @@ static void cros_usbpd_notify_remove_plat(struct platform_device *pdev)
+                                          &pdnotify->nb);
+ }
++static const struct platform_device_id cros_usbpd_notify_id[] = {
++      { DRV_NAME, 0 },
++      {}
++};
++MODULE_DEVICE_TABLE(platform, cros_usbpd_notify_id);
++
+ static struct platform_driver cros_usbpd_notify_plat_driver = {
+       .driver = {
+               .name = DRV_NAME,
+       },
+       .probe = cros_usbpd_notify_probe_plat,
+       .remove_new = cros_usbpd_notify_remove_plat,
++      .id_table = cros_usbpd_notify_id,
+ };
+ static int __init cros_usbpd_notify_init(void)
+@@ -258,4 +266,3 @@ module_exit(cros_usbpd_notify_exit);
+ MODULE_LICENSE("GPL");
+ MODULE_DESCRIPTION("ChromeOS power delivery notifier device");
+ MODULE_AUTHOR("Jon Flatley <jflat@chromium.org>");
+-MODULE_ALIAS("platform:" DRV_NAME);
+-- 
+2.43.0
+
diff --git a/queue-6.9/platform-x86-p2sb-don-t-init-until-unassigned-resour.patch b/queue-6.9/platform-x86-p2sb-don-t-init-until-unassigned-resour.patch
new file mode 100644 (file)
index 0000000..2a60380
--- /dev/null
@@ -0,0 +1,86 @@
+From 788a77e7341398be0876236a94d8a31250b96700 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 May 2024 16:49:34 +0000
+Subject: platform/x86: p2sb: Don't init until unassigned resources have been
+ assigned
+
+From: Ben Fradella <bfradell@netapp.com>
+
+[ Upstream commit 2c6370e6607663fc5fa0fd9ed58e2e01014898c7 ]
+
+The P2SB could get an invalid BAR from the BIOS, and that won't be fixed
+up until pcibios_assign_resources(), which is an fs_initcall().
+
+- Move p2sb_fs_init() to an fs_initcall_sync(). This is still early
+  enough to avoid a race with any dependent drivers.
+
+- Add a check for IORESOURCE_UNSET in p2sb_valid_resource() to catch
+  unset BARs going forward.
+
+- Return error values from p2sb_fs_init() so that the 'initcall_debug'
+  cmdline arg provides useful data.
+
+Signed-off-by: Ben Fradella <bfradell@netapp.com>
+Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Tested-by: Klara Modin <klarasmodin@gmail.com>
+Reviewed-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Link: https://lore.kernel.org/r/20240509164905.41016-1-bcfradella@proton.me
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/p2sb.c | 29 +++++++++++++++--------------
+ 1 file changed, 15 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/platform/x86/p2sb.c b/drivers/platform/x86/p2sb.c
+index 3d66e1d4eb1f5..1ac30034f3e59 100644
+--- a/drivers/platform/x86/p2sb.c
++++ b/drivers/platform/x86/p2sb.c
+@@ -56,12 +56,9 @@ static int p2sb_get_devfn(unsigned int *devfn)
+       return 0;
+ }
+-static bool p2sb_valid_resource(struct resource *res)
++static bool p2sb_valid_resource(const struct resource *res)
+ {
+-      if (res->flags)
+-              return true;
+-
+-      return false;
++      return res->flags & ~IORESOURCE_UNSET;
+ }
+ /* Copy resource from the first BAR of the device in question */
+@@ -220,16 +217,20 @@ EXPORT_SYMBOL_GPL(p2sb_bar);
+ static int __init p2sb_fs_init(void)
+ {
+-      p2sb_cache_resources();
+-      return 0;
++      return p2sb_cache_resources();
+ }
+ /*
+- * pci_rescan_remove_lock to avoid access to unhidden P2SB devices can
+- * not be locked in sysfs pci bus rescan path because of deadlock. To
+- * avoid the deadlock, access to P2SB devices with the lock at an early
+- * step in kernel initialization and cache required resources. This
+- * should happen after subsys_initcall which initializes PCI subsystem
+- * and before device_initcall which requires P2SB resources.
++ * pci_rescan_remove_lock() can not be locked in sysfs PCI bus rescan path
++ * because of deadlock. To avoid the deadlock, access P2SB devices with the lock
++ * at an early step in kernel initialization and cache required resources.
++ *
++ * We want to run as early as possible. If the P2SB was assigned a bad BAR,
++ * we'll need to wait on pcibios_assign_resources() to fix it. So, our list of
++ * initcall dependencies looks something like this:
++ *
++ * ...
++ * subsys_initcall (pci_subsys_init)
++ * fs_initcall     (pcibios_assign_resources)
+  */
+-fs_initcall(p2sb_fs_init);
++fs_initcall_sync(p2sb_fs_init);
+-- 
+2.43.0
+
diff --git a/queue-6.9/platform-x86-toshiba_acpi-add-quirk-for-buttons-on-z.patch b/queue-6.9/platform-x86-toshiba_acpi-add-quirk-for-buttons-on-z.patch
new file mode 100644 (file)
index 0000000..4415d2f
--- /dev/null
@@ -0,0 +1,138 @@
+From cbdf5f119f5608a462c0c92a9339a207eb9ad602 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jan 2024 12:16:41 +0100
+Subject: platform/x86: toshiba_acpi: Add quirk for buttons on Z830
+
+From: Arvid Norlander <lkml@vorpal.se>
+
+[ Upstream commit 23f1d8b47d125dcd8c1ec62a91164e6bc5d691d0 ]
+
+The Z830 has some buttons that will only work properly as "quickstart"
+buttons. To enable them in that mode, a value between 1 and 7 must be
+used for HCI_HOTKEY_EVENT. Windows uses 0x5 on this laptop so use that for
+maximum predictability and compatibility.
+
+As there is not yet a known way of auto detection, this patch uses a DMI
+quirk table. A module parameter is exposed to allow setting this on other
+models for testing.
+
+Signed-off-by: Arvid Norlander <lkml@vorpal.se>
+Tested-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20240131111641.4418-3-W_Armin@gmx.de
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/toshiba_acpi.c | 36 ++++++++++++++++++++++++++---
+ 1 file changed, 33 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
+index 77244c9aa60d2..16e941449b144 100644
+--- a/drivers/platform/x86/toshiba_acpi.c
++++ b/drivers/platform/x86/toshiba_acpi.c
+@@ -57,6 +57,11 @@ module_param(turn_on_panel_on_resume, int, 0644);
+ MODULE_PARM_DESC(turn_on_panel_on_resume,
+       "Call HCI_PANEL_POWER_ON on resume (-1 = auto, 0 = no, 1 = yes");
++static int hci_hotkey_quickstart = -1;
++module_param(hci_hotkey_quickstart, int, 0644);
++MODULE_PARM_DESC(hci_hotkey_quickstart,
++               "Call HCI_HOTKEY_EVENT with value 0x5 for quickstart button support (-1 = auto, 0 = no, 1 = yes");
++
+ #define TOSHIBA_WMI_EVENT_GUID "59142400-C6A3-40FA-BADB-8A2652834100"
+ /* Scan code for Fn key on TOS1900 models */
+@@ -136,6 +141,7 @@ MODULE_PARM_DESC(turn_on_panel_on_resume,
+ #define HCI_ACCEL_MASK                        0x7fff
+ #define HCI_ACCEL_DIRECTION_MASK      0x8000
+ #define HCI_HOTKEY_DISABLE            0x0b
++#define HCI_HOTKEY_ENABLE_QUICKSTART  0x05
+ #define HCI_HOTKEY_ENABLE             0x09
+ #define HCI_HOTKEY_SPECIAL_FUNCTIONS  0x10
+ #define HCI_LCD_BRIGHTNESS_BITS               3
+@@ -2731,10 +2737,15 @@ static int toshiba_acpi_enable_hotkeys(struct toshiba_acpi_dev *dev)
+               return -ENODEV;
+       /*
++       * Enable quickstart buttons if supported.
++       *
+        * Enable the "Special Functions" mode only if they are
+        * supported and if they are activated.
+        */
+-      if (dev->kbd_function_keys_supported && dev->special_functions)
++      if (hci_hotkey_quickstart)
++              result = hci_write(dev, HCI_HOTKEY_EVENT,
++                                 HCI_HOTKEY_ENABLE_QUICKSTART);
++      else if (dev->kbd_function_keys_supported && dev->special_functions)
+               result = hci_write(dev, HCI_HOTKEY_EVENT,
+                                  HCI_HOTKEY_SPECIAL_FUNCTIONS);
+       else
+@@ -3258,7 +3269,14 @@ static const char *find_hci_method(acpi_handle handle)
+  * works. toshiba_acpi_resume() uses HCI_PANEL_POWER_ON to avoid changing
+  * the configured brightness level.
+  */
+-static const struct dmi_system_id turn_on_panel_on_resume_dmi_ids[] = {
++#define QUIRK_TURN_ON_PANEL_ON_RESUME         BIT(0)
++/*
++ * Some Toshibas use "quickstart" keys. On these, HCI_HOTKEY_EVENT must use
++ * the value HCI_HOTKEY_ENABLE_QUICKSTART.
++ */
++#define QUIRK_HCI_HOTKEY_QUICKSTART           BIT(1)
++
++static const struct dmi_system_id toshiba_dmi_quirks[] = {
+       {
+        /* Toshiba Portégé R700 */
+        /* https://bugzilla.kernel.org/show_bug.cgi?id=21012 */
+@@ -3266,6 +3284,7 @@ static const struct dmi_system_id turn_on_panel_on_resume_dmi_ids[] = {
+               DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R700"),
+               },
++       .driver_data = (void *)QUIRK_TURN_ON_PANEL_ON_RESUME,
+       },
+       {
+        /* Toshiba Satellite/Portégé R830 */
+@@ -3275,6 +3294,7 @@ static const struct dmi_system_id turn_on_panel_on_resume_dmi_ids[] = {
+               DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "R830"),
+               },
++       .driver_data = (void *)QUIRK_TURN_ON_PANEL_ON_RESUME,
+       },
+       {
+        /* Toshiba Satellite/Portégé Z830 */
+@@ -3282,6 +3302,7 @@ static const struct dmi_system_id turn_on_panel_on_resume_dmi_ids[] = {
+               DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "Z830"),
+               },
++       .driver_data = (void *)(QUIRK_TURN_ON_PANEL_ON_RESUME | QUIRK_HCI_HOTKEY_QUICKSTART),
+       },
+ };
+@@ -3290,6 +3311,8 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev)
+       struct toshiba_acpi_dev *dev;
+       const char *hci_method;
+       u32 dummy;
++      const struct dmi_system_id *dmi_id;
++      long quirks = 0;
+       int ret = 0;
+       if (toshiba_acpi)
+@@ -3442,8 +3465,15 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev)
+       }
+ #endif
++      dmi_id = dmi_first_match(toshiba_dmi_quirks);
++      if (dmi_id)
++              quirks = (long)dmi_id->driver_data;
++
+       if (turn_on_panel_on_resume == -1)
+-              turn_on_panel_on_resume = dmi_check_system(turn_on_panel_on_resume_dmi_ids);
++              turn_on_panel_on_resume = !!(quirks & QUIRK_TURN_ON_PANEL_ON_RESUME);
++
++      if (hci_hotkey_quickstart == -1)
++              hci_hotkey_quickstart = !!(quirks & QUIRK_HCI_HOTKEY_QUICKSTART);
+       toshiba_wwan_available(dev);
+       if (dev->wwan_supported)
+-- 
+2.43.0
+
diff --git a/queue-6.9/platform-x86-x86-android-tablets-add-lenovo-yoga-tab.patch b/queue-6.9/platform-x86-x86-android-tablets-add-lenovo-yoga-tab.patch
new file mode 100644 (file)
index 0000000..39e0b57
--- /dev/null
@@ -0,0 +1,306 @@
+From 15afefa8b3f5ef3aaaf091af8341fbf08b1e02c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Apr 2024 14:50:57 +0200
+Subject: platform/x86: x86-android-tablets: Add Lenovo Yoga Tablet 2 Pro
+ 1380F/L data
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 3eee73ad42c3899d97e073bf2c41e7670a3c575c ]
+
+The Lenovo Yoga Tablet 2 Pro 1380F/L is a x86 ACPI tablet which ships with
+Android x86 as factory OS. Its DSDT contains a bunch of I2C devices which
+are not actually there, causing various resource conflicts. Enumeration of
+these is skipped through the acpi_quirk_skip_i2c_client_enumeration().
+
+Add support for manually instantiating the I2C + other devices which are
+actually present on this tablet by adding the necessary device info to
+the x86-android-tablets module.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20240406125058.13624-2-hdegoede@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../platform/x86/x86-android-tablets/dmi.c    |  18 ++
+ .../platform/x86/x86-android-tablets/lenovo.c | 216 ++++++++++++++++++
+ .../x86-android-tablets/x86-android-tablets.h |   1 +
+ 3 files changed, 235 insertions(+)
+
+diff --git a/drivers/platform/x86/x86-android-tablets/dmi.c b/drivers/platform/x86/x86-android-tablets/dmi.c
+index 5d6c12494f082..141a2d25e83be 100644
+--- a/drivers/platform/x86/x86-android-tablets/dmi.c
++++ b/drivers/platform/x86/x86-android-tablets/dmi.c
+@@ -104,6 +104,24 @@ const struct dmi_system_id x86_android_tablet_ids[] __initconst = {
+               },
+               .driver_data = (void *)&lenovo_yogabook_x91_info,
+       },
++      {
++              /*
++               * Lenovo Yoga Tablet 2 Pro 1380F/L (13") This has more or less
++               * the same BIOS as the 830F/L or 1050F/L (8" and 10") below,
++               * but unlike the 8" / 10" models which share the same mainboard
++               * this model has a different mainboard.
++               * This match for the 13" model MUST come before the 8" + 10"
++               * match since that one will also match the 13" model!
++               */
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."),
++                      DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"),
++                      DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"),
++                      /* Full match so as to NOT match the 830/1050 BIOS */
++                      DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21.X64.0005.R00.1504101516"),
++              },
++              .driver_data = (void *)&lenovo_yoga_tab2_1380_info,
++      },
+       {
+               /*
+                * Lenovo Yoga Tablet 2 830F/L or 1050F/L (The 8" and 10"
+diff --git a/drivers/platform/x86/x86-android-tablets/lenovo.c b/drivers/platform/x86/x86-android-tablets/lenovo.c
+index c297391955adb..16fa04d604a09 100644
+--- a/drivers/platform/x86/x86-android-tablets/lenovo.c
++++ b/drivers/platform/x86/x86-android-tablets/lenovo.c
+@@ -19,6 +19,7 @@
+ #include <linux/pinctrl/machine.h>
+ #include <linux/platform_data/lp855x.h>
+ #include <linux/platform_device.h>
++#include <linux/power/bq24190_charger.h>
+ #include <linux/reboot.h>
+ #include <linux/rmi.h>
+ #include <linux/spi/spi.h>
+@@ -565,6 +566,221 @@ static void lenovo_yoga_tab2_830_1050_exit(void)
+       }
+ }
++/*
++ * Lenovo Yoga Tablet 2 Pro 1380F/L
++ *
++ * The Lenovo Yoga Tablet 2 Pro 1380F/L mostly has the same design as the 830F/L
++ * and the 1050F/L so this re-uses some of the handling for that from above.
++ */
++static const char * const lc824206xa_chg_det_psy[] = { "lc824206xa-charger-detect" };
++
++static const struct property_entry lenovo_yoga_tab2_1380_bq24190_props[] = {
++      PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lc824206xa_chg_det_psy),
++      PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
++      PROPERTY_ENTRY_BOOL("omit-battery-class"),
++      PROPERTY_ENTRY_BOOL("disable-reset"),
++      { }
++};
++
++static const struct software_node lenovo_yoga_tab2_1380_bq24190_node = {
++      .properties = lenovo_yoga_tab2_1380_bq24190_props,
++};
++
++/* For enabling the bq24190 5V boost based on id-pin */
++static struct regulator_consumer_supply lc824206xa_consumer = {
++      .supply = "vbus",
++      .dev_name = "i2c-lc824206xa",
++};
++
++static const struct regulator_init_data lenovo_yoga_tab2_1380_bq24190_vbus_init_data = {
++      .constraints = {
++              .name = "bq24190_vbus",
++              .valid_ops_mask = REGULATOR_CHANGE_STATUS,
++      },
++      .consumer_supplies = &lc824206xa_consumer,
++      .num_consumer_supplies = 1,
++};
++
++struct bq24190_platform_data lenovo_yoga_tab2_1380_bq24190_pdata = {
++      .regulator_init_data = &lenovo_yoga_tab2_1380_bq24190_vbus_init_data,
++};
++
++static const struct property_entry lenovo_yoga_tab2_1380_lc824206xa_props[] = {
++      PROPERTY_ENTRY_BOOL("onnn,enable-miclr-for-dcp"),
++      { }
++};
++
++static const struct software_node lenovo_yoga_tab2_1380_lc824206xa_node = {
++      .properties = lenovo_yoga_tab2_1380_lc824206xa_props,
++};
++
++static const char * const lenovo_yoga_tab2_1380_lms303d_mount_matrix[] = {
++      "0", "-1", "0",
++      "-1", "0", "0",
++      "0", "0", "1"
++};
++
++static const struct property_entry lenovo_yoga_tab2_1380_lms303d_props[] = {
++      PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", lenovo_yoga_tab2_1380_lms303d_mount_matrix),
++      { }
++};
++
++static const struct software_node lenovo_yoga_tab2_1380_lms303d_node = {
++      .properties = lenovo_yoga_tab2_1380_lms303d_props,
++};
++
++static const struct x86_i2c_client_info lenovo_yoga_tab2_1380_i2c_clients[] __initconst = {
++      {
++              /* BQ27541 fuel-gauge */
++              .board_info = {
++                      .type = "bq27541",
++                      .addr = 0x55,
++                      .dev_name = "bq27541",
++                      .swnode = &fg_bq24190_supply_node,
++              },
++              .adapter_path = "\\_SB_.I2C1",
++      }, {
++              /* bq24292i battery charger */
++              .board_info = {
++                      .type = "bq24190",
++                      .addr = 0x6b,
++                      .dev_name = "bq24292i",
++                      .swnode = &lenovo_yoga_tab2_1380_bq24190_node,
++                      .platform_data = &lenovo_yoga_tab2_1380_bq24190_pdata,
++              },
++              .adapter_path = "\\_SB_.I2C1",
++              .irq_data = {
++                      .type = X86_ACPI_IRQ_TYPE_GPIOINT,
++                      .chip = "INT33FC:02",
++                      .index = 2,
++                      .trigger = ACPI_EDGE_SENSITIVE,
++                      .polarity = ACPI_ACTIVE_HIGH,
++                      .con_id = "bq24292i_irq",
++              },
++      }, {
++              /* LP8557 Backlight controller */
++              .board_info = {
++                      .type = "lp8557",
++                      .addr = 0x2c,
++                      .dev_name = "lp8557",
++                      .platform_data = &lenovo_lp8557_pwm_and_reg_pdata,
++              },
++              .adapter_path = "\\_SB_.I2C3",
++      }, {
++              /* LC824206XA Micro USB Switch */
++              .board_info = {
++                      .type = "lc824206xa",
++                      .addr = 0x48,
++                      .dev_name = "lc824206xa",
++                      .swnode = &lenovo_yoga_tab2_1380_lc824206xa_node,
++              },
++              .adapter_path = "\\_SB_.I2C3",
++              .irq_data = {
++                      .type = X86_ACPI_IRQ_TYPE_GPIOINT,
++                      .chip = "INT33FC:02",
++                      .index = 1,
++                      .trigger = ACPI_LEVEL_SENSITIVE,
++                      .polarity = ACPI_ACTIVE_LOW,
++                      .con_id = "lc824206xa_irq",
++              },
++      }, {
++              /* AL3320A ambient light sensor */
++              .board_info = {
++                      .type = "al3320a",
++                      .addr = 0x1c,
++                      .dev_name = "al3320a",
++              },
++              .adapter_path = "\\_SB_.I2C5",
++      }, {
++              /* LSM303DA accelerometer + magnetometer */
++              .board_info = {
++                      .type = "lsm303d",
++                      .addr = 0x1d,
++                      .dev_name = "lsm303d",
++                      .swnode = &lenovo_yoga_tab2_1380_lms303d_node,
++              },
++              .adapter_path = "\\_SB_.I2C5",
++      }, {
++              /* Synaptics RMI touchscreen */
++              .board_info = {
++                      .type = "rmi4_i2c",
++                      .addr = 0x38,
++                      .dev_name = "rmi4_i2c",
++                      .platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata,
++              },
++              .adapter_path = "\\_SB_.I2C6",
++              .irq_data = {
++                      .type = X86_ACPI_IRQ_TYPE_APIC,
++                      .index = 0x45,
++                      .trigger = ACPI_EDGE_SENSITIVE,
++                      .polarity = ACPI_ACTIVE_HIGH,
++              },
++      }
++};
++
++static const struct platform_device_info lenovo_yoga_tab2_1380_pdevs[] __initconst = {
++      {
++              /* For the Tablet 2 Pro 1380's custom fast charging driver */
++              .name = "lenovo-yoga-tab2-pro-1380-fastcharger",
++              .id = PLATFORM_DEVID_NONE,
++      },
++};
++
++const char * const lenovo_yoga_tab2_1380_modules[] __initconst = {
++      "bq24190_charger",            /* For the Vbus regulator for lc824206xa */
++      NULL
++};
++
++static int __init lenovo_yoga_tab2_1380_init(void)
++{
++      int ret;
++
++      /* To verify that the DMI matching works vs the 830 / 1050 models */
++      pr_info("detected Lenovo Yoga Tablet 2 Pro 1380F/L\n");
++
++      ret = lenovo_yoga_tab2_830_1050_init_codec();
++      if (ret)
++              return ret;
++
++      /* SYS_OFF_PRIO_FIRMWARE + 1 so that it runs before acpi_power_off */
++      lenovo_yoga_tab2_830_1050_sys_off_handler =
++              register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE + 1,
++                                       lenovo_yoga_tab2_830_1050_power_off, NULL);
++      if (IS_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler))
++              return PTR_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler);
++
++      return 0;
++}
++
++static struct gpiod_lookup_table lenovo_yoga_tab2_1380_fc_gpios = {
++      .dev_id = "serial0-0",
++      .table = {
++              GPIO_LOOKUP("INT33FC:00", 57, "uart3_txd", GPIO_ACTIVE_HIGH),
++              GPIO_LOOKUP("INT33FC:00", 61, "uart3_rxd", GPIO_ACTIVE_HIGH),
++              { }
++      },
++};
++
++static struct gpiod_lookup_table * const lenovo_yoga_tab2_1380_gpios[] = {
++      &lenovo_yoga_tab2_830_1050_codec_gpios,
++      &lenovo_yoga_tab2_1380_fc_gpios,
++      NULL
++};
++
++const struct x86_dev_info lenovo_yoga_tab2_1380_info __initconst = {
++      .i2c_client_info = lenovo_yoga_tab2_1380_i2c_clients,
++      .i2c_client_count = ARRAY_SIZE(lenovo_yoga_tab2_1380_i2c_clients),
++      .pdev_info = lenovo_yoga_tab2_1380_pdevs,
++      .pdev_count = ARRAY_SIZE(lenovo_yoga_tab2_1380_pdevs),
++      .gpio_button = &lenovo_yoga_tab2_830_1050_lid,
++      .gpio_button_count = 1,
++      .gpiod_lookup_tables = lenovo_yoga_tab2_1380_gpios,
++      .bat_swnode = &generic_lipo_hv_4v35_battery_node,
++      .modules = lenovo_yoga_tab2_1380_modules,
++      .init = lenovo_yoga_tab2_1380_init,
++      .exit = lenovo_yoga_tab2_830_1050_exit,
++};
++
+ /* Lenovo Yoga Tab 3 Pro YT3-X90F */
+ /*
+diff --git a/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h b/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h
+index 468993edfeee2..821dc094b0254 100644
+--- a/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h
++++ b/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h
+@@ -112,6 +112,7 @@ extern const struct x86_dev_info czc_p10t;
+ extern const struct x86_dev_info lenovo_yogabook_x90_info;
+ extern const struct x86_dev_info lenovo_yogabook_x91_info;
+ extern const struct x86_dev_info lenovo_yoga_tab2_830_1050_info;
++extern const struct x86_dev_info lenovo_yoga_tab2_1380_info;
+ extern const struct x86_dev_info lenovo_yt3_info;
+ extern const struct x86_dev_info medion_lifetab_s10346_info;
+ extern const struct x86_dev_info nextbook_ares8_info;
+-- 
+2.43.0
+
diff --git a/queue-6.9/platform-x86-x86-android-tablets-unregister-devices-.patch b/queue-6.9/platform-x86-x86-android-tablets-unregister-devices-.patch
new file mode 100644 (file)
index 0000000..1907e10
--- /dev/null
@@ -0,0 +1,99 @@
+From 4a415794d62b90669c77e2e915cae7cce2071b26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Apr 2024 14:50:56 +0200
+Subject: platform/x86: x86-android-tablets: Unregister devices in reverse
+ order
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 3de0f2627ef849735f155c1818247f58404dddfe ]
+
+Not all subsystems support a device getting removed while there are
+still consumers of the device with a reference to the device.
+
+One example of this is the regulator subsystem. If a regulator gets
+unregistered while there are still drivers holding a reference
+a WARN() at drivers/regulator/core.c:5829 triggers, e.g.:
+
+ WARNING: CPU: 1 PID: 1587 at drivers/regulator/core.c:5829 regulator_unregister
+ Hardware name: Intel Corp. VALLEYVIEW C0 PLATFORM/BYT-T FFD8, BIOS BLADE_21.X64.0005.R00.1504101516 FFD8_X64_R_2015_04_10_1516 04/10/2015
+ RIP: 0010:regulator_unregister
+ Call Trace:
+  <TASK>
+  regulator_unregister
+  devres_release_group
+  i2c_device_remove
+  device_release_driver_internal
+  bus_remove_device
+  device_del
+  device_unregister
+  x86_android_tablet_remove
+
+On the Lenovo Yoga Tablet 2 series the bq24190 charger chip also provides
+a 5V boost converter output for powering USB devices connected to the micro
+USB port, the bq24190-charger driver exports this as a Vbus regulator.
+
+On the 830 (8") and 1050 ("10") models this regulator is controlled by
+a platform_device and x86_android_tablet_remove() removes platform_device-s
+before i2c_clients so the consumer gets removed first.
+
+But on the 1380 (13") model there is a lc824206xa micro-USB switch
+connected over I2C and the extcon driver for that controls the regulator.
+The bq24190 i2c-client *must* be registered first, because that creates
+the regulator with the lc824206xa listed as its consumer. If the regulator
+has not been registered yet the lc824206xa driver will end up getting
+a dummy regulator.
+
+Since in this case both the regulator provider and consumer are I2C
+devices, the only way to ensure that the consumer is unregistered first
+is to unregister the I2C devices in reverse order of in which they were
+created.
+
+For consistency and to avoid similar problems in the future change
+x86_android_tablet_remove() to unregister all device types in reverse
+order.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20240406125058.13624-1-hdegoede@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/x86-android-tablets/core.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c
+index a3415f1c0b5f8..6559bb4ea7305 100644
+--- a/drivers/platform/x86/x86-android-tablets/core.c
++++ b/drivers/platform/x86/x86-android-tablets/core.c
+@@ -278,25 +278,25 @@ static void x86_android_tablet_remove(struct platform_device *pdev)
+ {
+       int i;
+-      for (i = 0; i < serdev_count; i++) {
++      for (i = serdev_count - 1; i >= 0; i--) {
+               if (serdevs[i])
+                       serdev_device_remove(serdevs[i]);
+       }
+       kfree(serdevs);
+-      for (i = 0; i < pdev_count; i++)
++      for (i = pdev_count - 1; i >= 0; i--)
+               platform_device_unregister(pdevs[i]);
+       kfree(pdevs);
+       kfree(buttons);
+-      for (i = 0; i < spi_dev_count; i++)
++      for (i = spi_dev_count - 1; i >= 0; i--)
+               spi_unregister_device(spi_devs[i]);
+       kfree(spi_devs);
+-      for (i = 0; i < i2c_client_count; i++)
++      for (i = i2c_client_count - 1; i >= 0; i--)
+               i2c_unregister_device(i2c_clients[i]);
+       kfree(i2c_clients);
+-- 
+2.43.0
+
diff --git a/queue-6.9/power-supply-cros_usbpd-provide-id-table-for-avoidin.patch b/queue-6.9/power-supply-cros_usbpd-provide-id-table-for-avoidin.patch
new file mode 100644 (file)
index 0000000..4ee0593
--- /dev/null
@@ -0,0 +1,66 @@
+From 4d09b275011ab3d9ed5408329560c80a3a04306e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Apr 2024 11:00:49 +0800
+Subject: power: supply: cros_usbpd: provide ID table for avoiding fallback
+ match
+
+From: Tzung-Bi Shih <tzungbi@kernel.org>
+
+[ Upstream commit 0f8678c34cbfdc63569a9b0ede1fe235ec6ec693 ]
+
+Instead of using fallback driver name match, provide ID table[1] for the
+primary match.
+
+[1]: https://elixir.bootlin.com/linux/v6.8/source/drivers/base/platform.c#L1353
+
+Reviewed-by: Benson Leung <bleung@chromium.org>
+Reviewed-by: Prashant Malani <pmalani@chromium.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
+Link: https://lore.kernel.org/r/20240401030052.2887845-4-tzungbi@kernel.org
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/cros_usbpd-charger.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/power/supply/cros_usbpd-charger.c b/drivers/power/supply/cros_usbpd-charger.c
+index b6c96376776a9..8008e31c0c098 100644
+--- a/drivers/power/supply/cros_usbpd-charger.c
++++ b/drivers/power/supply/cros_usbpd-charger.c
+@@ -5,6 +5,7 @@
+  * Copyright (c) 2014 - 2018 Google, Inc
+  */
++#include <linux/mod_devicetable.h>
+ #include <linux/module.h>
+ #include <linux/platform_data/cros_ec_commands.h>
+ #include <linux/platform_data/cros_ec_proto.h>
+@@ -711,16 +712,22 @@ static int cros_usbpd_charger_resume(struct device *dev)
+ static SIMPLE_DEV_PM_OPS(cros_usbpd_charger_pm_ops, NULL,
+                        cros_usbpd_charger_resume);
++static const struct platform_device_id cros_usbpd_charger_id[] = {
++      { DRV_NAME, 0 },
++      {}
++};
++MODULE_DEVICE_TABLE(platform, cros_usbpd_charger_id);
++
+ static struct platform_driver cros_usbpd_charger_driver = {
+       .driver = {
+               .name = DRV_NAME,
+               .pm = &cros_usbpd_charger_pm_ops,
+       },
+-      .probe = cros_usbpd_charger_probe
++      .probe = cros_usbpd_charger_probe,
++      .id_table = cros_usbpd_charger_id,
+ };
+ module_platform_driver(cros_usbpd_charger_driver);
+ MODULE_LICENSE("GPL");
+ MODULE_DESCRIPTION("ChromeOS EC USBPD charger");
+-MODULE_ALIAS("platform:" DRV_NAME);
+-- 
+2.43.0
+
diff --git a/queue-6.9/powerpc-io-avoid-clang-null-pointer-arithmetic-warni.patch b/queue-6.9/powerpc-io-avoid-clang-null-pointer-arithmetic-warni.patch
new file mode 100644 (file)
index 0000000..717ef12
--- /dev/null
@@ -0,0 +1,85 @@
+From 68cfde474f56adb47ca0097db37bec109def570c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 May 2024 17:56:18 +1000
+Subject: powerpc/io: Avoid clang null pointer arithmetic warnings
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit 03c0f2c2b2220fc9cf8785cd7b61d3e71e24a366 ]
+
+With -Wextra clang warns about pointer arithmetic using a null pointer.
+When building with CONFIG_PCI=n, that triggers a warning in the IO
+accessors, eg:
+
+  In file included from linux/arch/powerpc/include/asm/io.h:672:
+  linux/arch/powerpc/include/asm/io-defs.h:23:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
+     23 | DEF_PCI_AC_RET(inb, u8, (unsigned long port), (port), pio, port)
+        | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ...
+  linux/arch/powerpc/include/asm/io.h:591:53: note: expanded from macro '__do_inb'
+    591 | #define __do_inb(port)          readb((PCI_IO_ADDR)_IO_BASE + port);
+        |                                       ~~~~~~~~~~~~~~~~~~~~~ ^
+
+That is because when CONFIG_PCI=n, _IO_BASE is defined as 0.
+
+Although _IO_BASE is defined as plain 0, the cast (PCI_IO_ADDR) converts
+it to void * before the addition with port happens.
+
+Instead the addition can be done first, and then the cast. The resulting
+value will be the same, but avoids the warning, and also avoids void
+pointer arithmetic which is apparently non-standard.
+
+Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org>
+Closes: https://lore.kernel.org/all/CA+G9fYtEh8zmq8k8wE-8RZwW-Qr927RLTn+KqGnq1F=ptaaNsA@mail.gmail.com
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20240503075619.394467-1-mpe@ellerman.id.au
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/io.h | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
+index 08c550ed49be6..ba2e13bb879dc 100644
+--- a/arch/powerpc/include/asm/io.h
++++ b/arch/powerpc/include/asm/io.h
+@@ -585,12 +585,12 @@ __do_out_asm(_rec_outl, "stwbrx")
+ #define __do_inw(port)                _rec_inw(port)
+ #define __do_inl(port)                _rec_inl(port)
+ #else /* CONFIG_PPC32 */
+-#define __do_outb(val, port)  writeb(val,(PCI_IO_ADDR)_IO_BASE+port);
+-#define __do_outw(val, port)  writew(val,(PCI_IO_ADDR)_IO_BASE+port);
+-#define __do_outl(val, port)  writel(val,(PCI_IO_ADDR)_IO_BASE+port);
+-#define __do_inb(port)                readb((PCI_IO_ADDR)_IO_BASE + port);
+-#define __do_inw(port)                readw((PCI_IO_ADDR)_IO_BASE + port);
+-#define __do_inl(port)                readl((PCI_IO_ADDR)_IO_BASE + port);
++#define __do_outb(val, port)  writeb(val,(PCI_IO_ADDR)(_IO_BASE+port));
++#define __do_outw(val, port)  writew(val,(PCI_IO_ADDR)(_IO_BASE+port));
++#define __do_outl(val, port)  writel(val,(PCI_IO_ADDR)(_IO_BASE+port));
++#define __do_inb(port)                readb((PCI_IO_ADDR)(_IO_BASE + port));
++#define __do_inw(port)                readw((PCI_IO_ADDR)(_IO_BASE + port));
++#define __do_inl(port)                readl((PCI_IO_ADDR)(_IO_BASE + port));
+ #endif /* !CONFIG_PPC32 */
+ #ifdef CONFIG_EEH
+@@ -606,12 +606,12 @@ __do_out_asm(_rec_outl, "stwbrx")
+ #define __do_writesw(a, b, n) _outsw(PCI_FIX_ADDR(a),(b),(n))
+ #define __do_writesl(a, b, n) _outsl(PCI_FIX_ADDR(a),(b),(n))
+-#define __do_insb(p, b, n)    readsb((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))
+-#define __do_insw(p, b, n)    readsw((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))
+-#define __do_insl(p, b, n)    readsl((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))
+-#define __do_outsb(p, b, n)   writesb((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
+-#define __do_outsw(p, b, n)   writesw((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
+-#define __do_outsl(p, b, n)   writesl((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
++#define __do_insb(p, b, n)    readsb((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n))
++#define __do_insw(p, b, n)    readsw((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n))
++#define __do_insl(p, b, n)    readsl((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n))
++#define __do_outsb(p, b, n)   writesb((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n))
++#define __do_outsw(p, b, n)   writesw((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n))
++#define __do_outsl(p, b, n)   writesl((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n))
+ #define __do_memset_io(addr, c, n)    \
+                               _memset_io(PCI_FIX_ADDR(addr), c, n)
+-- 
+2.43.0
+
diff --git a/queue-6.9/powerpc-pseries-enforce-hcall-result-buffer-validity.patch b/queue-6.9/powerpc-pseries-enforce-hcall-result-buffer-validity.patch
new file mode 100644 (file)
index 0000000..5af4b67
--- /dev/null
@@ -0,0 +1,82 @@
+From b38cf46addff8bae06a403719aa11a99a3bfd8ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Apr 2024 09:08:31 -0500
+Subject: powerpc/pseries: Enforce hcall result buffer validity and size
+
+From: Nathan Lynch <nathanl@linux.ibm.com>
+
+[ Upstream commit ff2e185cf73df480ec69675936c4ee75a445c3e4 ]
+
+plpar_hcall(), plpar_hcall9(), and related functions expect callers to
+provide valid result buffers of certain minimum size. Currently this
+is communicated only through comments in the code and the compiler has
+no idea.
+
+For example, if I write a bug like this:
+
+  long retbuf[PLPAR_HCALL_BUFSIZE]; // should be PLPAR_HCALL9_BUFSIZE
+  plpar_hcall9(H_ALLOCATE_VAS_WINDOW, retbuf, ...);
+
+This compiles with no diagnostics emitted, but likely results in stack
+corruption at runtime when plpar_hcall9() stores results past the end
+of the array. (To be clear this is a contrived example and I have not
+found a real instance yet.)
+
+To make this class of error less likely, we can use explicitly-sized
+array parameters instead of pointers in the declarations for the hcall
+APIs. When compiled with -Warray-bounds[1], the code above now
+provokes a diagnostic like this:
+
+error: array argument is too small;
+is of size 32, callee requires at least 72 [-Werror,-Warray-bounds]
+   60 |                 plpar_hcall9(H_ALLOCATE_VAS_WINDOW, retbuf,
+      |                 ^                                   ~~~~~~
+
+[1] Enabled for LLVM builds but not GCC for now. See commit
+    0da6e5fd6c37 ("gcc: disable '-Warray-bounds' for gcc-13 too") and
+    related changes.
+
+Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20240408-pseries-hvcall-retbuf-v1-1-ebc73d7253cf@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/hvcall.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
+index 51172625fa3a5..7a8495660c2f8 100644
+--- a/arch/powerpc/include/asm/hvcall.h
++++ b/arch/powerpc/include/asm/hvcall.h
+@@ -524,7 +524,7 @@ long plpar_hcall_norets_notrace(unsigned long opcode, ...);
+  * Used for all but the craziest of phyp interfaces (see plpar_hcall9)
+  */
+ #define PLPAR_HCALL_BUFSIZE 4
+-long plpar_hcall(unsigned long opcode, unsigned long *retbuf, ...);
++long plpar_hcall(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL_BUFSIZE], ...);
+ /**
+  * plpar_hcall_raw: - Make a hypervisor call without calculating hcall stats
+@@ -538,7 +538,7 @@ long plpar_hcall(unsigned long opcode, unsigned long *retbuf, ...);
+  * plpar_hcall, but plpar_hcall_raw works in real mode and does not
+  * calculate hypervisor call statistics.
+  */
+-long plpar_hcall_raw(unsigned long opcode, unsigned long *retbuf, ...);
++long plpar_hcall_raw(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL_BUFSIZE], ...);
+ /**
+  * plpar_hcall9: - Make a pseries hypervisor call with up to 9 return arguments
+@@ -549,8 +549,8 @@ long plpar_hcall_raw(unsigned long opcode, unsigned long *retbuf, ...);
+  * PLPAR_HCALL9_BUFSIZE to size the return argument buffer.
+  */
+ #define PLPAR_HCALL9_BUFSIZE 9
+-long plpar_hcall9(unsigned long opcode, unsigned long *retbuf, ...);
+-long plpar_hcall9_raw(unsigned long opcode, unsigned long *retbuf, ...);
++long plpar_hcall9(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL9_BUFSIZE], ...);
++long plpar_hcall9_raw(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL9_BUFSIZE], ...);
+ /* pseries hcall tracing */
+ extern struct static_key hcall_tracepoint_key;
+-- 
+2.43.0
+
diff --git a/queue-6.9/rcutorture-fix-invalid-context-warning-when-enable-s.patch b/queue-6.9/rcutorture-fix-invalid-context-warning-when-enable-s.patch
new file mode 100644 (file)
index 0000000..83531bf
--- /dev/null
@@ -0,0 +1,120 @@
+From 4623bbc44daefc097da652a971f2f453fa4e61ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Mar 2024 15:52:19 +0800
+Subject: rcutorture: Fix invalid context warning when enable srcu barrier
+ testing
+
+From: Zqiang <qiang.zhang1211@gmail.com>
+
+[ Upstream commit 668c0406d887467d53f8fe79261dda1d22d5b671 ]
+
+When the torture_type is set srcu or srcud and cb_barrier is
+non-zero, running the rcutorture test will trigger the
+following warning:
+
+[  163.910989][    C1] BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48
+[  163.910994][    C1] in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 0, name: swapper/1
+[  163.910999][    C1] preempt_count: 10001, expected: 0
+[  163.911002][    C1] RCU nest depth: 0, expected: 0
+[  163.911005][    C1] INFO: lockdep is turned off.
+[  163.911007][    C1] irq event stamp: 30964
+[  163.911010][    C1] hardirqs last  enabled at (30963): [<ffffffffabc7df52>] do_idle+0x362/0x500
+[  163.911018][    C1] hardirqs last disabled at (30964): [<ffffffffae616eff>] sysvec_call_function_single+0xf/0xd0
+[  163.911025][    C1] softirqs last  enabled at (0): [<ffffffffabb6475f>] copy_process+0x16ff/0x6580
+[  163.911033][    C1] softirqs last disabled at (0): [<0000000000000000>] 0x0
+[  163.911038][    C1] Preemption disabled at:
+[  163.911039][    C1] [<ffffffffacf1964b>] stack_depot_save_flags+0x24b/0x6c0
+[  163.911063][    C1] CPU: 1 PID: 0 Comm: swapper/1 Tainted: G        W          6.8.0-rc4-rt4-yocto-preempt-rt+ #3 1e39aa9a737dd024a3275c4f835a872f673a7d3a
+[  163.911071][    C1] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014
+[  163.911075][    C1] Call Trace:
+[  163.911078][    C1]  <IRQ>
+[  163.911080][    C1]  dump_stack_lvl+0x88/0xd0
+[  163.911089][    C1]  dump_stack+0x10/0x20
+[  163.911095][    C1]  __might_resched+0x36f/0x530
+[  163.911105][    C1]  rt_spin_lock+0x82/0x1c0
+[  163.911112][    C1]  spin_lock_irqsave_ssp_contention+0xb8/0x100
+[  163.911121][    C1]  srcu_gp_start_if_needed+0x782/0xf00
+[  163.911128][    C1]  ? _raw_spin_unlock_irqrestore+0x46/0x70
+[  163.911136][    C1]  ? debug_object_active_state+0x336/0x470
+[  163.911148][    C1]  ? __pfx_srcu_gp_start_if_needed+0x10/0x10
+[  163.911156][    C1]  ? __pfx_lock_release+0x10/0x10
+[  163.911165][    C1]  ? __pfx_rcu_torture_barrier_cbf+0x10/0x10
+[  163.911188][    C1]  __call_srcu+0x9f/0xe0
+[  163.911196][    C1]  call_srcu+0x13/0x20
+[  163.911201][    C1]  srcu_torture_call+0x1b/0x30
+[  163.911224][    C1]  rcu_torture_barrier1cb+0x4a/0x60
+[  163.911247][    C1]  __flush_smp_call_function_queue+0x267/0xca0
+[  163.911256][    C1]  ? __pfx_rcu_torture_barrier1cb+0x10/0x10
+[  163.911281][    C1]  generic_smp_call_function_single_interrupt+0x13/0x20
+[  163.911288][    C1]  __sysvec_call_function_single+0x7d/0x280
+[  163.911295][    C1]  sysvec_call_function_single+0x93/0xd0
+[  163.911302][    C1]  </IRQ>
+[  163.911304][    C1]  <TASK>
+[  163.911308][    C1]  asm_sysvec_call_function_single+0x1b/0x20
+[  163.911313][    C1] RIP: 0010:default_idle+0x17/0x20
+[  163.911326][    C1] RSP: 0018:ffff888001997dc8 EFLAGS: 00000246
+[  163.911333][    C1] RAX: 0000000000000000 RBX: dffffc0000000000 RCX: ffffffffae618b51
+[  163.911337][    C1] RDX: 0000000000000000 RSI: ffffffffaea80920 RDI: ffffffffaec2de80
+[  163.911342][    C1] RBP: ffff888001997dc8 R08: 0000000000000001 R09: ffffed100d740cad
+[  163.911346][    C1] R10: ffffed100d740cac R11: ffff88806ba06563 R12: 0000000000000001
+[  163.911350][    C1] R13: ffffffffafe460c0 R14: ffffffffafe460c0 R15: 0000000000000000
+[  163.911358][    C1]  ? ct_kernel_exit.constprop.3+0x121/0x160
+[  163.911369][    C1]  ? lockdep_hardirqs_on+0xc4/0x150
+[  163.911376][    C1]  arch_cpu_idle+0x9/0x10
+[  163.911383][    C1]  default_idle_call+0x7a/0xb0
+[  163.911390][    C1]  do_idle+0x362/0x500
+[  163.911398][    C1]  ? __pfx_do_idle+0x10/0x10
+[  163.911404][    C1]  ? complete_with_flags+0x8b/0xb0
+[  163.911416][    C1]  cpu_startup_entry+0x58/0x70
+[  163.911423][    C1]  start_secondary+0x221/0x280
+[  163.911430][    C1]  ? __pfx_start_secondary+0x10/0x10
+[  163.911440][    C1]  secondary_startup_64_no_verify+0x17f/0x18b
+[  163.911455][    C1]  </TASK>
+
+This commit therefore use smp_call_on_cpu() instead of
+smp_call_function_single(), make rcu_torture_barrier1cb() invoked
+happens on task-context.
+
+Signed-off-by: Zqiang <qiang.zhang1211@gmail.com>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/rcutorture.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
+index 4a2cf312e695a..cf2e907534a8d 100644
+--- a/kernel/rcu/rcutorture.c
++++ b/kernel/rcu/rcutorture.c
+@@ -3041,11 +3041,12 @@ static void rcu_torture_barrier_cbf(struct rcu_head *rcu)
+ }
+ /* IPI handler to get callback posted on desired CPU, if online. */
+-static void rcu_torture_barrier1cb(void *rcu_void)
++static int rcu_torture_barrier1cb(void *rcu_void)
+ {
+       struct rcu_head *rhp = rcu_void;
+       cur_ops->call(rhp, rcu_torture_barrier_cbf);
++      return 0;
+ }
+ /* kthread function to register callbacks used to test RCU barriers. */
+@@ -3071,11 +3072,9 @@ static int rcu_torture_barrier_cbs(void *arg)
+                * The above smp_load_acquire() ensures barrier_phase load
+                * is ordered before the following ->call().
+                */
+-              if (smp_call_function_single(myid, rcu_torture_barrier1cb,
+-                                           &rcu, 1)) {
+-                      // IPI failed, so use direct call from current CPU.
++              if (smp_call_on_cpu(myid, rcu_torture_barrier1cb, &rcu, 1))
+                       cur_ops->call(&rcu, rcu_torture_barrier_cbf);
+-              }
++
+               if (atomic_dec_and_test(&barrier_cbs_count))
+                       wake_up(&barrier_wq);
+       } while (!torture_must_stop());
+-- 
+2.43.0
+
diff --git a/queue-6.9/rcutorture-fix-rcu_torture_one_read-pipe_count-overf.patch b/queue-6.9/rcutorture-fix-rcu_torture_one_read-pipe_count-overf.patch
new file mode 100644 (file)
index 0000000..3a32a3d
--- /dev/null
@@ -0,0 +1,39 @@
+From c6c7aa682fba9570b5709d3325d7d7059614ce5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Mar 2024 19:21:47 -0800
+Subject: rcutorture: Fix rcu_torture_one_read() pipe_count overflow comment
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+[ Upstream commit 8b9b443fa860276822b25057cb3ff3b28734dec0 ]
+
+The "pipe_count > RCU_TORTURE_PIPE_LEN" check has a comment saying "Should
+not happen, but...".  This is only true when testing an RCU whose grace
+periods are always long enough.  This commit therefore fixes this comment.
+
+Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
+Closes: https://lore.kernel.org/lkml/CAHk-=wi7rJ-eGq+xaxVfzFEgbL9tdf6Kc8Z89rCpfcQOKm74Tw@mail.gmail.com/
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/rcutorture.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
+index 45d6b4c3d199c..5dfea5c6de577 100644
+--- a/kernel/rcu/rcutorture.c
++++ b/kernel/rcu/rcutorture.c
+@@ -1997,7 +1997,8 @@ static bool rcu_torture_one_read(struct torture_random_state *trsp, long myid)
+       preempt_disable();
+       pipe_count = READ_ONCE(p->rtort_pipe_count);
+       if (pipe_count > RCU_TORTURE_PIPE_LEN) {
+-              /* Should not happen, but... */
++              // Should not happen in a correct RCU implementation,
++              // happens quite often for torture_type=busted.
+               pipe_count = RCU_TORTURE_PIPE_LEN;
+       }
+       completed = cur_ops->get_gp_seq();
+-- 
+2.43.0
+
diff --git a/queue-6.9/rcutorture-make-stall-tasks-directly-exit-when-rcuto.patch b/queue-6.9/rcutorture-make-stall-tasks-directly-exit-when-rcuto.patch
new file mode 100644 (file)
index 0000000..69fb191
--- /dev/null
@@ -0,0 +1,103 @@
+From bfdac0c6a8cb06b40047fcf6c3f5fa4360b93efa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Mar 2024 16:28:50 +0800
+Subject: rcutorture: Make stall-tasks directly exit when rcutorture tests end
+
+From: Zqiang <qiang.zhang1211@gmail.com>
+
+[ Upstream commit 431315a563015f259b28e34c5842f6166439e969 ]
+
+When the rcutorture tests start to exit, the rcu_torture_cleanup() is
+invoked to stop kthreads and release resources, if the stall-task
+kthreads exist, cpu-stall has started and the rcutorture.stall_cpu
+is set to a larger value, the rcu_torture_cleanup() will be blocked
+for a long time and the hung-task may occur, this commit therefore
+add kthread_should_stop() to the loop of cpu-stall operation, when
+rcutorture tests ends, no need to wait for cpu-stall to end, exit
+directly.
+
+Use the following command to test:
+
+insmod rcutorture.ko torture_type=srcu fwd_progress=0 stat_interval=4
+stall_cpu_block=1 stall_cpu=200 stall_cpu_holdoff=10 read_exit_burst=0
+object_debug=1
+rmmod rcutorture
+
+[15361.918610] INFO: task rmmod:878 blocked for more than 122 seconds.
+[15361.918613]       Tainted: G        W
+6.8.0-rc2-yoctodev-standard+ #25
+[15361.918615] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
+disables this message.
+[15361.918616] task:rmmod           state:D stack:0     pid:878
+tgid:878   ppid:773    flags:0x00004002
+[15361.918621] Call Trace:
+[15361.918623]  <TASK>
+[15361.918626]  __schedule+0xc0d/0x28f0
+[15361.918631]  ? __pfx___schedule+0x10/0x10
+[15361.918635]  ? rcu_is_watching+0x19/0xb0
+[15361.918638]  ? schedule+0x1f6/0x290
+[15361.918642]  ? __pfx_lock_release+0x10/0x10
+[15361.918645]  ? schedule+0xc9/0x290
+[15361.918648]  ? schedule+0xc9/0x290
+[15361.918653]  ? trace_preempt_off+0x54/0x100
+[15361.918657]  ? schedule+0xc9/0x290
+[15361.918661]  schedule+0xd0/0x290
+[15361.918665]  schedule_timeout+0x56d/0x7d0
+[15361.918669]  ? debug_smp_processor_id+0x1b/0x30
+[15361.918672]  ? rcu_is_watching+0x19/0xb0
+[15361.918676]  ? __pfx_schedule_timeout+0x10/0x10
+[15361.918679]  ? debug_smp_processor_id+0x1b/0x30
+[15361.918683]  ? rcu_is_watching+0x19/0xb0
+[15361.918686]  ? wait_for_completion+0x179/0x4c0
+[15361.918690]  ? __pfx_lock_release+0x10/0x10
+[15361.918693]  ? __kasan_check_write+0x18/0x20
+[15361.918696]  ? wait_for_completion+0x9d/0x4c0
+[15361.918700]  ? _raw_spin_unlock_irq+0x36/0x50
+[15361.918703]  ? wait_for_completion+0x179/0x4c0
+[15361.918707]  ? _raw_spin_unlock_irq+0x36/0x50
+[15361.918710]  ? wait_for_completion+0x179/0x4c0
+[15361.918714]  ? trace_preempt_on+0x54/0x100
+[15361.918718]  ? wait_for_completion+0x179/0x4c0
+[15361.918723]  wait_for_completion+0x181/0x4c0
+[15361.918728]  ? __pfx_wait_for_completion+0x10/0x10
+[15361.918738]  kthread_stop+0x152/0x470
+[15361.918742]  _torture_stop_kthread+0x44/0xc0 [torture
+7af7f9cbba28271a10503b653f9e05d518fbc8c3]
+[15361.918752]  rcu_torture_cleanup+0x2ac/0xe90 [rcutorture
+f2cb1f556ee7956270927183c4c2c7749a336529]
+[15361.918766]  ? __pfx_rcu_torture_cleanup+0x10/0x10 [rcutorture
+f2cb1f556ee7956270927183c4c2c7749a336529]
+[15361.918777]  ? __kasan_check_write+0x18/0x20
+[15361.918781]  ? __mutex_unlock_slowpath+0x17c/0x670
+[15361.918789]  ? __might_fault+0xcd/0x180
+[15361.918793]  ? find_module_all+0x104/0x1d0
+[15361.918799]  __x64_sys_delete_module+0x2a4/0x3f0
+[15361.918803]  ? __pfx___x64_sys_delete_module+0x10/0x10
+[15361.918807]  ? syscall_exit_to_user_mode+0x149/0x280
+
+Signed-off-by: Zqiang <qiang.zhang1211@gmail.com>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/rcutorture.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
+index 5dfea5c6de577..4a2cf312e695a 100644
+--- a/kernel/rcu/rcutorture.c
++++ b/kernel/rcu/rcutorture.c
+@@ -2487,8 +2487,8 @@ static int rcu_torture_stall(void *args)
+                       preempt_disable();
+               pr_alert("%s start on CPU %d.\n",
+                         __func__, raw_smp_processor_id());
+-              while (ULONG_CMP_LT((unsigned long)ktime_get_seconds(),
+-                                  stop_at))
++              while (ULONG_CMP_LT((unsigned long)ktime_get_seconds(), stop_at) &&
++                     !kthread_should_stop())
+                       if (stall_cpu_block) {
+ #ifdef CONFIG_PREEMPTION
+                               preempt_schedule();
+-- 
+2.43.0
+
diff --git a/queue-6.9/scsi-qedi-fix-crash-while-reading-debugfs-attribute.patch b/queue-6.9/scsi-qedi-fix-crash-while-reading-debugfs-attribute.patch
new file mode 100644 (file)
index 0000000..c506664
--- /dev/null
@@ -0,0 +1,95 @@
+From d5f84b1883c070d96be55cfd7d0ae8e294faa7e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Apr 2024 12:51:55 +0530
+Subject: scsi: qedi: Fix crash while reading debugfs attribute
+
+From: Manish Rangankar <mrangankar@marvell.com>
+
+[ Upstream commit 28027ec8e32ecbadcd67623edb290dad61e735b5 ]
+
+The qedi_dbg_do_not_recover_cmd_read() function invokes sprintf() directly
+on a __user pointer, which results into the crash.
+
+To fix this issue, use a small local stack buffer for sprintf() and then
+call simple_read_from_buffer(), which in turns make the copy_to_user()
+call.
+
+BUG: unable to handle page fault for address: 00007f4801111000
+PGD 8000000864df6067 P4D 8000000864df6067 PUD 864df7067 PMD 846028067 PTE 0
+Oops: 0002 [#1] PREEMPT SMP PTI
+Hardware name: HPE ProLiant DL380 Gen10/ProLiant DL380 Gen10, BIOS U30 06/15/2023
+RIP: 0010:memcpy_orig+0xcd/0x130
+RSP: 0018:ffffb7a18c3ffc40 EFLAGS: 00010202
+RAX: 00007f4801111000 RBX: 00007f4801111000 RCX: 000000000000000f
+RDX: 000000000000000f RSI: ffffffffc0bfd7a0 RDI: 00007f4801111000
+RBP: ffffffffc0bfd7a0 R08: 725f746f6e5f6f64 R09: 3d7265766f636572
+R10: ffffb7a18c3ffd08 R11: 0000000000000000 R12: 00007f4881110fff
+R13: 000000007fffffff R14: ffffb7a18c3ffca0 R15: ffffffffc0bfd7af
+FS:  00007f480118a740(0000) GS:ffff98e38af00000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007f4801111000 CR3: 0000000864b8e001 CR4: 00000000007706e0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+PKRU: 55555554
+Call Trace:
+ <TASK>
+ ? __die_body+0x1a/0x60
+ ? page_fault_oops+0x183/0x510
+ ? exc_page_fault+0x69/0x150
+ ? asm_exc_page_fault+0x22/0x30
+ ? memcpy_orig+0xcd/0x130
+ vsnprintf+0x102/0x4c0
+ sprintf+0x51/0x80
+ qedi_dbg_do_not_recover_cmd_read+0x2f/0x50 [qedi 6bcfdeeecdea037da47069eca2ba717c84a77324]
+ full_proxy_read+0x50/0x80
+ vfs_read+0xa5/0x2e0
+ ? folio_add_new_anon_rmap+0x44/0xa0
+ ? set_pte_at+0x15/0x30
+ ? do_pte_missing+0x426/0x7f0
+ ksys_read+0xa5/0xe0
+ do_syscall_64+0x58/0x80
+ ? __count_memcg_events+0x46/0x90
+ ? count_memcg_event_mm+0x3d/0x60
+ ? handle_mm_fault+0x196/0x2f0
+ ? do_user_addr_fault+0x267/0x890
+ ? exc_page_fault+0x69/0x150
+ entry_SYSCALL_64_after_hwframe+0x72/0xdc
+RIP: 0033:0x7f4800f20b4d
+
+Tested-by: Martin Hoyer <mhoyer@redhat.com>
+Reviewed-by: John Meneghini <jmeneghi@redhat.com>
+Signed-off-by: Manish Rangankar <mrangankar@marvell.com>
+Link: https://lore.kernel.org/r/20240415072155.30840-1-mrangankar@marvell.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qedi/qedi_debugfs.c | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/scsi/qedi/qedi_debugfs.c b/drivers/scsi/qedi/qedi_debugfs.c
+index 8deb2001dc2ff..37eed6a278164 100644
+--- a/drivers/scsi/qedi/qedi_debugfs.c
++++ b/drivers/scsi/qedi/qedi_debugfs.c
+@@ -120,15 +120,11 @@ static ssize_t
+ qedi_dbg_do_not_recover_cmd_read(struct file *filp, char __user *buffer,
+                                size_t count, loff_t *ppos)
+ {
+-      size_t cnt = 0;
+-
+-      if (*ppos)
+-              return 0;
++      char buf[64];
++      int len;
+-      cnt = sprintf(buffer, "do_not_recover=%d\n", qedi_do_not_recover);
+-      cnt = min_t(int, count, cnt - *ppos);
+-      *ppos += cnt;
+-      return cnt;
++      len = sprintf(buf, "do_not_recover=%d\n", qedi_do_not_recover);
++      return simple_read_from_buffer(buffer, count, ppos, buf, len);
+ }
+ static int
+-- 
+2.43.0
+
diff --git a/queue-6.9/selftests-bpf-fix-flaky-test-btf_map_in_map-lookup_u.patch b/queue-6.9/selftests-bpf-fix-flaky-test-btf_map_in_map-lookup_u.patch
new file mode 100644 (file)
index 0000000..8db3d50
--- /dev/null
@@ -0,0 +1,87 @@
+From 8f9d7a670c37799c02afae3b08bcfbaf304a7a31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Mar 2024 23:13:53 -0700
+Subject: selftests/bpf: Fix flaky test btf_map_in_map/lookup_update
+
+From: Yonghong Song <yonghong.song@linux.dev>
+
+[ Upstream commit 14bb1e8c8d4ad5d9d2febb7d19c70a3cf536e1e5 ]
+
+Recently, I frequently hit the following test failure:
+
+  [root@arch-fb-vm1 bpf]# ./test_progs -n 33/1
+  test_lookup_update:PASS:skel_open 0 nsec
+  [...]
+  test_lookup_update:PASS:sync_rcu 0 nsec
+  test_lookup_update:FAIL:map1_leak inner_map1 leaked!
+  #33/1    btf_map_in_map/lookup_update:FAIL
+  #33      btf_map_in_map:FAIL
+
+In the test, after map is closed and then after two rcu grace periods,
+it is assumed that map_id is not available to user space.
+
+But the above assumption cannot be guaranteed. After zero or one
+or two rcu grace periods in different siturations, the actual
+freeing-map-work is put into a workqueue. Later on, when the work
+is dequeued, the map will be actually freed.
+See bpf_map_put() in kernel/bpf/syscall.c.
+
+By using workqueue, there is no ganrantee that map will be actually
+freed after a couple of rcu grace periods. This patch removed
+such map leak detection and then the test can pass consistently.
+
+Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/20240322061353.632136-1-yonghong.song@linux.dev
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/bpf/prog_tests/btf_map_in_map.c | 26 +------------------
+ 1 file changed, 1 insertion(+), 25 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/btf_map_in_map.c b/tools/testing/selftests/bpf/prog_tests/btf_map_in_map.c
+index a8b53b8736f01..f66ceccd7029c 100644
+--- a/tools/testing/selftests/bpf/prog_tests/btf_map_in_map.c
++++ b/tools/testing/selftests/bpf/prog_tests/btf_map_in_map.c
+@@ -25,7 +25,7 @@ static void test_lookup_update(void)
+       int map1_fd, map2_fd, map3_fd, map4_fd, map5_fd, map1_id, map2_id;
+       int outer_arr_fd, outer_hash_fd, outer_arr_dyn_fd;
+       struct test_btf_map_in_map *skel;
+-      int err, key = 0, val, i, fd;
++      int err, key = 0, val, i;
+       skel = test_btf_map_in_map__open_and_load();
+       if (CHECK(!skel, "skel_open", "failed to open&load skeleton\n"))
+@@ -102,30 +102,6 @@ static void test_lookup_update(void)
+       CHECK(map1_id == 0, "map1_id", "failed to get ID 1\n");
+       CHECK(map2_id == 0, "map2_id", "failed to get ID 2\n");
+-      test_btf_map_in_map__destroy(skel);
+-      skel = NULL;
+-
+-      /* we need to either wait for or force synchronize_rcu(), before
+-       * checking for "still exists" condition, otherwise map could still be
+-       * resolvable by ID, causing false positives.
+-       *
+-       * Older kernels (5.8 and earlier) freed map only after two
+-       * synchronize_rcu()s, so trigger two, to be entirely sure.
+-       */
+-      CHECK(kern_sync_rcu(), "sync_rcu", "failed\n");
+-      CHECK(kern_sync_rcu(), "sync_rcu", "failed\n");
+-
+-      fd = bpf_map_get_fd_by_id(map1_id);
+-      if (CHECK(fd >= 0, "map1_leak", "inner_map1 leaked!\n")) {
+-              close(fd);
+-              goto cleanup;
+-      }
+-      fd = bpf_map_get_fd_by_id(map2_id);
+-      if (CHECK(fd >= 0, "map2_leak", "inner_map2 leaked!\n")) {
+-              close(fd);
+-              goto cleanup;
+-      }
+-
+ cleanup:
+       test_btf_map_in_map__destroy(skel);
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.9/selftests-bpf-prevent-client-connect-before-server-b.patch b/queue-6.9/selftests-bpf-prevent-client-connect-before-server-b.patch
new file mode 100644 (file)
index 0000000..7a0df25
--- /dev/null
@@ -0,0 +1,82 @@
+From fcdead2be0213e0f6cc0a36d5fad0e84a4c372aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Mar 2024 10:59:11 +0000
+Subject: selftests/bpf: Prevent client connect before server bind in
+ test_tc_tunnel.sh
+
+From: Alessandro Carminati (Red Hat) <alessandro.carminati@gmail.com>
+
+[ Upstream commit f803bcf9208a2540acb4c32bdc3616673169f490 ]
+
+In some systems, the netcat server can incur in delay to start listening.
+When this happens, the test can randomly fail in various points.
+This is an example error message:
+
+   # ip gre none gso
+   # encap 192.168.1.1 to 192.168.1.2, type gre, mac none len 2000
+   # test basic connectivity
+   # Ncat: Connection refused.
+
+The issue stems from a race condition between the netcat client and server.
+The test author had addressed this problem by implementing a sleep, which
+I have removed in this patch.
+This patch introduces a function capable of sleeping for up to two seconds.
+However, it can terminate the waiting period early if the port is reported
+to be listening.
+
+Signed-off-by: Alessandro Carminati (Red Hat) <alessandro.carminati@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20240314105911.213411-1-alessandro.carminati@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/test_tc_tunnel.sh | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/bpf/test_tc_tunnel.sh b/tools/testing/selftests/bpf/test_tc_tunnel.sh
+index 910044f08908a..7989ec6084545 100755
+--- a/tools/testing/selftests/bpf/test_tc_tunnel.sh
++++ b/tools/testing/selftests/bpf/test_tc_tunnel.sh
+@@ -72,7 +72,6 @@ cleanup() {
+ server_listen() {
+       ip netns exec "${ns2}" nc "${netcat_opt}" -l "${port}" > "${outfile}" &
+       server_pid=$!
+-      sleep 0.2
+ }
+ client_connect() {
+@@ -93,6 +92,16 @@ verify_data() {
+       fi
+ }
++wait_for_port() {
++      for i in $(seq 20); do
++              if ip netns exec "${ns2}" ss ${2:--4}OHntl | grep -q "$1"; then
++                      return 0
++              fi
++              sleep 0.1
++      done
++      return 1
++}
++
+ set -e
+ # no arguments: automated test, run all
+@@ -193,6 +202,7 @@ setup
+ # basic communication works
+ echo "test basic connectivity"
+ server_listen
++wait_for_port ${port} ${netcat_opt}
+ client_connect
+ verify_data
+@@ -204,6 +214,7 @@ ip netns exec "${ns1}" tc filter add dev veth1 egress \
+       section "encap_${tuntype}_${mac}"
+ echo "test bpf encap without decap (expect failure)"
+ server_listen
++wait_for_port ${port} ${netcat_opt}
+ ! client_connect
+ if [[ "$tuntype" =~ "udp" ]]; then
+-- 
+2.43.0
+
diff --git a/queue-6.9/selftests-net-fix-timestamp-not-arriving-in-cmsg_tim.patch b/queue-6.9/selftests-net-fix-timestamp-not-arriving-in-cmsg_tim.patch
new file mode 100644 (file)
index 0000000..4114cf2
--- /dev/null
@@ -0,0 +1,87 @@
+From 5b150f5c3c0720deb7ead7ce2d524ddc47985ac1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 May 2024 17:57:04 -0700
+Subject: selftests: net: fix timestamp not arriving in cmsg_time.sh
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 2d3b8dfd82d76b1295167c6453d683ab99e50794 ]
+
+On slow machines the SND timestamp sometimes doesn't arrive before
+we quit. The test only waits as long as the packet delay, so it's
+easy for a race condition to happen.
+
+Double the wait but do a bit of polling, once the SND timestamp
+arrives there's no point to wait any longer.
+
+This fixes the "TXTIME abs" failures on debug kernels, like:
+
+   Case ICMPv4  - TXTIME abs returned '', expected 'OK'
+
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://lore.kernel.org/r/20240510005705.43069-1-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/cmsg_sender.c | 20 +++++++++++++++-----
+ 1 file changed, 15 insertions(+), 5 deletions(-)
+
+diff --git a/tools/testing/selftests/net/cmsg_sender.c b/tools/testing/selftests/net/cmsg_sender.c
+index c79e65581dc37..161db24e3c409 100644
+--- a/tools/testing/selftests/net/cmsg_sender.c
++++ b/tools/testing/selftests/net/cmsg_sender.c
+@@ -333,16 +333,17 @@ static const char *cs_ts_info2str(unsigned int info)
+       return "unknown";
+ }
+-static void
++static unsigned long
+ cs_read_cmsg(int fd, struct msghdr *msg, char *cbuf, size_t cbuf_sz)
+ {
+       struct sock_extended_err *see;
+       struct scm_timestamping *ts;
++      unsigned long ts_seen = 0;
+       struct cmsghdr *cmsg;
+       int i, err;
+       if (!opt.ts.ena)
+-              return;
++              return 0;
+       msg->msg_control = cbuf;
+       msg->msg_controllen = cbuf_sz;
+@@ -396,8 +397,11 @@ cs_read_cmsg(int fd, struct msghdr *msg, char *cbuf, size_t cbuf_sz)
+                       printf(" %5s ts%d %lluus\n",
+                              cs_ts_info2str(see->ee_info),
+                              i, rel_time);
++                      ts_seen |= 1 << see->ee_info;
+               }
+       }
++
++      return ts_seen;
+ }
+ static void ca_set_sockopts(int fd)
+@@ -509,10 +513,16 @@ int main(int argc, char *argv[])
+       err = ERN_SUCCESS;
+       if (opt.ts.ena) {
+-              /* Make sure all timestamps have time to loop back */
+-              usleep(opt.txtime.delay);
++              unsigned long seen;
++              int i;
+-              cs_read_cmsg(fd, &msg, cbuf, sizeof(cbuf));
++              /* Make sure all timestamps have time to loop back */
++              for (i = 0; i < 40; i++) {
++                      seen = cs_read_cmsg(fd, &msg, cbuf, sizeof(cbuf));
++                      if (seen & (1 << SCM_TSTAMP_SND))
++                              break;
++                      usleep(opt.txtime.delay / 20);
++              }
+       }
+ err_out:
+-- 
+2.43.0
+
diff --git a/queue-6.9/serial-exar-adding-missing-cti-and-exar-pci-ids.patch b/queue-6.9/serial-exar-adding-missing-cti-and-exar-pci-ids.patch
new file mode 100644 (file)
index 0000000..478f7b1
--- /dev/null
@@ -0,0 +1,77 @@
+From 83bc5789898b3af50cf860c526ca669585477d23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Apr 2024 08:55:28 -0400
+Subject: serial: exar: adding missing CTI and Exar PCI ids
+
+From: Parker Newman <pnewman@connecttech.com>
+
+[ Upstream commit b86ae40ffcf5a16b9569b1016da4a08c4f352ca2 ]
+
+- Added Connect Tech and Exar IDs not already in pci_ids.h
+
+Signed-off-by: Parker Newman <pnewman@connecttech.com>
+Link: https://lore.kernel.org/r/7c3d8e795a864dd9b0a00353b722060dc27c4e09.1713270624.git.pnewman@connecttech.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/8250/8250_exar.c | 42 +++++++++++++++++++++++++++++
+ 1 file changed, 42 insertions(+)
+
+diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c
+index 0440df7de1ed7..4d1e07343d0bb 100644
+--- a/drivers/tty/serial/8250/8250_exar.c
++++ b/drivers/tty/serial/8250/8250_exar.c
+@@ -46,8 +46,50 @@
+ #define PCI_DEVICE_ID_COMMTECH_4228PCIE               0x0021
+ #define PCI_DEVICE_ID_COMMTECH_4222PCIE               0x0022
++#define PCI_VENDOR_ID_CONNECT_TECH                            0x12c4
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_SP_OPTO        0x0340
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_SP_OPTO_A      0x0341
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_SP_OPTO_B      0x0342
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_XPRS           0x0350
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XPRS_A         0x0351
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XPRS_B         0x0352
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_XPRS           0x0353
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_16_XPRS_A        0x0354
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_16_XPRS_B        0x0355
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_XPRS_OPTO      0x0360
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XPRS_OPTO_A    0x0361
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XPRS_OPTO_B    0x0362
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_SP             0x0370
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_SP_232         0x0371
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_SP_485         0x0372
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_4_SP           0x0373
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_6_2_SP           0x0374
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_6_SP           0x0375
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_SP_232_NS      0x0376
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_XP_OPTO_LEFT   0x0380
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_XP_OPTO_RIGHT  0x0381
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XP_OPTO        0x0382
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_4_XPRS_OPTO    0x0392
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_XPRS_LP        0x03A0
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_XPRS_LP_232    0x03A1
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_XPRS_LP_485    0x03A2
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_XPRS_LP_232_NS 0x03A3
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XEG001               0x0602
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XR35X_BASE           0x1000
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XR35X_2              0x1002
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XR35X_4              0x1004
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XR35X_8              0x1008
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XR35X_12             0x100C
++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XR35X_16             0x1010
++#define PCI_DEVICE_ID_CONNECT_TECH_PCI_XR79X_12_XIG00X          0x110c
++#define PCI_DEVICE_ID_CONNECT_TECH_PCI_XR79X_12_XIG01X          0x110d
++#define PCI_DEVICE_ID_CONNECT_TECH_PCI_XR79X_16                 0x1110
++
+ #define PCI_DEVICE_ID_EXAR_XR17V4358          0x4358
+ #define PCI_DEVICE_ID_EXAR_XR17V8358          0x8358
++#define PCI_DEVICE_ID_EXAR_XR17V252           0x0252
++#define PCI_DEVICE_ID_EXAR_XR17V254           0x0254
++#define PCI_DEVICE_ID_EXAR_XR17V258           0x0258
+ #define PCI_SUBDEVICE_ID_USR_2980             0x0128
+ #define PCI_SUBDEVICE_ID_USR_2981             0x0129
+-- 
+2.43.0
+
diff --git a/queue-6.9/serial-imx-introduce-timeout-when-waiting-on-transmi.patch b/queue-6.9/serial-imx-introduce-timeout-when-waiting-on-transmi.patch
new file mode 100644 (file)
index 0000000..0b20c99
--- /dev/null
@@ -0,0 +1,59 @@
+From 947102742d5ab0c72a647568ecb2487cc46067a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Apr 2024 14:19:23 +0200
+Subject: serial: imx: Introduce timeout when waiting on transmitter empty
+
+From: Esben Haabendal <esben@geanix.com>
+
+[ Upstream commit e533e4c62e9993e62e947ae9bbec34e4c7ae81c2 ]
+
+By waiting at most 1 second for USR2_TXDC to be set, we avoid a potential
+deadlock.
+
+In case of the timeout, there is not much we can do, so we simply ignore
+the transmitter state and optimistically try to continue.
+
+Signed-off-by: Esben Haabendal <esben@geanix.com>
+Acked-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Link: https://lore.kernel.org/r/919647898c337a46604edcabaf13d42d80c0915d.1712837613.git.esben@geanix.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/imx.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
+index e148132506161..09c1678ddfd49 100644
+--- a/drivers/tty/serial/imx.c
++++ b/drivers/tty/serial/imx.c
+@@ -26,6 +26,7 @@
+ #include <linux/slab.h>
+ #include <linux/of.h>
+ #include <linux/io.h>
++#include <linux/iopoll.h>
+ #include <linux/dma-mapping.h>
+ #include <asm/irq.h>
+@@ -2010,7 +2011,7 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count)
+       struct imx_port *sport = imx_uart_ports[co->index];
+       struct imx_port_ucrs old_ucr;
+       unsigned long flags;
+-      unsigned int ucr1;
++      unsigned int ucr1, usr2;
+       int locked = 1;
+       if (sport->port.sysrq)
+@@ -2041,8 +2042,8 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count)
+        *      Finally, wait for transmitter to become empty
+        *      and restore UCR1/2/3
+        */
+-      while (!(imx_uart_readl(sport, USR2) & USR2_TXDC));
+-
++      read_poll_timeout_atomic(imx_uart_readl, usr2, usr2 & USR2_TXDC,
++                               0, USEC_PER_SEC, false, sport, USR2);
+       imx_uart_ucrs_restore(sport, &old_ucr);
+       if (locked)
+-- 
+2.43.0
+
diff --git a/queue-6.9/series b/queue-6.9/series
new file mode 100644 (file)
index 0000000..630f26a
--- /dev/null
@@ -0,0 +1,95 @@
+fs-writeback-bail-out-if-there-is-no-more-inodes-for.patch
+padata-disable-bh-when-taking-works-lock-on-mt-path.patch
+crypto-hisilicon-sec-fix-memory-leak-for-sec-resourc.patch
+crypto-hisilicon-qm-add-the-err-memory-release-proce.patch
+io_uring-sqpoll-work-around-a-potential-audit-memory.patch
+rcutorture-fix-rcu_torture_one_read-pipe_count-overf.patch
+rcutorture-make-stall-tasks-directly-exit-when-rcuto.patch
+rcutorture-fix-invalid-context-warning-when-enable-s.patch
+platform-chrome-cros_usbpd_logger-provide-id-table-f.patch
+platform-chrome-cros_usbpd_notify-provide-id-table-f.patch
+ubsan-avoid-i386-ubsan-handler-crashes-with-clang.patch
+arm64-defconfig-select-interconnect_qcom_sm6115-as-b.patch
+block-ioctl-prefer-different-overflow-check.patch
+ssb-fix-potential-null-pointer-dereference-in-ssb_de.patch
+selftests-bpf-prevent-client-connect-before-server-b.patch
+selftests-bpf-fix-flaky-test-btf_map_in_map-lookup_u.patch
+bpf-avoid-kfree_rcu-under-lock-in-bpf_lpm_trie.patch
+devlink-use-kvzalloc-to-allocate-devlink-instance-re.patch
+batman-adv-bypass-empty-buckets-in-batadv_purge_orig.patch
+wifi-rtw89-8852c-add-quirk-to-set-pci-ber-for-certai.patch
+wifi-ath9k-work-around-memset-overflow-warning.patch
+af_packet-avoid-a-false-positive-warning-in-packet_s.patch
+clocksource-make-watchdog-and-suspend-timing-multipl.patch
+acpi-x86-add-pnp_uart1_skip-quirk-for-lenovo-blade2-.patch
+drop_monitor-replace-spin_lock-by-raw_spin_lock.patch
+acpi-resource-do-irq-override-on-gmxbgxx-xmg-apex-17.patch
+wifi-ath12k-fix-kernel-crash-during-resume.patch
+scsi-qedi-fix-crash-while-reading-debugfs-attribute.patch
+net-sfp-enhance-quirk-for-fibrestore-2.5g-copper-sfp.patch
+net-sfp-add-quirk-for-ats-sfp-ge-t-1000base-tx-modul.patch
+net-sched-fix-false-lockdep-warning-on-qdisc-root-lo.patch
+arm64-sysreg-update-pie-permission-encodings.patch
+kselftest-arm64-add-a-null-pointer-check.patch
+net-dsa-realtek-keep-default-led-state-in-rtl8366rb.patch
+net-dsa-realtek-do-not-assert-reset-on-remove.patch
+acpi-resource-skip-irq-override-on-asus-vivobook-pro.patch
+netpoll-fix-race-condition-in-netpoll_owner_active.patch
+wifi-ath12k-fix-the-problem-that-down-grade-phy-mode.patch
+wifi-mt76-mt7921s-fix-potential-hung-tasks-during-ch.patch
+hid-add-quirk-for-logitech-casa-touchpad.patch
+hid-asus-fix-more-n-key-report-descriptors-if-n-key-.patch
+acpi-video-add-backlight-native-quirk-for-lenovo-sli.patch
+bpf-avoid-uninitialized-warnings-in-verifier_global_.patch
+selftests-net-fix-timestamp-not-arriving-in-cmsg_tim.patch
+net-ena-add-validation-for-completion-descriptors-co.patch
+bluetooth-ath3k-fix-multiple-issues-reported-by-chec.patch
+drm-amd-display-exit-idle-optimizations-before-hdcp-.patch
+drm-amd-display-workaround-register-access-in-idle-r.patch
+asoc-intel-sof_cs42l42-rename-bt-offload-quirk.patch
+platform-x86-toshiba_acpi-add-quirk-for-buttons-on-z.patch
+cgroup-cpuset-make-cpuset-hotplug-processing-synchro.patch
+asoc-intel-sof_sdw-add-jd2-quirk-for-hp-omen-14.patch
+asoc-intel-sof_sdw-add-quirk-for-dell-sku-0c0f.patch
+drm-lima-add-mask-irq-callback-to-gp-and-pp.patch
+drm-lima-include-pp-bcast-irq-in-timeout-handler-che.patch
+drm-lima-mask-irqs-in-timeout-path-before-hard-reset.patch
+platform-x86-x86-android-tablets-unregister-devices-.patch
+platform-x86-x86-android-tablets-add-lenovo-yoga-tab.patch
+alsa-hda-realtek-add-quirks-for-hp-omen-models-using.patch
+alsa-hda-realtek-add-quirks-for-lenovo-13x.patch
+powerpc-pseries-enforce-hcall-result-buffer-validity.patch
+media-intel-ipu6-fix-build-with-acpi.patch
+media-mtk-vcodec-potential-null-pointer-deference-in.patch
+powerpc-io-avoid-clang-null-pointer-arithmetic-warni.patch
+platform-x86-p2sb-don-t-init-until-unassigned-resour.patch
+power-supply-cros_usbpd-provide-id-table-for-avoidin.patch
+iommu-arm-smmu-v3-free-msis-in-case-of-enomem.patch
+ext4-do-not-create-ea-inode-under-buffer-lock.patch
+ext4-fix-uninitialized-ratelimit_state-lock-access-i.patch
+kprobe-ftrace-bail-out-if-ftrace-was-killed.patch
+usb-gadget-uvc-configfs-ensure-guid-to-be-valid-befo.patch
+f2fs-fix-to-detect-inconsistent-nat-entry-during-tru.patch
+f2fs-remove-clear-sb_inlinecrypt-flag-in-default_opt.patch
+usb-typec-ucsi_glink-rework-quirks-implementation.patch
+usb-misc-uss720-check-for-incompatible-versions-of-t.patch
+avoid-hw_desc-array-overrun-in-dw-axi-dmac.patch
+usb-dwc3-pci-don-t-set-linux-phy_charger_detect-prop.patch
+usb-typec-ucsi_glink-drop-special-handling-for-cci_b.patch
+udf-udftime-prevent-overflow-in-udf_disk_stamp_to_ti.patch
+pci-pm-avoid-d3cold-for-hp-pavilion-17-pc-1972-pcie-.patch
+f2fs-don-t-set-ro-when-shutting-down-f2fs.patch
+mips-octeon-add-pcie-link-status-check.patch
+serial-imx-introduce-timeout-when-waiting-on-transmi.patch
+serial-exar-adding-missing-cti-and-exar-pci-ids.patch
+usb-gadget-function-remove-usage-of-the-deprecated-i.patch
+xhci-remove-xhci_trust_tx_length-quirk.patch
+tty-add-the-option-to-have-a-tty-reject-a-new-ldisc.patch
+i2c-lpi2c-avoid-calling-clk_get_rate-during-transfer.patch
+cxl-add-post-reset-warning-if-reset-results-in-loss-.patch
+vfio-pci-collect-hot-reset-devices-to-local-buffer.patch
+usb-typec-qcom-pmic-typec-split-hpd-bridge-alloc-and.patch
+cpufreq-amd-pstate-fix-memory-leak-on-cpu-epp-exit.patch
+acpi-ec-install-address-space-handler-at-the-namespa.patch
+pci-do-not-wait-for-disconnected-devices-when-resumi.patch
+opp-fix-required_opp_tables-for-multiple-genpds-usin.patch
diff --git a/queue-6.9/ssb-fix-potential-null-pointer-dereference-in-ssb_de.patch b/queue-6.9/ssb-fix-potential-null-pointer-dereference-in-ssb_de.patch
new file mode 100644 (file)
index 0000000..cfa6a47
--- /dev/null
@@ -0,0 +1,49 @@
+From c2160c392def5c5cdb01841dc330f992598bcbaf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Mar 2024 15:30:28 +0300
+Subject: ssb: Fix potential NULL pointer dereference in ssb_device_uevent()
+
+From: Rand Deeb <rand.sec96@gmail.com>
+
+[ Upstream commit 789c17185fb0f39560496c2beab9b57ce1d0cbe7 ]
+
+The ssb_device_uevent() function first attempts to convert the 'dev' pointer
+to 'struct ssb_device *'. However, it mistakenly dereferences 'dev' before
+performing the NULL check, potentially leading to a NULL pointer
+dereference if 'dev' is NULL.
+
+To fix this issue, move the NULL check before dereferencing the 'dev' pointer,
+ensuring that the pointer is valid before attempting to use it.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Signed-off-by: Rand Deeb <rand.sec96@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20240306123028.164155-1-rand.sec96@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ssb/main.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
+index 9f30e0edadfe2..bdb6595ffd2d5 100644
+--- a/drivers/ssb/main.c
++++ b/drivers/ssb/main.c
+@@ -341,11 +341,13 @@ static int ssb_bus_match(struct device *dev, struct device_driver *drv)
+ static int ssb_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
+ {
+-      const struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
++      const struct ssb_device *ssb_dev;
+       if (!dev)
+               return -ENODEV;
++      ssb_dev = dev_to_ssb_dev(dev);
++
+       return add_uevent_var(env,
+                            "MODALIAS=ssb:v%04Xid%04Xrev%02X",
+                            ssb_dev->id.vendor, ssb_dev->id.coreid,
+-- 
+2.43.0
+
diff --git a/queue-6.9/tty-add-the-option-to-have-a-tty-reject-a-new-ldisc.patch b/queue-6.9/tty-add-the-option-to-have-a-tty-reject-a-new-ldisc.patch
new file mode 100644 (file)
index 0000000..2239ed1
--- /dev/null
@@ -0,0 +1,111 @@
+From 1905ff16da0c10f232742a229e378e53d7083cbe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Apr 2024 09:33:39 -0700
+Subject: tty: add the option to have a tty reject a new ldisc
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+[ Upstream commit 6bd23e0c2bb6c65d4f5754d1456bc9a4427fc59b ]
+
+... and use it to limit the virtual terminals to just N_TTY.  They are
+kind of special, and in particular, the "con_write()" routine violates
+the "writes cannot sleep" rule that some ldiscs rely on.
+
+This avoids the
+
+   BUG: sleeping function called from invalid context at kernel/printk/printk.c:2659
+
+when N_GSM has been attached to a virtual console, and gsmld_write()
+calls con_write() while holding a spinlock, and con_write() then tries
+to get the console lock.
+
+Tested-by: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
+Cc: Jiri Slaby <jirislaby@kernel.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Daniel Starke <daniel.starke@siemens.com>
+Reported-by: syzbot <syzbot+dbac96d8e73b61aa559c@syzkaller.appspotmail.com>
+Closes: https://syzkaller.appspot.com/bug?extid=dbac96d8e73b61aa559c
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Link: https://lore.kernel.org/r/20240423163339.59780-1-torvalds@linux-foundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/tty_ldisc.c    |  6 ++++++
+ drivers/tty/vt/vt.c        | 10 ++++++++++
+ include/linux/tty_driver.h |  8 ++++++++
+ 3 files changed, 24 insertions(+)
+
+diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
+index 3f68e213df1f7..d80e9d4c974b4 100644
+--- a/drivers/tty/tty_ldisc.c
++++ b/drivers/tty/tty_ldisc.c
+@@ -545,6 +545,12 @@ int tty_set_ldisc(struct tty_struct *tty, int disc)
+               goto out;
+       }
++      if (tty->ops->ldisc_ok) {
++              retval = tty->ops->ldisc_ok(tty, disc);
++              if (retval)
++                      goto out;
++      }
++
+       old_ldisc = tty->ldisc;
+       /* Shutdown the old discipline. */
+diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
+index 9b5b98dfc8b40..cd87e3d1291ed 100644
+--- a/drivers/tty/vt/vt.c
++++ b/drivers/tty/vt/vt.c
+@@ -3576,6 +3576,15 @@ static void con_cleanup(struct tty_struct *tty)
+       tty_port_put(&vc->port);
+ }
++/*
++ * We can't deal with anything but the N_TTY ldisc,
++ * because we can sleep in our write() routine.
++ */
++static int con_ldisc_ok(struct tty_struct *tty, int ldisc)
++{
++      return ldisc == N_TTY ? 0 : -EINVAL;
++}
++
+ static int default_color           = 7; /* white */
+ static int default_italic_color    = 2; // green (ASCII)
+ static int default_underline_color = 3; // cyan (ASCII)
+@@ -3695,6 +3704,7 @@ static const struct tty_operations con_ops = {
+       .resize = vt_resize,
+       .shutdown = con_shutdown,
+       .cleanup = con_cleanup,
++      .ldisc_ok = con_ldisc_ok,
+ };
+ static struct cdev vc0_cdev;
+diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
+index 7372124fbf90b..dd4b31ce6d5d4 100644
+--- a/include/linux/tty_driver.h
++++ b/include/linux/tty_driver.h
+@@ -154,6 +154,13 @@ struct serial_struct;
+  *
+  *    Optional. Called under the @tty->termios_rwsem. May sleep.
+  *
++ * @ldisc_ok: ``int ()(struct tty_struct *tty, int ldisc)``
++ *
++ *    This routine allows the @tty driver to decide if it can deal
++ *    with a particular @ldisc.
++ *
++ *    Optional. Called under the @tty->ldisc_sem and @tty->termios_rwsem.
++ *
+  * @set_ldisc: ``void ()(struct tty_struct *tty)``
+  *
+  *    This routine allows the @tty driver to be notified when the device's
+@@ -372,6 +379,7 @@ struct tty_operations {
+       void (*hangup)(struct tty_struct *tty);
+       int (*break_ctl)(struct tty_struct *tty, int state);
+       void (*flush_buffer)(struct tty_struct *tty);
++      int (*ldisc_ok)(struct tty_struct *tty, int ldisc);
+       void (*set_ldisc)(struct tty_struct *tty);
+       void (*wait_until_sent)(struct tty_struct *tty, int timeout);
+       void (*send_xchar)(struct tty_struct *tty, u8 ch);
+-- 
+2.43.0
+
diff --git a/queue-6.9/ubsan-avoid-i386-ubsan-handler-crashes-with-clang.patch b/queue-6.9/ubsan-avoid-i386-ubsan-handler-crashes-with-clang.patch
new file mode 100644 (file)
index 0000000..babd415
--- /dev/null
@@ -0,0 +1,80 @@
+From 17194c5969bda0b0b334ae20df8c7710fd3ad36d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Apr 2024 15:40:29 -0700
+Subject: ubsan: Avoid i386 UBSAN handler crashes with Clang
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit 2e431b23a13ce4459cf484c8f0b3218c7048b515 ]
+
+When generating Runtime Calls, Clang doesn't respect the -mregparm=3
+option used on i386. Hopefully this will be fixed correctly in Clang 19:
+https://github.com/llvm/llvm-project/pull/89707
+but we need to fix this for earlier Clang versions today. Force the
+calling convention to use non-register arguments.
+
+Reported-by: Erhard Furtner <erhard_f@mailbox.org>
+Closes: https://github.com/KSPP/linux/issues/350
+Link: https://lore.kernel.org/r/20240424224026.it.216-kees@kernel.org
+Acked-by: Nathan Chancellor <nathan@kernel.org>
+Acked-by: Justin Stitt <justinstitt@google.com>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/ubsan.h | 41 +++++++++++++++++++++++++++--------------
+ 1 file changed, 27 insertions(+), 14 deletions(-)
+
+diff --git a/lib/ubsan.h b/lib/ubsan.h
+index 0abbbac8700d1..0982578fbd98f 100644
+--- a/lib/ubsan.h
++++ b/lib/ubsan.h
+@@ -124,19 +124,32 @@ typedef s64 s_max;
+ typedef u64 u_max;
+ #endif
+-void __ubsan_handle_add_overflow(void *data, void *lhs, void *rhs);
+-void __ubsan_handle_sub_overflow(void *data, void *lhs, void *rhs);
+-void __ubsan_handle_mul_overflow(void *data, void *lhs, void *rhs);
+-void __ubsan_handle_negate_overflow(void *_data, void *old_val);
+-void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs);
+-void __ubsan_handle_type_mismatch(struct type_mismatch_data *data, void *ptr);
+-void __ubsan_handle_type_mismatch_v1(void *_data, void *ptr);
+-void __ubsan_handle_out_of_bounds(void *_data, void *index);
+-void __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs);
+-void __ubsan_handle_builtin_unreachable(void *_data);
+-void __ubsan_handle_load_invalid_value(void *_data, void *val);
+-void __ubsan_handle_alignment_assumption(void *_data, unsigned long ptr,
+-                                       unsigned long align,
+-                                       unsigned long offset);
++/*
++ * When generating Runtime Calls, Clang doesn't respect the -mregparm=3
++ * option used on i386: https://github.com/llvm/llvm-project/issues/89670
++ * Fix this for earlier Clang versions by forcing the calling convention
++ * to use non-register arguments.
++ */
++#if defined(CONFIG_X86_32) && \
++    defined(CONFIG_CC_IS_CLANG) && CONFIG_CLANG_VERSION < 190000
++# define ubsan_linkage asmlinkage
++#else
++# define ubsan_linkage
++#endif
++
++void ubsan_linkage __ubsan_handle_add_overflow(void *data, void *lhs, void *rhs);
++void ubsan_linkage __ubsan_handle_sub_overflow(void *data, void *lhs, void *rhs);
++void ubsan_linkage __ubsan_handle_mul_overflow(void *data, void *lhs, void *rhs);
++void ubsan_linkage __ubsan_handle_negate_overflow(void *_data, void *old_val);
++void ubsan_linkage __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs);
++void ubsan_linkage __ubsan_handle_type_mismatch(struct type_mismatch_data *data, void *ptr);
++void ubsan_linkage __ubsan_handle_type_mismatch_v1(void *_data, void *ptr);
++void ubsan_linkage __ubsan_handle_out_of_bounds(void *_data, void *index);
++void ubsan_linkage __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs);
++void ubsan_linkage __ubsan_handle_builtin_unreachable(void *_data);
++void ubsan_linkage __ubsan_handle_load_invalid_value(void *_data, void *val);
++void ubsan_linkage __ubsan_handle_alignment_assumption(void *_data, unsigned long ptr,
++                                                     unsigned long align,
++                                                     unsigned long offset);
+ #endif
+-- 
+2.43.0
+
diff --git a/queue-6.9/udf-udftime-prevent-overflow-in-udf_disk_stamp_to_ti.patch b/queue-6.9/udf-udftime-prevent-overflow-in-udf_disk_stamp_to_ti.patch
new file mode 100644 (file)
index 0000000..389f978
--- /dev/null
@@ -0,0 +1,54 @@
+From 0a98a71e1e66e92ac3c930a5d36a749867a22f20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Mar 2024 16:27:55 +0300
+Subject: udf: udftime: prevent overflow in udf_disk_stamp_to_time()
+
+From: Roman Smirnov <r.smirnov@omp.ru>
+
+[ Upstream commit 3b84adf460381169c085e4bc09e7b57e9e16db0a ]
+
+An overflow can occur in a situation where src.centiseconds
+takes the value of 255. This situation is unlikely, but there
+is no validation check anywere in the code.
+
+Found by Linux Verification Center (linuxtesting.org) with Svace.
+
+Suggested-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Roman Smirnov <r.smirnov@omp.ru>
+Reviewed-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Message-Id: <20240327132755.13945-1-r.smirnov@omp.ru>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/udf/udftime.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c
+index 758163af39c26..78ecc633606fb 100644
+--- a/fs/udf/udftime.c
++++ b/fs/udf/udftime.c
+@@ -46,13 +46,18 @@ udf_disk_stamp_to_time(struct timespec64 *dest, struct timestamp src)
+       dest->tv_sec = mktime64(year, src.month, src.day, src.hour, src.minute,
+                       src.second);
+       dest->tv_sec -= offset * 60;
+-      dest->tv_nsec = 1000 * (src.centiseconds * 10000 +
+-                      src.hundredsOfMicroseconds * 100 + src.microseconds);
++
+       /*
+        * Sanitize nanosecond field since reportedly some filesystems are
+        * recorded with bogus sub-second values.
+        */
+-      dest->tv_nsec %= NSEC_PER_SEC;
++      if (src.centiseconds < 100 && src.hundredsOfMicroseconds < 100 &&
++          src.microseconds < 100) {
++              dest->tv_nsec = 1000 * (src.centiseconds * 10000 +
++                      src.hundredsOfMicroseconds * 100 + src.microseconds);
++      } else {
++              dest->tv_nsec = 0;
++      }
+ }
+ void
+-- 
+2.43.0
+
diff --git a/queue-6.9/usb-dwc3-pci-don-t-set-linux-phy_charger_detect-prop.patch b/queue-6.9/usb-dwc3-pci-don-t-set-linux-phy_charger_detect-prop.patch
new file mode 100644 (file)
index 0000000..f15d7c7
--- /dev/null
@@ -0,0 +1,68 @@
+From e00d6d5cd833d18574930d535667f34244f9d258 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Apr 2024 16:01:27 +0200
+Subject: usb: dwc3: pci: Don't set "linux,phy_charger_detect" property on
+ Lenovo Yoga Tab2 1380
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 0fb782b5d5c462b2518b3b4fe7d652114c28d613 ]
+
+The Lenovo Yoga Tablet 2 Pro 1380 model is the exception to the rule that
+devices which use the Crystal Cove PMIC without using ACPI for battery and
+AC power_supply class support use the USB-phy for charger detection.
+
+Unlike the Lenovo Yoga Tablet 2 830 / 1050 models this model has an extra
+LC824206XA Micro USB switch which does the charger detection.
+
+Add a DMI quirk to not set the "linux,phy_charger_detect" property on
+the 1380 model. This quirk matches on the BIOS version to differentiate
+the 1380 model from the 830 and 1050 models which otherwise have
+the same DMI strings.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/20240406140127.17885-1-hdegoede@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/dwc3-pci.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
+index 497deed38c0c1..9ef821ca2fc71 100644
+--- a/drivers/usb/dwc3/dwc3-pci.c
++++ b/drivers/usb/dwc3/dwc3-pci.c
+@@ -8,6 +8,7 @@
+  *        Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+  */
++#include <linux/dmi.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
+@@ -220,6 +221,7 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc,
+               if (pdev->device == PCI_DEVICE_ID_INTEL_BYT) {
+                       struct gpio_desc *gpio;
++                      const char *bios_ver;
+                       int ret;
+                       /* On BYT the FW does not always enable the refclock */
+@@ -277,8 +279,12 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc,
+                        * detection. These can be identified by them _not_
+                        * using the standard ACPI battery and ac drivers.
+                        */
++                      bios_ver = dmi_get_system_info(DMI_BIOS_VERSION);
+                       if (acpi_dev_present("INT33FD", "1", 2) &&
+-                          acpi_quirk_skip_acpi_ac_and_battery()) {
++                          acpi_quirk_skip_acpi_ac_and_battery() &&
++                          /* Lenovo Yoga Tablet 2 Pro 1380 uses LC824206XA instead */
++                          !(bios_ver &&
++                            strstarts(bios_ver, "BLADE_21.X64.0005.R00.1504101516"))) {
+                               dev_info(&pdev->dev, "Using TUSB1211 phy for charger detection\n");
+                               swnode = &dwc3_pci_intel_phy_charger_detect_swnode;
+                       }
+-- 
+2.43.0
+
diff --git a/queue-6.9/usb-gadget-function-remove-usage-of-the-deprecated-i.patch b/queue-6.9/usb-gadget-function-remove-usage-of-the-deprecated-i.patch
new file mode 100644 (file)
index 0000000..acefd0d
--- /dev/null
@@ -0,0 +1,98 @@
+From 213cbeabc2056ee8ef4798caba01b4b9fec71340 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 14 Apr 2024 17:10:32 +0200
+Subject: usb: gadget: function: Remove usage of the deprecated ida_simple_xx()
+ API
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 920e7522e3bab5ebc2fb0cc1a034f4470c87fa97 ]
+
+ida_alloc() and ida_free() should be preferred to the deprecated
+ida_simple_get() and ida_simple_remove().
+
+Note that the upper limit of ida_simple_get() is exclusive, but the one of
+ida_alloc_max() is inclusive. So a -1 has been added when needed.
+
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/7cd361e2b377a5373968fa7deee4169229992a1e.1713107386.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/f_hid.c     | 6 +++---
+ drivers/usb/gadget/function/f_printer.c | 6 +++---
+ drivers/usb/gadget/function/rndis.c     | 4 ++--
+ 3 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c
+index 3c8a9dd585c09..2db01e03bfbf0 100644
+--- a/drivers/usb/gadget/function/f_hid.c
++++ b/drivers/usb/gadget/function/f_hid.c
+@@ -1029,9 +1029,9 @@ static inline int hidg_get_minor(void)
+ {
+       int ret;
+-      ret = ida_simple_get(&hidg_ida, 0, 0, GFP_KERNEL);
++      ret = ida_alloc(&hidg_ida, GFP_KERNEL);
+       if (ret >= HIDG_MINORS) {
+-              ida_simple_remove(&hidg_ida, ret);
++              ida_free(&hidg_ida, ret);
+               ret = -ENODEV;
+       }
+@@ -1176,7 +1176,7 @@ static const struct config_item_type hid_func_type = {
+ static inline void hidg_put_minor(int minor)
+ {
+-      ida_simple_remove(&hidg_ida, minor);
++      ida_free(&hidg_ida, minor);
+ }
+ static void hidg_free_inst(struct usb_function_instance *f)
+diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c
+index 076dd4c1be96c..ba7d180cc9e6d 100644
+--- a/drivers/usb/gadget/function/f_printer.c
++++ b/drivers/usb/gadget/function/f_printer.c
+@@ -1312,9 +1312,9 @@ static inline int gprinter_get_minor(void)
+ {
+       int ret;
+-      ret = ida_simple_get(&printer_ida, 0, 0, GFP_KERNEL);
++      ret = ida_alloc(&printer_ida, GFP_KERNEL);
+       if (ret >= PRINTER_MINORS) {
+-              ida_simple_remove(&printer_ida, ret);
++              ida_free(&printer_ida, ret);
+               ret = -ENODEV;
+       }
+@@ -1323,7 +1323,7 @@ static inline int gprinter_get_minor(void)
+ static inline void gprinter_put_minor(int minor)
+ {
+-      ida_simple_remove(&printer_ida, minor);
++      ida_free(&printer_ida, minor);
+ }
+ static int gprinter_setup(int);
+diff --git a/drivers/usb/gadget/function/rndis.c b/drivers/usb/gadget/function/rndis.c
+index 29bf8664bf582..12c5d9cf450c1 100644
+--- a/drivers/usb/gadget/function/rndis.c
++++ b/drivers/usb/gadget/function/rndis.c
+@@ -869,12 +869,12 @@ EXPORT_SYMBOL_GPL(rndis_msg_parser);
+ static inline int rndis_get_nr(void)
+ {
+-      return ida_simple_get(&rndis_ida, 0, 1000, GFP_KERNEL);
++      return ida_alloc_max(&rndis_ida, 999, GFP_KERNEL);
+ }
+ static inline void rndis_put_nr(int nr)
+ {
+-      ida_simple_remove(&rndis_ida, nr);
++      ida_free(&rndis_ida, nr);
+ }
+ struct rndis_params *rndis_register(void (*resp_avail)(void *v), void *v)
+-- 
+2.43.0
+
diff --git a/queue-6.9/usb-gadget-uvc-configfs-ensure-guid-to-be-valid-befo.patch b/queue-6.9/usb-gadget-uvc-configfs-ensure-guid-to-be-valid-befo.patch
new file mode 100644 (file)
index 0000000..f8f26c2
--- /dev/null
@@ -0,0 +1,64 @@
+From 7b1d0ee53618005259d505ba1d8f666ffe1234f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Feb 2024 23:14:47 +0100
+Subject: usb: gadget: uvc: configfs: ensure guid to be valid before set
+
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+
+[ Upstream commit f7a7f80ccc8df017507e2b1e1dd652361374d25b ]
+
+When setting the guid via configfs it is possible to test if
+its value is one of the kernel supported ones by calling
+uvc_format_by_guid on it. If the result is NULL, we know the
+guid is unsupported and can be ignored.
+
+Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Link: https://lore.kernel.org/r/20240221-uvc-gadget-configfs-guid-v1-1-f0678ca62ebb@pengutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/uvc_configfs.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c
+index a4377df612f51..6fac696ea8463 100644
+--- a/drivers/usb/gadget/function/uvc_configfs.c
++++ b/drivers/usb/gadget/function/uvc_configfs.c
+@@ -13,6 +13,7 @@
+ #include "uvc_configfs.h"
+ #include <linux/sort.h>
++#include <linux/usb/uvc.h>
+ #include <linux/usb/video.h>
+ /* -----------------------------------------------------------------------------
+@@ -2260,6 +2261,8 @@ static ssize_t uvcg_uncompressed_guid_format_store(struct config_item *item,
+       struct f_uvc_opts *opts;
+       struct config_item *opts_item;
+       struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
++      const struct uvc_format_desc *format;
++      u8 tmpguidFormat[sizeof(ch->desc.guidFormat)];
+       int ret;
+       mutex_lock(su_mutex); /* for navigating configfs hierarchy */
+@@ -2273,7 +2276,16 @@ static ssize_t uvcg_uncompressed_guid_format_store(struct config_item *item,
+               goto end;
+       }
+-      memcpy(ch->desc.guidFormat, page,
++      memcpy(tmpguidFormat, page,
++             min(sizeof(tmpguidFormat), len));
++
++      format = uvc_format_by_guid(tmpguidFormat);
++      if (!format) {
++              ret = -EINVAL;
++              goto end;
++      }
++
++      memcpy(ch->desc.guidFormat, tmpguidFormat,
+              min(sizeof(ch->desc.guidFormat), len));
+       ret = sizeof(ch->desc.guidFormat);
+-- 
+2.43.0
+
diff --git a/queue-6.9/usb-misc-uss720-check-for-incompatible-versions-of-t.patch b/queue-6.9/usb-misc-uss720-check-for-incompatible-versions-of-t.patch
new file mode 100644 (file)
index 0000000..a67db08
--- /dev/null
@@ -0,0 +1,75 @@
+From b39e8dce16e950551db35de2296f90d3ebeebab5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Mar 2024 09:07:11 -0600
+Subject: usb: misc: uss720: check for incompatible versions of the Belkin
+ F5U002
+
+From: Alex Henrie <alexhenrie24@gmail.com>
+
+[ Upstream commit 3295f1b866bfbcabd625511968e8a5c541f9ab32 ]
+
+The incompatible device in my possession has a sticker that says
+"F5U002 Rev 2" and "P80453-B", and lsusb identifies it as
+"050d:0002 Belkin Components IEEE-1284 Controller". There is a bug
+report from 2007 from Michael Trausch who was seeing the exact same
+errors that I saw in 2024 trying to use this cable.
+
+Link: https://lore.kernel.org/all/46DE5830.9060401@trausch.us/
+Signed-off-by: Alex Henrie <alexhenrie24@gmail.com>
+Link: https://lore.kernel.org/r/20240326150723.99939-5-alexhenrie24@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/misc/uss720.c | 20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c
+index b00d92db5dfd1..eb5a8e0d9e2d6 100644
+--- a/drivers/usb/misc/uss720.c
++++ b/drivers/usb/misc/uss720.c
+@@ -677,7 +677,7 @@ static int uss720_probe(struct usb_interface *intf,
+       struct parport_uss720_private *priv;
+       struct parport *pp;
+       unsigned char reg;
+-      int i;
++      int ret;
+       dev_dbg(&intf->dev, "probe: vendor id 0x%x, device id 0x%x\n",
+               le16_to_cpu(usbdev->descriptor.idVendor),
+@@ -688,8 +688,8 @@ static int uss720_probe(struct usb_interface *intf,
+               usb_put_dev(usbdev);
+               return -ENODEV;
+       }
+-      i = usb_set_interface(usbdev, intf->altsetting->desc.bInterfaceNumber, 2);
+-      dev_dbg(&intf->dev, "set interface result %d\n", i);
++      ret = usb_set_interface(usbdev, intf->altsetting->desc.bInterfaceNumber, 2);
++      dev_dbg(&intf->dev, "set interface result %d\n", ret);
+       interface = intf->cur_altsetting;
+@@ -725,12 +725,18 @@ static int uss720_probe(struct usb_interface *intf,
+       set_1284_register(pp, 7, 0x00, GFP_KERNEL);
+       set_1284_register(pp, 6, 0x30, GFP_KERNEL);  /* PS/2 mode */
+       set_1284_register(pp, 2, 0x0c, GFP_KERNEL);
+-      /* debugging */
+-      get_1284_register(pp, 0, &reg, GFP_KERNEL);
++
++      /* The Belkin F5U002 Rev 2 P80453-B USB parallel port adapter shares the
++       * device ID 050d:0002 with some other device that works with this
++       * driver, but it itself does not. Detect and handle the bad cable
++       * here. */
++      ret = get_1284_register(pp, 0, &reg, GFP_KERNEL);
+       dev_dbg(&intf->dev, "reg: %7ph\n", priv->reg);
++      if (ret < 0)
++              return ret;
+-      i = usb_find_last_int_in_endpoint(interface, &epd);
+-      if (!i) {
++      ret = usb_find_last_int_in_endpoint(interface, &epd);
++      if (!ret) {
+               dev_dbg(&intf->dev, "epaddr %d interval %d\n",
+                               epd->bEndpointAddress, epd->bInterval);
+       }
+-- 
+2.43.0
+
diff --git a/queue-6.9/usb-typec-qcom-pmic-typec-split-hpd-bridge-alloc-and.patch b/queue-6.9/usb-typec-qcom-pmic-typec-split-hpd-bridge-alloc-and.patch
new file mode 100644 (file)
index 0000000..62aaab4
--- /dev/null
@@ -0,0 +1,80 @@
+From a1605d35e4a95d2ce25c99139f92c57bf87d6f1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Apr 2024 05:16:57 +0300
+Subject: usb: typec: qcom-pmic-typec: split HPD bridge alloc and registration
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 718b36a7b49acbba36546371db2d235271ceb06c ]
+
+If a probe function returns -EPROBE_DEFER after creating another device
+there is a change of ending up in a probe deferral loop, (see commit
+fbc35b45f9f6 ("Add documentation on meaning of -EPROBE_DEFER"). In case
+of the qcom-pmic-typec driver the tcpm_register_port() function looks up
+external resources (USB role switch and inherently via called
+typec_register_port() USB-C muxes, switches and retimers).
+
+In order to prevent such probe-defer loops caused by qcom-pmic-typec
+driver, use the API added by Johan Hovold and move HPD bridge
+registration to the end of the probe function.
+
+The devm_drm_dp_hpd_bridge_add() is called at the end of the probe
+function after all TCPM start functions. This is done as a way to
+overcome a different problem, the DRM subsystem can not properly cope
+with the DRM bridges being destroyed once the bridge is attached. Having
+this function call at the end of the probe function prevents possible
+DRM bridge device creation followed by destruction in case one of the
+TCPM start functions returns an error.
+
+Reported-by: Caleb Connolly <caleb.connolly@linaro.org>
+Acked-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
+Link: https://lore.kernel.org/r/20240424-qc-pmic-typec-hpd-split-v4-1-f7e10d147443@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
+index d3958c061a972..501eddb294e43 100644
+--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
++++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
+@@ -41,7 +41,7 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
+       struct device_node *np = dev->of_node;
+       const struct pmic_typec_resources *res;
+       struct regmap *regmap;
+-      struct device *bridge_dev;
++      struct auxiliary_device *bridge_dev;
+       u32 base;
+       int ret;
+@@ -92,7 +92,7 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
+       if (!tcpm->tcpc.fwnode)
+               return -EINVAL;
+-      bridge_dev = drm_dp_hpd_bridge_register(tcpm->dev, to_of_node(tcpm->tcpc.fwnode));
++      bridge_dev = devm_drm_dp_hpd_bridge_alloc(tcpm->dev, to_of_node(tcpm->tcpc.fwnode));
+       if (IS_ERR(bridge_dev))
+               return PTR_ERR(bridge_dev);
+@@ -110,8 +110,14 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
+       if (ret)
+               goto port_stop;
++      ret = devm_drm_dp_hpd_bridge_add(tcpm->dev, bridge_dev);
++      if (ret)
++              goto pdphy_stop;
++
+       return 0;
++pdphy_stop:
++      tcpm->pdphy_stop(tcpm);
+ port_stop:
+       tcpm->port_stop(tcpm);
+ port_unregister:
+-- 
+2.43.0
+
diff --git a/queue-6.9/usb-typec-ucsi_glink-drop-special-handling-for-cci_b.patch b/queue-6.9/usb-typec-ucsi_glink-drop-special-handling-for-cci_b.patch
new file mode 100644 (file)
index 0000000..ce9b334
--- /dev/null
@@ -0,0 +1,56 @@
+From 85054777b9ceb3cd5cd567d4e7b7c1b1a4dab59a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Apr 2024 04:04:17 +0300
+Subject: usb: typec: ucsi_glink: drop special handling for CCI_BUSY
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 1a395af9d53c6240bf7799abc43b4dc292ca9dd0 ]
+
+Newer Qualcomm platforms (sm8450+) successfully handle busy state and
+send the Command Completion after sending the Busy state. Older devices
+have firmware bug and can not continue after sending the CCI_BUSY state,
+but the command that leads to CCI_BUSY is already forbidden by the
+NO_PARTNER_PDOS quirk.
+
+Follow other UCSI glue drivers and drop special handling for CCI_BUSY
+event. Let the UCSI core properly handle this state.
+
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20240408-qcom-ucsi-fixes-bis-v1-3-716c145ca4b1@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/ucsi/ucsi_glink.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c
+index 0e6f837f6c31b..1d0e2d87e9b31 100644
+--- a/drivers/usb/typec/ucsi/ucsi_glink.c
++++ b/drivers/usb/typec/ucsi/ucsi_glink.c
+@@ -176,7 +176,8 @@ static int pmic_glink_ucsi_sync_write(struct ucsi *__ucsi, unsigned int offset,
+       left = wait_for_completion_timeout(&ucsi->sync_ack, 5 * HZ);
+       if (!left) {
+               dev_err(ucsi->dev, "timeout waiting for UCSI sync write response\n");
+-              ret = -ETIMEDOUT;
++              /* return 0 here and let core UCSI code handle the CCI_BUSY */
++              ret = 0;
+       } else if (ucsi->sync_val) {
+               dev_err(ucsi->dev, "sync write returned: %d\n", ucsi->sync_val);
+       }
+@@ -243,10 +244,7 @@ static void pmic_glink_ucsi_notify(struct work_struct *work)
+               ucsi_connector_change(ucsi->ucsi, con_num);
+       }
+-      if (ucsi->sync_pending && cci & UCSI_CCI_BUSY) {
+-              ucsi->sync_val = -EBUSY;
+-              complete(&ucsi->sync_ack);
+-      } else if (ucsi->sync_pending &&
++      if (ucsi->sync_pending &&
+                  (cci & (UCSI_CCI_ACK_COMPLETE | UCSI_CCI_COMMAND_COMPLETE))) {
+               complete(&ucsi->sync_ack);
+       }
+-- 
+2.43.0
+
diff --git a/queue-6.9/usb-typec-ucsi_glink-rework-quirks-implementation.patch b/queue-6.9/usb-typec-ucsi_glink-rework-quirks-implementation.patch
new file mode 100644 (file)
index 0000000..bad9897
--- /dev/null
@@ -0,0 +1,58 @@
+From e3e2c683b74937d9bd3a6bcf027f37d2533d9064 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Mar 2024 08:15:40 +0200
+Subject: usb: typec: ucsi_glink: rework quirks implementation
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 3f81cf54c1889eeecbb8d9188f5f2f597622170e ]
+
+In preparation to adding more quirks, extract quirks to the static
+variables and reference them through match->data. Otherwise adding
+more quirks will add the table really cumbersome.
+
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20240329-qcom-ucsi-fixes-v2-8-0f5d37ed04db@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/ucsi/ucsi_glink.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c
+index ce08eb33e5bec..0e6f837f6c31b 100644
+--- a/drivers/usb/typec/ucsi/ucsi_glink.c
++++ b/drivers/usb/typec/ucsi/ucsi_glink.c
+@@ -311,12 +311,14 @@ static void pmic_glink_ucsi_destroy(void *data)
+       mutex_unlock(&ucsi->lock);
+ }
++static unsigned long quirk_sc8180x = UCSI_NO_PARTNER_PDOS;
++
+ static const struct of_device_id pmic_glink_ucsi_of_quirks[] = {
+-      { .compatible = "qcom,qcm6490-pmic-glink", .data = (void *)UCSI_NO_PARTNER_PDOS, },
+-      { .compatible = "qcom,sc8180x-pmic-glink", .data = (void *)UCSI_NO_PARTNER_PDOS, },
+-      { .compatible = "qcom,sc8280xp-pmic-glink", .data = (void *)UCSI_NO_PARTNER_PDOS, },
+-      { .compatible = "qcom,sm8350-pmic-glink", .data = (void *)UCSI_NO_PARTNER_PDOS, },
+-      { .compatible = "qcom,sm8550-pmic-glink", .data = (void *)UCSI_NO_PARTNER_PDOS, },
++      { .compatible = "qcom,qcm6490-pmic-glink", .data = &quirk_sc8180x, },
++      { .compatible = "qcom,sc8180x-pmic-glink", .data = &quirk_sc8180x, },
++      { .compatible = "qcom,sc8280xp-pmic-glink", .data = &quirk_sc8180x, },
++      { .compatible = "qcom,sm8350-pmic-glink", .data = &quirk_sc8180x, },
++      { .compatible = "qcom,sm8550-pmic-glink", .data = &quirk_sc8180x, },
+       {}
+ };
+@@ -354,7 +356,7 @@ static int pmic_glink_ucsi_probe(struct auxiliary_device *adev,
+       match = of_match_device(pmic_glink_ucsi_of_quirks, dev->parent);
+       if (match)
+-              ucsi->ucsi->quirks = (unsigned long)match->data;
++              ucsi->ucsi->quirks = *(unsigned long *)match->data;
+       ucsi_set_drvdata(ucsi->ucsi, ucsi);
+-- 
+2.43.0
+
diff --git a/queue-6.9/vfio-pci-collect-hot-reset-devices-to-local-buffer.patch b/queue-6.9/vfio-pci-collect-hot-reset-devices-to-local-buffer.patch
new file mode 100644 (file)
index 0000000..d5d7938
--- /dev/null
@@ -0,0 +1,337 @@
+From 64a22d39cbba420eb7270af67262123d33e6357c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 May 2024 08:31:36 -0600
+Subject: vfio/pci: Collect hot-reset devices to local buffer
+
+From: Alex Williamson <alex.williamson@redhat.com>
+
+[ Upstream commit f6944d4a0b87c16bc34ae589169e1ded3d4db08e ]
+
+Lockdep reports the below circular locking dependency issue.  The
+mmap_lock acquisition while holding pci_bus_sem is due to the use of
+copy_to_user() from within a pci_walk_bus() callback.
+
+Building the devices array directly into the user buffer is only for
+convenience.  Instead we can allocate a local buffer for the array,
+bounded by the number of devices on the bus/slot, fill the device
+information into this local buffer, then copy it into the user buffer
+outside the bus walk callback.
+
+======================================================
+WARNING: possible circular locking dependency detected
+6.9.0-rc5+ #39 Not tainted
+------------------------------------------------------
+CPU 0/KVM/4113 is trying to acquire lock:
+ffff99a609ee18a8 (&vdev->vma_lock){+.+.}-{4:4}, at: vfio_pci_mmap_fault+0x35/0x1a0 [vfio_pci_core]
+
+but task is already holding lock:
+ffff99a243a052a0 (&mm->mmap_lock){++++}-{4:4}, at: vaddr_get_pfns+0x3f/0x170 [vfio_iommu_type1]
+
+which lock already depends on the new lock.
+
+the existing dependency chain (in reverse order) is:
+
+-> #3 (&mm->mmap_lock){++++}-{4:4}:
+       __lock_acquire+0x4e4/0xb90
+       lock_acquire+0xbc/0x2d0
+       __might_fault+0x5c/0x80
+       _copy_to_user+0x1e/0x60
+       vfio_pci_fill_devs+0x9f/0x130 [vfio_pci_core]
+       vfio_pci_walk_wrapper+0x45/0x60 [vfio_pci_core]
+       __pci_walk_bus+0x6b/0xb0
+       vfio_pci_ioctl_get_pci_hot_reset_info+0x10b/0x1d0 [vfio_pci_core]
+       vfio_pci_core_ioctl+0x1cb/0x400 [vfio_pci_core]
+       vfio_device_fops_unl_ioctl+0x7e/0x140 [vfio]
+       __x64_sys_ioctl+0x8a/0xc0
+       do_syscall_64+0x8d/0x170
+       entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+-> #2 (pci_bus_sem){++++}-{4:4}:
+       __lock_acquire+0x4e4/0xb90
+       lock_acquire+0xbc/0x2d0
+       down_read+0x3e/0x160
+       pci_bridge_wait_for_secondary_bus.part.0+0x33/0x2d0
+       pci_reset_bus+0xdd/0x160
+       vfio_pci_dev_set_hot_reset+0x256/0x270 [vfio_pci_core]
+       vfio_pci_ioctl_pci_hot_reset_groups+0x1a3/0x280 [vfio_pci_core]
+       vfio_pci_core_ioctl+0x3b5/0x400 [vfio_pci_core]
+       vfio_device_fops_unl_ioctl+0x7e/0x140 [vfio]
+       __x64_sys_ioctl+0x8a/0xc0
+       do_syscall_64+0x8d/0x170
+       entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+-> #1 (&vdev->memory_lock){+.+.}-{4:4}:
+       __lock_acquire+0x4e4/0xb90
+       lock_acquire+0xbc/0x2d0
+       down_write+0x3b/0xc0
+       vfio_pci_zap_and_down_write_memory_lock+0x1c/0x30 [vfio_pci_core]
+       vfio_basic_config_write+0x281/0x340 [vfio_pci_core]
+       vfio_config_do_rw+0x1fa/0x300 [vfio_pci_core]
+       vfio_pci_config_rw+0x75/0xe50 [vfio_pci_core]
+       vfio_pci_rw+0xea/0x1a0 [vfio_pci_core]
+       vfs_write+0xea/0x520
+       __x64_sys_pwrite64+0x90/0xc0
+       do_syscall_64+0x8d/0x170
+       entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+-> #0 (&vdev->vma_lock){+.+.}-{4:4}:
+       check_prev_add+0xeb/0xcc0
+       validate_chain+0x465/0x530
+       __lock_acquire+0x4e4/0xb90
+       lock_acquire+0xbc/0x2d0
+       __mutex_lock+0x97/0xde0
+       vfio_pci_mmap_fault+0x35/0x1a0 [vfio_pci_core]
+       __do_fault+0x31/0x160
+       do_pte_missing+0x65/0x3b0
+       __handle_mm_fault+0x303/0x720
+       handle_mm_fault+0x10f/0x460
+       fixup_user_fault+0x7f/0x1f0
+       follow_fault_pfn+0x66/0x1c0 [vfio_iommu_type1]
+       vaddr_get_pfns+0xf2/0x170 [vfio_iommu_type1]
+       vfio_pin_pages_remote+0x348/0x4e0 [vfio_iommu_type1]
+       vfio_pin_map_dma+0xd2/0x330 [vfio_iommu_type1]
+       vfio_dma_do_map+0x2c0/0x440 [vfio_iommu_type1]
+       vfio_iommu_type1_ioctl+0xc5/0x1d0 [vfio_iommu_type1]
+       __x64_sys_ioctl+0x8a/0xc0
+       do_syscall_64+0x8d/0x170
+       entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+other info that might help us debug this:
+
+Chain exists of:
+  &vdev->vma_lock --> pci_bus_sem --> &mm->mmap_lock
+
+ Possible unsafe locking scenario:
+
+block dm-0: the capability attribute has been deprecated.
+       CPU0                    CPU1
+       ----                    ----
+  rlock(&mm->mmap_lock);
+                               lock(pci_bus_sem);
+                               lock(&mm->mmap_lock);
+  lock(&vdev->vma_lock);
+
+ *** DEADLOCK ***
+
+2 locks held by CPU 0/KVM/4113:
+ #0: ffff99a25f294888 (&iommu->lock#2){+.+.}-{4:4}, at: vfio_dma_do_map+0x60/0x440 [vfio_iommu_type1]
+ #1: ffff99a243a052a0 (&mm->mmap_lock){++++}-{4:4}, at: vaddr_get_pfns+0x3f/0x170 [vfio_iommu_type1]
+
+stack backtrace:
+CPU: 1 PID: 4113 Comm: CPU 0/KVM Not tainted 6.9.0-rc5+ #39
+Hardware name: Dell Inc. PowerEdge T640/04WYPY, BIOS 2.15.1 06/16/2022
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x64/0xa0
+ check_noncircular+0x131/0x150
+ check_prev_add+0xeb/0xcc0
+ ? add_chain_cache+0x10a/0x2f0
+ ? __lock_acquire+0x4e4/0xb90
+ validate_chain+0x465/0x530
+ __lock_acquire+0x4e4/0xb90
+ lock_acquire+0xbc/0x2d0
+ ? vfio_pci_mmap_fault+0x35/0x1a0 [vfio_pci_core]
+ ? lock_is_held_type+0x9a/0x110
+ __mutex_lock+0x97/0xde0
+ ? vfio_pci_mmap_fault+0x35/0x1a0 [vfio_pci_core]
+ ? lock_acquire+0xbc/0x2d0
+ ? vfio_pci_mmap_fault+0x35/0x1a0 [vfio_pci_core]
+ ? find_held_lock+0x2b/0x80
+ ? vfio_pci_mmap_fault+0x35/0x1a0 [vfio_pci_core]
+ vfio_pci_mmap_fault+0x35/0x1a0 [vfio_pci_core]
+ __do_fault+0x31/0x160
+ do_pte_missing+0x65/0x3b0
+ __handle_mm_fault+0x303/0x720
+ handle_mm_fault+0x10f/0x460
+ fixup_user_fault+0x7f/0x1f0
+ follow_fault_pfn+0x66/0x1c0 [vfio_iommu_type1]
+ vaddr_get_pfns+0xf2/0x170 [vfio_iommu_type1]
+ vfio_pin_pages_remote+0x348/0x4e0 [vfio_iommu_type1]
+ vfio_pin_map_dma+0xd2/0x330 [vfio_iommu_type1]
+ vfio_dma_do_map+0x2c0/0x440 [vfio_iommu_type1]
+ vfio_iommu_type1_ioctl+0xc5/0x1d0 [vfio_iommu_type1]
+ __x64_sys_ioctl+0x8a/0xc0
+ do_syscall_64+0x8d/0x170
+ ? rcu_core+0x8d/0x250
+ ? __lock_release+0x5e/0x160
+ ? rcu_core+0x8d/0x250
+ ? lock_release+0x5f/0x120
+ ? sched_clock+0xc/0x30
+ ? sched_clock_cpu+0xb/0x190
+ ? irqtime_account_irq+0x40/0xc0
+ ? __local_bh_enable+0x54/0x60
+ ? __do_softirq+0x315/0x3ca
+ ? lockdep_hardirqs_on_prepare.part.0+0x97/0x140
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+RIP: 0033:0x7f8300d0357b
+Code: ff ff ff 85 c0 79 9b 49 c7 c4 ff ff ff ff 5b 5d 4c 89 e0 41 5c c3 66 0f 1f 84 00 00 00 00 00 f3 0f 1e fa b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 75 68 0f 00 f7 d8 64 89 01 48
+RSP: 002b:00007f82ef3fb948 EFLAGS: 00000206 ORIG_RAX: 0000000000000010
+RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f8300d0357b
+RDX: 00007f82ef3fb990 RSI: 0000000000003b71 RDI: 0000000000000023
+RBP: 00007f82ef3fb9c0 R08: 0000000000000000 R09: 0000561b7e0bcac2
+R10: 0000000000000000 R11: 0000000000000206 R12: 0000000000000000
+R13: 0000000200000000 R14: 0000381800000000 R15: 0000000000000000
+ </TASK>
+
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/20240503143138.3562116-1-alex.williamson@redhat.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vfio/pci/vfio_pci_core.c | 78 ++++++++++++++++++++------------
+ 1 file changed, 49 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
+index d94d61b92c1ac..d8c95cc16be81 100644
+--- a/drivers/vfio/pci/vfio_pci_core.c
++++ b/drivers/vfio/pci/vfio_pci_core.c
+@@ -778,25 +778,26 @@ static int vfio_pci_count_devs(struct pci_dev *pdev, void *data)
+ }
+ struct vfio_pci_fill_info {
+-      struct vfio_pci_dependent_device __user *devices;
+-      struct vfio_pci_dependent_device __user *devices_end;
+       struct vfio_device *vdev;
++      struct vfio_pci_dependent_device *devices;
++      int nr_devices;
+       u32 count;
+       u32 flags;
+ };
+ static int vfio_pci_fill_devs(struct pci_dev *pdev, void *data)
+ {
+-      struct vfio_pci_dependent_device info = {
+-              .segment = pci_domain_nr(pdev->bus),
+-              .bus = pdev->bus->number,
+-              .devfn = pdev->devfn,
+-      };
++      struct vfio_pci_dependent_device *info;
+       struct vfio_pci_fill_info *fill = data;
+-      fill->count++;
+-      if (fill->devices >= fill->devices_end)
+-              return 0;
++      /* The topology changed since we counted devices */
++      if (fill->count >= fill->nr_devices)
++              return -EAGAIN;
++
++      info = &fill->devices[fill->count++];
++      info->segment = pci_domain_nr(pdev->bus);
++      info->bus = pdev->bus->number;
++      info->devfn = pdev->devfn;
+       if (fill->flags & VFIO_PCI_HOT_RESET_FLAG_DEV_ID) {
+               struct iommufd_ctx *iommufd = vfio_iommufd_device_ictx(fill->vdev);
+@@ -809,19 +810,19 @@ static int vfio_pci_fill_devs(struct pci_dev *pdev, void *data)
+                */
+               vdev = vfio_find_device_in_devset(dev_set, &pdev->dev);
+               if (!vdev) {
+-                      info.devid = VFIO_PCI_DEVID_NOT_OWNED;
++                      info->devid = VFIO_PCI_DEVID_NOT_OWNED;
+               } else {
+                       int id = vfio_iommufd_get_dev_id(vdev, iommufd);
+                       if (id > 0)
+-                              info.devid = id;
++                              info->devid = id;
+                       else if (id == -ENOENT)
+-                              info.devid = VFIO_PCI_DEVID_OWNED;
++                              info->devid = VFIO_PCI_DEVID_OWNED;
+                       else
+-                              info.devid = VFIO_PCI_DEVID_NOT_OWNED;
++                              info->devid = VFIO_PCI_DEVID_NOT_OWNED;
+               }
+               /* If devid is VFIO_PCI_DEVID_NOT_OWNED, clear owned flag. */
+-              if (info.devid == VFIO_PCI_DEVID_NOT_OWNED)
++              if (info->devid == VFIO_PCI_DEVID_NOT_OWNED)
+                       fill->flags &= ~VFIO_PCI_HOT_RESET_FLAG_DEV_ID_OWNED;
+       } else {
+               struct iommu_group *iommu_group;
+@@ -830,13 +831,10 @@ static int vfio_pci_fill_devs(struct pci_dev *pdev, void *data)
+               if (!iommu_group)
+                       return -EPERM; /* Cannot reset non-isolated devices */
+-              info.group_id = iommu_group_id(iommu_group);
++              info->group_id = iommu_group_id(iommu_group);
+               iommu_group_put(iommu_group);
+       }
+-      if (copy_to_user(fill->devices, &info, sizeof(info)))
+-              return -EFAULT;
+-      fill->devices++;
+       return 0;
+ }
+@@ -1258,10 +1256,11 @@ static int vfio_pci_ioctl_get_pci_hot_reset_info(
+ {
+       unsigned long minsz =
+               offsetofend(struct vfio_pci_hot_reset_info, count);
++      struct vfio_pci_dependent_device *devices = NULL;
+       struct vfio_pci_hot_reset_info hdr;
+       struct vfio_pci_fill_info fill = {};
+       bool slot = false;
+-      int ret = 0;
++      int ret, count;
+       if (copy_from_user(&hdr, arg, minsz))
+               return -EFAULT;
+@@ -1277,9 +1276,23 @@ static int vfio_pci_ioctl_get_pci_hot_reset_info(
+       else if (pci_probe_reset_bus(vdev->pdev->bus))
+               return -ENODEV;
+-      fill.devices = arg->devices;
+-      fill.devices_end = arg->devices +
+-                         (hdr.argsz - sizeof(hdr)) / sizeof(arg->devices[0]);
++      ret = vfio_pci_for_each_slot_or_bus(vdev->pdev, vfio_pci_count_devs,
++                                          &count, slot);
++      if (ret)
++              return ret;
++
++      if (count > (hdr.argsz - sizeof(hdr)) / sizeof(*devices)) {
++              hdr.count = count;
++              ret = -ENOSPC;
++              goto header;
++      }
++
++      devices = kcalloc(count, sizeof(*devices), GFP_KERNEL);
++      if (!devices)
++              return -ENOMEM;
++
++      fill.devices = devices;
++      fill.nr_devices = count;
+       fill.vdev = &vdev->vdev;
+       if (vfio_device_cdev_opened(&vdev->vdev))
+@@ -1291,16 +1304,23 @@ static int vfio_pci_ioctl_get_pci_hot_reset_info(
+                                           &fill, slot);
+       mutex_unlock(&vdev->vdev.dev_set->lock);
+       if (ret)
+-              return ret;
++              goto out;
++
++      if (copy_to_user(arg->devices, devices,
++                       sizeof(*devices) * fill.count)) {
++              ret = -EFAULT;
++              goto out;
++      }
+       hdr.count = fill.count;
+       hdr.flags = fill.flags;
+-      if (copy_to_user(arg, &hdr, minsz))
+-              return -EFAULT;
+-      if (fill.count > fill.devices - arg->devices)
+-              return -ENOSPC;
+-      return 0;
++header:
++      if (copy_to_user(arg, &hdr, minsz))
++              ret = -EFAULT;
++out:
++      kfree(devices);
++      return ret;
+ }
+ static int
+-- 
+2.43.0
+
diff --git a/queue-6.9/wifi-ath12k-fix-kernel-crash-during-resume.patch b/queue-6.9/wifi-ath12k-fix-kernel-crash-during-resume.patch
new file mode 100644 (file)
index 0000000..ee3bd1e
--- /dev/null
@@ -0,0 +1,225 @@
+From 4029b63c1099eedddd45c26bca7062b880f27605 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Apr 2024 15:11:47 +0300
+Subject: wifi: ath12k: fix kernel crash during resume
+
+From: Baochen Qiang <quic_bqiang@quicinc.com>
+
+[ Upstream commit 303c017821d88ebad887814114d4e5966d320b28 ]
+
+Currently during resume, QMI target memory is not properly handled, resulting
+in kernel crash in case DMA remap is not supported:
+
+BUG: Bad page state in process kworker/u16:54  pfn:36e80
+page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x36e80
+page dumped because: nonzero _refcount
+Call Trace:
+ bad_page
+ free_page_is_bad_report
+ __free_pages_ok
+ __free_pages
+ dma_direct_free
+ dma_free_attrs
+ ath12k_qmi_free_target_mem_chunk
+ ath12k_qmi_msg_mem_request_cb
+
+The reason is:
+Once ath12k module is loaded, firmware sends memory request to host. In case
+DMA remap not supported, ath12k refuses the first request due to failure in
+allocating with large segment size:
+
+ath12k_pci 0000:04:00.0: qmi firmware request memory request
+ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 7077888
+ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 8454144
+ath12k_pci 0000:04:00.0: qmi dma allocation failed (7077888 B type 1), will try later with small size
+ath12k_pci 0000:04:00.0: qmi delays mem_request 2
+ath12k_pci 0000:04:00.0: qmi firmware request memory request
+
+Later firmware comes back with more but small segments and allocation
+succeeds:
+
+ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 262144
+ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288
+ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 65536
+ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288
+
+Now ath12k is working. If suspend is triggered, firmware will be reloaded
+during resume. As same as before, firmware requests two large segments at
+first. In ath12k_qmi_msg_mem_request_cb() segment count and size are
+assigned:
+
+       ab->qmi.mem_seg_count == 2
+       ab->qmi.target_mem[0].size == 7077888
+       ab->qmi.target_mem[1].size == 8454144
+
+Then allocation failed like before and ath12k_qmi_free_target_mem_chunk()
+is called to free all allocated segments. Note the first segment is skipped
+because its v.addr is cleared due to allocation failure:
+
+       chunk->v.addr = dma_alloc_coherent()
+
+Also note that this leaks that segment because it has not been freed.
+
+While freeing the second segment, a size of 8454144 is passed to
+dma_free_coherent(). However remember that this segment is allocated at
+the first time firmware is loaded, before suspend. So its real size is
+524288, much smaller than 8454144. As a result kernel found we are freeing
+some memory which is in use and thus crashed.
+
+So one possible fix would be to free those segments during suspend. This
+works because with them freed, ath12k_qmi_free_target_mem_chunk() does
+nothing: all segment addresses are NULL so dma_free_coherent() is not called.
+
+But note that ath11k has similar logic but never hits this issue. Reviewing
+code there shows the luck comes from QMI memory reuse logic. So the decision
+is to port it to ath12k. Like in ath11k, the crash is avoided by adding
+prev_size to target_mem_chunk structure and caching real segment size in it,
+then prev_size instead of current size is passed to dma_free_coherent(),
+no unexpected memory is freed now.
+
+Also reuse m3 buffer.
+
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+
+Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://msgid.link/20240419034034.2842-1-quic_bqiang@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/core.c |  1 -
+ drivers/net/wireless/ath/ath12k/qmi.c  | 29 +++++++++++++++++++++-----
+ drivers/net/wireless/ath/ath12k/qmi.h  |  2 ++
+ 3 files changed, 26 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
+index 391b6fb2bd426..bff4598de4035 100644
+--- a/drivers/net/wireless/ath/ath12k/core.c
++++ b/drivers/net/wireless/ath/ath12k/core.c
+@@ -1132,7 +1132,6 @@ static void ath12k_core_reset(struct work_struct *work)
+                                               ATH12K_RECOVER_START_TIMEOUT_HZ);
+       ath12k_hif_power_down(ab);
+-      ath12k_qmi_free_resource(ab);
+       ath12k_hif_power_up(ab);
+       ath12k_dbg(ab, ATH12K_DBG_BOOT, "reset started\n");
+diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
+index 40b6abccbb508..4a0c4dc3593bf 100644
+--- a/drivers/net/wireless/ath/ath12k/qmi.c
++++ b/drivers/net/wireless/ath/ath12k/qmi.c
+@@ -2325,8 +2325,9 @@ static void ath12k_qmi_free_target_mem_chunk(struct ath12k_base *ab)
+       for (i = 0; i < ab->qmi.mem_seg_count; i++) {
+               if (!ab->qmi.target_mem[i].v.addr)
+                       continue;
++
+               dma_free_coherent(ab->dev,
+-                                ab->qmi.target_mem[i].size,
++                                ab->qmi.target_mem[i].prev_size,
+                                 ab->qmi.target_mem[i].v.addr,
+                                 ab->qmi.target_mem[i].paddr);
+               ab->qmi.target_mem[i].v.addr = NULL;
+@@ -2352,6 +2353,20 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab)
+               case M3_DUMP_REGION_TYPE:
+               case PAGEABLE_MEM_REGION_TYPE:
+               case CALDB_MEM_REGION_TYPE:
++                      /* Firmware reloads in recovery/resume.
++                       * In such cases, no need to allocate memory for FW again.
++                       */
++                      if (chunk->v.addr) {
++                              if (chunk->prev_type == chunk->type &&
++                                  chunk->prev_size == chunk->size)
++                                      goto this_chunk_done;
++
++                              /* cannot reuse the existing chunk */
++                              dma_free_coherent(ab->dev, chunk->prev_size,
++                                                chunk->v.addr, chunk->paddr);
++                              chunk->v.addr = NULL;
++                      }
++
+                       chunk->v.addr = dma_alloc_coherent(ab->dev,
+                                                          chunk->size,
+                                                          &chunk->paddr,
+@@ -2370,6 +2385,10 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab)
+                                           chunk->type, chunk->size);
+                               return -ENOMEM;
+                       }
++
++                      chunk->prev_type = chunk->type;
++                      chunk->prev_size = chunk->size;
++this_chunk_done:
+                       break;
+               default:
+                       ath12k_warn(ab, "memory type %u not supported\n",
+@@ -2675,10 +2694,6 @@ static int ath12k_qmi_m3_load(struct ath12k_base *ab)
+       size_t m3_len;
+       int ret;
+-      if (m3_mem->vaddr)
+-              /* m3 firmware buffer is already available in the DMA buffer */
+-              return 0;
+-
+       if (ab->fw.m3_data && ab->fw.m3_len > 0) {
+               /* firmware-N.bin had a m3 firmware file so use that */
+               m3_data = ab->fw.m3_data;
+@@ -2700,6 +2715,9 @@ static int ath12k_qmi_m3_load(struct ath12k_base *ab)
+               m3_len = fw->size;
+       }
++      if (m3_mem->vaddr)
++              goto skip_m3_alloc;
++
+       m3_mem->vaddr = dma_alloc_coherent(ab->dev,
+                                          m3_len, &m3_mem->paddr,
+                                          GFP_KERNEL);
+@@ -2710,6 +2728,7 @@ static int ath12k_qmi_m3_load(struct ath12k_base *ab)
+               goto out;
+       }
++skip_m3_alloc:
+       memcpy(m3_mem->vaddr, m3_data, m3_len);
+       m3_mem->size = m3_len;
+diff --git a/drivers/net/wireless/ath/ath12k/qmi.h b/drivers/net/wireless/ath/ath12k/qmi.h
+index 6ee33c9851c6b..f34263d4bee88 100644
+--- a/drivers/net/wireless/ath/ath12k/qmi.h
++++ b/drivers/net/wireless/ath/ath12k/qmi.h
+@@ -96,6 +96,8 @@ struct ath12k_qmi_event_msg {
+ struct target_mem_chunk {
+       u32 size;
+       u32 type;
++      u32 prev_size;
++      u32 prev_type;
+       dma_addr_t paddr;
+       union {
+               void __iomem *ioaddr;
+-- 
+2.43.0
+
diff --git a/queue-6.9/wifi-ath12k-fix-the-problem-that-down-grade-phy-mode.patch b/queue-6.9/wifi-ath12k-fix-the-problem-that-down-grade-phy-mode.patch
new file mode 100644 (file)
index 0000000..512b968
--- /dev/null
@@ -0,0 +1,91 @@
+From 702f6f3666120bb8385f924b3a0bd4dde97ac88d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Apr 2024 16:38:38 +0300
+Subject: wifi: ath12k: fix the problem that down grade phy mode operation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lingbo Kong <quic_lingbok@quicinc.com>
+
+[ Upstream commit bf76b144fe53c7f0de9e294947d903fc7724776f ]
+
+Currently, when using WCN7850 or QCN9274 as AP, ath12k always performs down
+grade phy mode operation regardless of whether the firmware supports EHT
+capability or not and then vdev will start in HE mode. When stations that
+support EHT capability try to connect to the AP, the AP will set phy mode
+to EHT after receiving the association request packet, and then send
+WMI_PEER_ASSOC_CMDID command to firmware, AP’s firmware will crash.
+
+This is because when the ath12k_mac_copy_sband_iftype_data() function
+handles EHT capability, it does not copy the EHT capability into the
+iftype[band][type] array according to the interface type. So, interface
+type should not be used as an index to get eht_cap in
+ath12k_mac_check_down_grade_phy_mode() function.
+
+To address this issue, use types_mask to select the eht_cap in
+ath12k_mac_check_down_grade_phy_mode() function.
+
+This patch affects QCN9274 and WCN7850 because they have the same issue.
+
+Hostapd log:
+wlo1: STA 02:03:7f:37:12:34 IEEE 802.11: Could not set STA to kernel driver
+
+Kernel log:
+[270894.816076] ath12k_pci 0000:03:00.0: failed to send WMI_PEER_SET_PARAM cmd
+[270894.816111] ath12k_pci 0000:03:00.0: failed to setup peer SMPS for vdev 0: -108
+[270894.816122] ath12k_pci 0000:03:00.0: Failed to associate station: 02:03:7f:37:12:34
+[270894.843389] ieee80211 phy5: Hardware restart was requested
+[270894.843517] ath12k_pci 0000:03:00.0: failed to lookup peer 02:03:7f:37:12:34 on vdev 0
+[270894.843616] ath12k_pci 0000:03:00.0: failed to send WMI_PEER_DELETE cmd
+[270894.843650] ath12k_pci 0000:03:00.0: failed to delete peer vdev_id 0 addr 02:03:7f:37:12:34 ret -108
+[270894.843663] ath12k_pci 0000:03:00.0: Failed to delete peer: 02:03:7f:37:12:34 for VDEV: 0
+
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
+
+Signed-off-by: Lingbo Kong <quic_lingbok@quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://msgid.link/20240425083837.5340-1-quic_lingbok@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/mac.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
+index 52a5fb8b03e9a..82ef4d4da681e 100644
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -6286,14 +6286,24 @@ ath12k_mac_check_down_grade_phy_mode(struct ath12k *ar,
+                                    enum nl80211_band band,
+                                    enum nl80211_iftype type)
+ {
+-      struct ieee80211_sta_eht_cap *eht_cap;
++      struct ieee80211_sta_eht_cap *eht_cap = NULL;
+       enum wmi_phy_mode down_mode;
++      int n = ar->mac.sbands[band].n_iftype_data;
++      int i;
++      struct ieee80211_sband_iftype_data *data;
+       if (mode < MODE_11BE_EHT20)
+               return mode;
+-      eht_cap = &ar->mac.iftype[band][type].eht_cap;
+-      if (eht_cap->has_eht)
++      data = ar->mac.iftype[band];
++      for (i = 0; i < n; i++) {
++              if (data[i].types_mask & BIT(type)) {
++                      eht_cap = &data[i].eht_cap;
++                      break;
++              }
++      }
++
++      if (eht_cap && eht_cap->has_eht)
+               return mode;
+       switch (mode) {
+-- 
+2.43.0
+
diff --git a/queue-6.9/wifi-ath9k-work-around-memset-overflow-warning.patch b/queue-6.9/wifi-ath9k-work-around-memset-overflow-warning.patch
new file mode 100644 (file)
index 0000000..15e8ff0
--- /dev/null
@@ -0,0 +1,72 @@
+From 4d48e5e3c9b14d3513d24db4968708a64ed92e85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Apr 2024 09:35:59 +0300
+Subject: wifi: ath9k: work around memset overflow warning
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 61752ac69b69ed2e04444d090f6917c77ab36d42 ]
+
+gcc-9 and some other older versions produce a false-positive warning
+for zeroing two fields
+
+In file included from include/linux/string.h:369,
+                 from drivers/net/wireless/ath/ath9k/main.c:18:
+In function 'fortify_memset_chk',
+    inlined from 'ath9k_ps_wakeup' at drivers/net/wireless/ath/ath9k/main.c:140:3:
+include/linux/fortify-string.h:462:25: error: call to '__write_overflow_field' declared with attribute warning: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror=attribute-warning]
+  462 |                         __write_overflow_field(p_size_field, size);
+      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Using a struct_group seems to reliably avoid the warning and
+not make the code much uglier. The combined memset() should even
+save a couple of cpu cycles.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://msgid.link/20240328135509.3755090-3-arnd@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath.h        | 6 ++++--
+ drivers/net/wireless/ath/ath9k/main.c | 3 +--
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
+index f02a308a9ffc5..34654f710d8a1 100644
+--- a/drivers/net/wireless/ath/ath.h
++++ b/drivers/net/wireless/ath/ath.h
+@@ -171,8 +171,10 @@ struct ath_common {
+       unsigned int clockrate;
+       spinlock_t cc_lock;
+-      struct ath_cycle_counters cc_ani;
+-      struct ath_cycle_counters cc_survey;
++      struct_group(cc,
++              struct ath_cycle_counters cc_ani;
++              struct ath_cycle_counters cc_survey;
++      );
+       struct ath_regulatory regulatory;
+       struct ath_regulatory reg_world_copy;
+diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
+index a2943aaecb202..01173aac30456 100644
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -135,8 +135,7 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
+       if (power_mode != ATH9K_PM_AWAKE) {
+               spin_lock(&common->cc_lock);
+               ath_hw_cycle_counters_update(common);
+-              memset(&common->cc_survey, 0, sizeof(common->cc_survey));
+-              memset(&common->cc_ani, 0, sizeof(common->cc_ani));
++              memset(&common->cc, 0, sizeof(common->cc));
+               spin_unlock(&common->cc_lock);
+       }
+-- 
+2.43.0
+
diff --git a/queue-6.9/wifi-mt76-mt7921s-fix-potential-hung-tasks-during-ch.patch b/queue-6.9/wifi-mt76-mt7921s-fix-potential-hung-tasks-during-ch.patch
new file mode 100644 (file)
index 0000000..1b55ce7
--- /dev/null
@@ -0,0 +1,106 @@
+From 0552457a14fd4678df3c03ccc4f4ff5d618e5bd3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 17:46:32 +0800
+Subject: wifi: mt76: mt7921s: fix potential hung tasks during chip recovery
+
+From: Leon Yen <leon.yen@mediatek.com>
+
+[ Upstream commit ecf0b2b8a37c8464186620bef37812a117ff6366 ]
+
+During chip recovery (e.g. chip reset), there is a possible situation that
+kernel worker reset_work is holding the lock and waiting for kernel thread
+stat_worker to be parked, while stat_worker is waiting for the release of
+the same lock.
+It causes a deadlock resulting in the dumping of hung tasks messages and
+possible rebooting of the device.
+
+This patch prevents the execution of stat_worker during the chip recovery.
+
+Signed-off-by: Leon Yen <leon.yen@mediatek.com>
+Signed-off-by: Ming Yen Hsieh <MingYen.Hsieh@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7921/mac.c      | 2 ++
+ drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c  | 2 --
+ drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c | 2 --
+ drivers/net/wireless/mediatek/mt76/sdio.c            | 3 ++-
+ 4 files changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+index 867e14f6b93a0..73e42ef429837 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+@@ -663,6 +663,7 @@ void mt7921_mac_reset_work(struct work_struct *work)
+       int i, ret;
+       dev_dbg(dev->mt76.dev, "chip reset\n");
++      set_bit(MT76_RESET, &dev->mphy.state);
+       dev->hw_full_reset = true;
+       ieee80211_stop_queues(hw);
+@@ -691,6 +692,7 @@ void mt7921_mac_reset_work(struct work_struct *work)
+       }
+       dev->hw_full_reset = false;
++      clear_bit(MT76_RESET, &dev->mphy.state);
+       pm->suspended = false;
+       ieee80211_wake_queues(hw);
+       ieee80211_iterate_active_interfaces(hw,
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c
+index c866144ff0613..031ba9aaa4e2f 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c
+@@ -64,7 +64,6 @@ int mt7921e_mac_reset(struct mt792x_dev *dev)
+       mt76_wr(dev, dev->irq_map->host_irq_enable, 0);
+       mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0);
+-      set_bit(MT76_RESET, &dev->mphy.state);
+       set_bit(MT76_MCU_RESET, &dev->mphy.state);
+       wake_up(&dev->mt76.mcu.wait);
+       skb_queue_purge(&dev->mt76.mcu.res_q);
+@@ -115,7 +114,6 @@ int mt7921e_mac_reset(struct mt792x_dev *dev)
+       err = __mt7921_start(&dev->phy);
+ out:
+-      clear_bit(MT76_RESET, &dev->mphy.state);
+       local_bh_disable();
+       napi_enable(&dev->mt76.tx_napi);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c
+index 389eb0903807e..1f77cf71ca701 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c
+@@ -98,7 +98,6 @@ int mt7921s_mac_reset(struct mt792x_dev *dev)
+       mt76_connac_free_pending_tx_skbs(&dev->pm, NULL);
+       mt76_txq_schedule_all(&dev->mphy);
+       mt76_worker_disable(&dev->mt76.tx_worker);
+-      set_bit(MT76_RESET, &dev->mphy.state);
+       set_bit(MT76_MCU_RESET, &dev->mphy.state);
+       wake_up(&dev->mt76.mcu.wait);
+       skb_queue_purge(&dev->mt76.mcu.res_q);
+@@ -135,7 +134,6 @@ int mt7921s_mac_reset(struct mt792x_dev *dev)
+       err = __mt7921_start(&dev->phy);
+ out:
+-      clear_bit(MT76_RESET, &dev->mphy.state);
+       mt76_worker_enable(&dev->mt76.tx_worker);
+diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c
+index 3e88798df0178..a4ed00eebc483 100644
+--- a/drivers/net/wireless/mediatek/mt76/sdio.c
++++ b/drivers/net/wireless/mediatek/mt76/sdio.c
+@@ -499,7 +499,8 @@ static void mt76s_tx_status_data(struct mt76_worker *worker)
+       dev = container_of(sdio, struct mt76_dev, sdio);
+       while (true) {
+-              if (test_bit(MT76_REMOVED, &dev->phy.state))
++              if (test_bit(MT76_RESET, &dev->phy.state) ||
++                  test_bit(MT76_REMOVED, &dev->phy.state))
+                       break;
+               if (!dev->drv->tx_status_data(dev, &update))
+-- 
+2.43.0
+
diff --git a/queue-6.9/wifi-rtw89-8852c-add-quirk-to-set-pci-ber-for-certai.patch b/queue-6.9/wifi-rtw89-8852c-add-quirk-to-set-pci-ber-for-certai.patch
new file mode 100644 (file)
index 0000000..b72d725
--- /dev/null
@@ -0,0 +1,257 @@
+From 41096a15400f8b8aa5ca2aa130d941e4371b5808 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Mar 2024 09:52:50 +0800
+Subject: wifi: rtw89: 8852c: add quirk to set PCI BER for certain platforms
+
+From: Ping-Ke Shih <pkshih@realtek.com>
+
+[ Upstream commit 5b919d726b613c78d4dc463dd9f90c55843fd1b3 ]
+
+Increase PCI BER (bit error rate) count depth setting which could increase
+PHY circuit fault tolerance and improve compatibility.
+
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://msgid.link/20240329015251.22762-4-pkshih@realtek.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw89/core.c     | 18 +++++++++++++++
+ drivers/net/wireless/realtek/rtw89/core.h     | 10 ++++++++
+ drivers/net/wireless/realtek/rtw89/pci.c      | 19 +++++++++++++++
+ drivers/net/wireless/realtek/rtw89/pci.h      |  5 ++++
+ .../net/wireless/realtek/rtw89/rtw8851be.c    |  1 +
+ .../net/wireless/realtek/rtw89/rtw8852ae.c    |  1 +
+ .../net/wireless/realtek/rtw89/rtw8852be.c    |  1 +
+ .../net/wireless/realtek/rtw89/rtw8852ce.c    | 23 +++++++++++++++++++
+ .../net/wireless/realtek/rtw89/rtw8922ae.c    |  1 +
+ 9 files changed, 79 insertions(+)
+
+diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
+index d474b8d5df3dd..b8d419a5b9db0 100644
+--- a/drivers/net/wireless/realtek/rtw89/core.c
++++ b/drivers/net/wireless/realtek/rtw89/core.c
+@@ -4069,6 +4069,24 @@ void rtw89_core_ntfy_btc_event(struct rtw89_dev *rtwdev, enum rtw89_btc_hmsg eve
+       }
+ }
++void rtw89_check_quirks(struct rtw89_dev *rtwdev, const struct dmi_system_id *quirks)
++{
++      const struct dmi_system_id *match;
++      enum rtw89_quirks quirk;
++
++      if (!quirks)
++              return;
++
++      for (match = dmi_first_match(quirks); match; match = dmi_first_match(match + 1)) {
++              quirk = (uintptr_t)match->driver_data;
++              if (quirk >= NUM_OF_RTW89_QUIRKS)
++                      continue;
++
++              set_bit(quirk, rtwdev->quirks);
++      }
++}
++EXPORT_SYMBOL(rtw89_check_quirks);
++
+ int rtw89_core_start(struct rtw89_dev *rtwdev)
+ {
+       int ret;
+diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
+index 2e854c9af7099..509d84a493348 100644
+--- a/drivers/net/wireless/realtek/rtw89/core.h
++++ b/drivers/net/wireless/realtek/rtw89/core.h
+@@ -7,6 +7,7 @@
+ #include <linux/average.h>
+ #include <linux/bitfield.h>
++#include <linux/dmi.h>
+ #include <linux/firmware.h>
+ #include <linux/iopoll.h>
+ #include <linux/workqueue.h>
+@@ -3977,6 +3978,7 @@ union rtw89_bus_info {
+ struct rtw89_driver_info {
+       const struct rtw89_chip_info *chip;
++      const struct dmi_system_id *quirks;
+       union rtw89_bus_info bus;
+ };
+@@ -4324,6 +4326,12 @@ enum rtw89_flags {
+       NUM_OF_RTW89_FLAGS,
+ };
++enum rtw89_quirks {
++      RTW89_QUIRK_PCI_BER,
++
++      NUM_OF_RTW89_QUIRKS,
++};
++
+ enum rtw89_pkt_drop_sel {
+       RTW89_PKT_DROP_SEL_MACID_BE_ONCE,
+       RTW89_PKT_DROP_SEL_MACID_BK_ONCE,
+@@ -5084,6 +5092,7 @@ struct rtw89_dev {
+       DECLARE_BITMAP(mac_id_map, RTW89_MAX_MAC_ID_NUM);
+       DECLARE_BITMAP(flags, NUM_OF_RTW89_FLAGS);
+       DECLARE_BITMAP(pkt_offload, RTW89_MAX_PKT_OFLD_NUM);
++      DECLARE_BITMAP(quirks, NUM_OF_RTW89_QUIRKS);
+       struct rtw89_phy_stat phystat;
+       struct rtw89_rfk_wait_info rfk_wait;
+@@ -6129,6 +6138,7 @@ int rtw89_core_sta_remove(struct rtw89_dev *rtwdev,
+ void rtw89_core_set_tid_config(struct rtw89_dev *rtwdev,
+                              struct ieee80211_sta *sta,
+                              struct cfg80211_tid_config *tid_config);
++void rtw89_check_quirks(struct rtw89_dev *rtwdev, const struct dmi_system_id *quirks);
+ int rtw89_core_init(struct rtw89_dev *rtwdev);
+ void rtw89_core_deinit(struct rtw89_dev *rtwdev);
+ int rtw89_core_register(struct rtw89_dev *rtwdev);
+diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c
+index 0afe22e568f43..3b0d97da048dc 100644
+--- a/drivers/net/wireless/realtek/rtw89/pci.c
++++ b/drivers/net/wireless/realtek/rtw89/pci.c
+@@ -2299,6 +2299,22 @@ static int rtw89_pci_deglitch_setting(struct rtw89_dev *rtwdev)
+       return 0;
+ }
++static void rtw89_pci_ber(struct rtw89_dev *rtwdev)
++{
++      u32 phy_offset;
++
++      if (!test_bit(RTW89_QUIRK_PCI_BER, rtwdev->quirks))
++              return;
++
++      phy_offset = R_RAC_DIRECT_OFFSET_G1;
++      rtw89_write16(rtwdev, phy_offset + RAC_ANA1E * RAC_MULT, RAC_ANA1E_G1_VAL);
++      rtw89_write16(rtwdev, phy_offset + RAC_ANA2E * RAC_MULT, RAC_ANA2E_VAL);
++
++      phy_offset = R_RAC_DIRECT_OFFSET_G2;
++      rtw89_write16(rtwdev, phy_offset + RAC_ANA1E * RAC_MULT, RAC_ANA1E_G2_VAL);
++      rtw89_write16(rtwdev, phy_offset + RAC_ANA2E * RAC_MULT, RAC_ANA2E_VAL);
++}
++
+ static void rtw89_pci_rxdma_prefth(struct rtw89_dev *rtwdev)
+ {
+       if (rtwdev->chip->chip_id != RTL8852A)
+@@ -2696,6 +2712,7 @@ static int rtw89_pci_ops_mac_pre_init_ax(struct rtw89_dev *rtwdev)
+       const struct rtw89_pci_info *info = rtwdev->pci_info;
+       int ret;
++      rtw89_pci_ber(rtwdev);
+       rtw89_pci_rxdma_prefth(rtwdev);
+       rtw89_pci_l1off_pwroff(rtwdev);
+       rtw89_pci_deglitch_setting(rtwdev);
+@@ -4172,6 +4189,8 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+       rtwdev->hci.rpwm_addr = pci_info->rpwm_addr;
+       rtwdev->hci.cpwm_addr = pci_info->cpwm_addr;
++      rtw89_check_quirks(rtwdev, info->quirks);
++
+       SET_IEEE80211_DEV(rtwdev->hw, &pdev->dev);
+       ret = rtw89_core_init(rtwdev);
+diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h
+index a63b6b7c9bfaf..87e7081664c1f 100644
+--- a/drivers/net/wireless/realtek/rtw89/pci.h
++++ b/drivers/net/wireless/realtek/rtw89/pci.h
+@@ -26,11 +26,16 @@
+ #define RAC_REG_FLD_0                 0x1D
+ #define BAC_AUTOK_N_MASK              GENMASK(3, 2)
+ #define PCIE_AUTOK_4                  0x3
++#define RAC_ANA1E                     0x1E
++#define RAC_ANA1E_G1_VAL              0x66EA
++#define RAC_ANA1E_G2_VAL              0x6EEA
+ #define RAC_ANA1F                     0x1F
+ #define RAC_ANA24                     0x24
+ #define B_AX_DEGLITCH                 GENMASK(11, 8)
+ #define RAC_ANA26                     0x26
+ #define B_AX_RXEN                     GENMASK(15, 14)
++#define RAC_ANA2E                     0x2E
++#define RAC_ANA2E_VAL                 0xFFFE
+ #define RAC_CTRL_PPR_V1                       0x30
+ #define B_AX_CLK_CALIB_EN             BIT(12)
+ #define B_AX_CALIB_EN                 BIT(13)
+diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851be.c b/drivers/net/wireless/realtek/rtw89/rtw8851be.c
+index ca1374a717272..ec3629d95fda1 100644
+--- a/drivers/net/wireless/realtek/rtw89/rtw8851be.c
++++ b/drivers/net/wireless/realtek/rtw89/rtw8851be.c
+@@ -63,6 +63,7 @@ static const struct rtw89_pci_info rtw8851b_pci_info = {
+ static const struct rtw89_driver_info rtw89_8851be_info = {
+       .chip = &rtw8851b_chip_info,
++      .quirks = NULL,
+       .bus = {
+               .pci = &rtw8851b_pci_info,
+       },
+diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c
+index 7c6ffedb77e27..fdee5dd4ba148 100644
+--- a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c
++++ b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c
+@@ -61,6 +61,7 @@ static const struct rtw89_pci_info rtw8852a_pci_info = {
+ static const struct rtw89_driver_info rtw89_8852ae_info = {
+       .chip = &rtw8852a_chip_info,
++      .quirks = NULL,
+       .bus = {
+               .pci = &rtw8852a_pci_info,
+       },
+diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852be.c b/drivers/net/wireless/realtek/rtw89/rtw8852be.c
+index ed71364e6437b..5f941122655c4 100644
+--- a/drivers/net/wireless/realtek/rtw89/rtw8852be.c
++++ b/drivers/net/wireless/realtek/rtw89/rtw8852be.c
+@@ -63,6 +63,7 @@ static const struct rtw89_pci_info rtw8852b_pci_info = {
+ static const struct rtw89_driver_info rtw89_8852be_info = {
+       .chip = &rtw8852b_chip_info,
++      .quirks = NULL,
+       .bus = {
+               .pci = &rtw8852b_pci_info,
+       },
+diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c
+index 583ea673a4f54..e07c7f3ade41e 100644
+--- a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c
++++ b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c
+@@ -68,8 +68,31 @@ static const struct rtw89_pci_info rtw8852c_pci_info = {
+       .recognize_intrs        = rtw89_pci_recognize_intrs_v1,
+ };
++static const struct dmi_system_id rtw8852c_pci_quirks[] = {
++      {
++              .ident = "Dell Inc. Vostro 16 5640",
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++                      DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 16 5640"),
++                      DMI_MATCH(DMI_PRODUCT_SKU, "0CA0"),
++              },
++              .driver_data = (void *)RTW89_QUIRK_PCI_BER,
++      },
++      {
++              .ident = "Dell Inc. Inspiron 16 5640",
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++                      DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 16 5640"),
++                      DMI_MATCH(DMI_PRODUCT_SKU, "0C9F"),
++              },
++              .driver_data = (void *)RTW89_QUIRK_PCI_BER,
++      },
++      {},
++};
++
+ static const struct rtw89_driver_info rtw89_8852ce_info = {
+       .chip = &rtw8852c_chip_info,
++      .quirks = rtw8852c_pci_quirks,
+       .bus = {
+               .pci = &rtw8852c_pci_info,
+       },
+diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922ae.c b/drivers/net/wireless/realtek/rtw89/rtw8922ae.c
+index 4981b657bd7b0..ce8aaa9501e16 100644
+--- a/drivers/net/wireless/realtek/rtw89/rtw8922ae.c
++++ b/drivers/net/wireless/realtek/rtw89/rtw8922ae.c
+@@ -61,6 +61,7 @@ static const struct rtw89_pci_info rtw8922a_pci_info = {
+ static const struct rtw89_driver_info rtw89_8922ae_info = {
+       .chip = &rtw8922a_chip_info,
++      .quirks = NULL,
+       .bus = {
+               .pci = &rtw8922a_pci_info,
+       },
+-- 
+2.43.0
+
diff --git a/queue-6.9/xhci-remove-xhci_trust_tx_length-quirk.patch b/queue-6.9/xhci-remove-xhci_trust_tx_length-quirk.patch
new file mode 100644 (file)
index 0000000..acd2199
--- /dev/null
@@ -0,0 +1,189 @@
+From c901e085aac4c4b3b7dca2d7e450ff77701f0299 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Apr 2024 17:02:36 +0300
+Subject: xhci: remove XHCI_TRUST_TX_LENGTH quirk
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+[ Upstream commit 34b67198244f2d7d8409fa4eb76204c409c0c97e ]
+
+If this quirk was set then driver would treat transfer events with
+'Success' completion code as 'Short packet' if there were untransferred
+bytes left.
+
+This is so common that turn it into default behavior.
+
+xhci_warn_ratelimited() is no longer used after this, so remove it.
+
+A success event with untransferred bytes left doesn't always mean a
+misbehaving controller. If there was an error mid a multi-TRB TD it's
+allowed to issue a success event for the last TRB in that TD.
+
+See xhci 1.2 spec 4.9.1 Transfer Descriptors
+
+"Note: If an error is detected while processing a multi-TRB TD, the xHC
+ shall generate a Transfer Event for the TRB that the error was detected
+ on with the appropriate error Condition Code, then may advance to the
+ next TD. If in the process of advancing to the next TD, a Transfer TRB
+ is encountered with its IOC flag set, then the Condition Code of the
+ Transfer Event generated for that Transfer TRB should be Success,
+ because there was no error actually associated with the TRB that
+ generated the Event. However, an xHC implementation may redundantly
+ assert the original error Condition Code."
+
+Co-developed-by: Niklas Neronin <niklas.neronin@linux.intel.com>
+Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20240429140245.3955523-10-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-pci.c  | 15 ++-------------
+ drivers/usb/host/xhci-rcar.c |  6 ++----
+ drivers/usb/host/xhci-ring.c | 15 +++++----------
+ drivers/usb/host/xhci.h      |  4 +---
+ 4 files changed, 10 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
+index b271ec916926b..febf64723434c 100644
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -271,17 +271,12 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+                               "QUIRK: Fresco Logic revision %u "
+                               "has broken MSI implementation",
+                               pdev->revision);
+-              xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+       }
+       if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
+                       pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_FL1009)
+               xhci->quirks |= XHCI_BROKEN_STREAMS;
+-      if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
+-                      pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_FL1100)
+-              xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+-
+       if (pdev->vendor == PCI_VENDOR_ID_NEC)
+               xhci->quirks |= XHCI_NEC_HOST;
+@@ -308,11 +303,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+               xhci->quirks |= XHCI_RESET_ON_RESUME;
+       }
+-      if (pdev->vendor == PCI_VENDOR_ID_AMD) {
+-              xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+-              if (pdev->device == 0x43f7)
+-                      xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW;
+-      }
++      if (pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x43f7)
++              xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW;
+       if ((pdev->vendor == PCI_VENDOR_ID_AMD) &&
+               ((pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4) ||
+@@ -400,7 +392,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+       if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
+                       pdev->device == PCI_DEVICE_ID_EJ168) {
+               xhci->quirks |= XHCI_RESET_ON_RESUME;
+-              xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+               xhci->quirks |= XHCI_BROKEN_STREAMS;
+       }
+       if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
+@@ -411,7 +402,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+       if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
+           pdev->device == 0x0014) {
+-              xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+               xhci->quirks |= XHCI_ZERO_64B_REGS;
+       }
+       if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
+@@ -441,7 +431,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+       }
+       if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
+               pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) {
+-              xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+               xhci->quirks |= XHCI_NO_64BIT_SUPPORT;
+       }
+       if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
+diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c
+index ab9c5969e4624..8b357647728c2 100644
+--- a/drivers/usb/host/xhci-rcar.c
++++ b/drivers/usb/host/xhci-rcar.c
+@@ -214,8 +214,7 @@ static int xhci_rcar_resume_quirk(struct usb_hcd *hcd)
+  */
+ #define SET_XHCI_PLAT_PRIV_FOR_RCAR(firmware)                         \
+       .firmware_name = firmware,                                      \
+-      .quirks = XHCI_NO_64BIT_SUPPORT | XHCI_TRUST_TX_LENGTH |        \
+-                XHCI_SLOW_SUSPEND,                                    \
++      .quirks = XHCI_NO_64BIT_SUPPORT |  XHCI_SLOW_SUSPEND,           \
+       .init_quirk = xhci_rcar_init_quirk,                             \
+       .plat_start = xhci_rcar_start,                                  \
+       .resume_quirk = xhci_rcar_resume_quirk,
+@@ -229,8 +228,7 @@ static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen3 = {
+ };
+ static const struct xhci_plat_priv xhci_plat_renesas_rzv2m = {
+-      .quirks = XHCI_NO_64BIT_SUPPORT | XHCI_TRUST_TX_LENGTH |
+-                XHCI_SLOW_SUSPEND,
++      .quirks = XHCI_NO_64BIT_SUPPORT | XHCI_SLOW_SUSPEND,
+       .init_quirk = xhci_rzv2m_init_quirk,
+       .plat_start = xhci_rzv2m_start,
+ };
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index 850846c206ed4..48d745e9f9730 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -2431,8 +2431,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
+                       break;
+               if (remaining) {
+                       frame->status = short_framestatus;
+-                      if (xhci->quirks & XHCI_TRUST_TX_LENGTH)
+-                              sum_trbs_for_length = true;
++                      sum_trbs_for_length = true;
+                       break;
+               }
+               frame->status = 0;
+@@ -2681,15 +2680,11 @@ static int handle_tx_event(struct xhci_hcd *xhci,
+        * transfer type
+        */
+       case COMP_SUCCESS:
+-              if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0)
+-                      break;
+-              if (xhci->quirks & XHCI_TRUST_TX_LENGTH ||
+-                  ep_ring->last_td_was_short)
++              if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
+                       trb_comp_code = COMP_SHORT_PACKET;
+-              else
+-                      xhci_warn_ratelimited(xhci,
+-                                            "WARN Successful completion on short TX for slot %u ep %u: needs XHCI_TRUST_TX_LENGTH quirk?\n",
+-                                            slot_id, ep_index);
++                      xhci_dbg(xhci, "Successful completion on short TX for slot %u ep %u with last td short %d\n",
++                               slot_id, ep_index, ep_ring->last_td_was_short);
++              }
+               break;
+       case COMP_SHORT_PACKET:
+               break;
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index 069a187540a0c..1683d779e4bc0 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1590,7 +1590,7 @@ struct xhci_hcd {
+ #define XHCI_RESET_ON_RESUME  BIT_ULL(7)
+ #define       XHCI_SW_BW_CHECKING     BIT_ULL(8)
+ #define XHCI_AMD_0x96_HOST    BIT_ULL(9)
+-#define XHCI_TRUST_TX_LENGTH  BIT_ULL(10)
++#define XHCI_TRUST_TX_LENGTH  BIT_ULL(10) /* Deprecated */
+ #define XHCI_LPM_SUPPORT      BIT_ULL(11)
+ #define XHCI_INTEL_HOST               BIT_ULL(12)
+ #define XHCI_SPURIOUS_REBOOT  BIT_ULL(13)
+@@ -1730,8 +1730,6 @@ static inline bool xhci_has_one_roothub(struct xhci_hcd *xhci)
+       dev_err(xhci_to_hcd(xhci)->self.controller , fmt , ## args)
+ #define xhci_warn(xhci, fmt, args...) \
+       dev_warn(xhci_to_hcd(xhci)->self.controller , fmt , ## args)
+-#define xhci_warn_ratelimited(xhci, fmt, args...) \
+-      dev_warn_ratelimited(xhci_to_hcd(xhci)->self.controller , fmt , ## args)
+ #define xhci_info(xhci, fmt, args...) \
+       dev_info(xhci_to_hcd(xhci)->self.controller , fmt , ## args)
+-- 
+2.43.0
+