From: Sasha Levin Date: Fri, 21 Jun 2024 15:39:24 +0000 (-0400) Subject: Fixes for 6.9 X-Git-Tag: v6.1.96~75 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bb9f901eccf9b6d32238d629b0a61fb1e3116371;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.9 Signed-off-by: Sasha Levin --- 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 index 00000000000..fc00ce3cac1 --- /dev/null +++ b/queue-6.9/acpi-ec-install-address-space-handler-at-the-namespa.patch @@ -0,0 +1,131 @@ +From 4b8b13358d687b767f4b4c129bd4eed43477e5f2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 May 2024 21:40:54 +0200 +Subject: ACPI: EC: Install address space handler at the namespace root + +From: Rafael J. Wysocki + +[ 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 +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 +Signed-off-by: Rafael J. Wysocki +Reviewed-by: Hans de Goede +Reviewed-by: Mario Limonciello +Reviewed-by: Andy Shevchenko +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..f5ae1724428 --- /dev/null +++ b/queue-6.9/acpi-resource-do-irq-override-on-gmxbgxx-xmg-apex-17.patch @@ -0,0 +1,45 @@ +From 8cb0cf1c1a269209d6af930c5cab1cde8ab253d8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 15 Apr 2024 20:51:18 +0200 +Subject: ACPI: resource: Do IRQ override on GMxBGxx (XMG APEX 17 M23) + +From: Guenter Schafranek + +[ 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 +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..6c2f0c7cdd5 --- /dev/null +++ b/queue-6.9/acpi-resource-skip-irq-override-on-asus-vivobook-pro.patch @@ -0,0 +1,45 @@ +From accaab45570f2362b974eaa361bad8d0e351a253 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Apr 2024 13:08:12 -0400 +Subject: ACPI: resource: Skip IRQ override on Asus Vivobook Pro N6506MV + +From: Tamim Khan + +[ 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 +Signed-off-by: Tamim Khan +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..a9679641586 --- /dev/null +++ b/queue-6.9/acpi-video-add-backlight-native-quirk-for-lenovo-sli.patch @@ -0,0 +1,47 @@ +From d59d25b059d576496071429175afd15f2c00bc60 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 May 2024 16:08:50 +0200 +Subject: ACPI: video: Add backlight=native quirk for Lenovo Slim 7 16ARH7 + +From: Takashi Iwai + +[ 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 +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..7dde7992bcf --- /dev/null +++ b/queue-6.9/acpi-x86-add-pnp_uart1_skip-quirk-for-lenovo-blade2-.patch @@ -0,0 +1,89 @@ +From 28471a74e51330c9c0062d3e12f654a6f41148f2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..d36a2e27006 --- /dev/null +++ b/queue-6.9/af_packet-avoid-a-false-positive-warning-in-packet_s.patch @@ -0,0 +1,81 @@ +From 770942a1e647c0d193f878047164336a0b78ebc0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 5 Apr 2024 11:49:39 +0000 +Subject: af_packet: avoid a false positive warning in packet_setsockopt() + +From: Eric Dumazet + +[ 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 +Signed-off-by: Eric Dumazet +Cc: Kees Cook +Cc: Willem de Bruijn +Reviewed-by: Kees Cook +Reviewed-by: Willem de Bruijn +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..bd2fc3a38fa --- /dev/null +++ b/queue-6.9/alsa-hda-realtek-add-quirks-for-hp-omen-models-using.patch @@ -0,0 +1,46 @@ +From 4ee88440862349990cb5b89645176935bf928f68 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Apr 2024 12:08:09 +0100 +Subject: ALSA: hda/realtek: Add quirks for HP Omen models using CS35L41 + +From: Stefan Binding + +[ 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 +Signed-off-by: Takashi Iwai +Message-ID: <20240411110813.330483-4-sbinding@opensource.cirrus.com> +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..815ac4eab0e --- /dev/null +++ b/queue-6.9/alsa-hda-realtek-add-quirks-for-lenovo-13x.patch @@ -0,0 +1,37 @@ +From cabed86c6eb55fdd6dbebfc6d84eb388ee3d3127 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Apr 2024 17:23:03 +0100 +Subject: ALSA: hda/realtek: Add quirks for Lenovo 13X + +From: Stefan Binding + +[ 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 +Message-ID: <20240423162303.638211-3-sbinding@opensource.cirrus.com> +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..df6f719247d --- /dev/null +++ b/queue-6.9/arm64-defconfig-select-interconnect_qcom_sm6115-as-b.patch @@ -0,0 +1,37 @@ +From c11d3be03d993557746a8d585d9428ced1459434 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Apr 2024 04:19:27 +0300 +Subject: arm64: defconfig: select INTERCONNECT_QCOM_SM6115 as built-in + +From: Dmitry Baryshkov + +[ 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 +Link: https://lore.kernel.org/r/20240424-enable-sm6115-icc-v3-1-21c83be48f0e@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..90e0f9d77a8 --- /dev/null +++ b/queue-6.9/arm64-sysreg-update-pie-permission-encodings.patch @@ -0,0 +1,98 @@ +From b12c572a695336fbfc92a5b011bb85440b9e65ba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 21 Apr 2024 14:33:28 +0800 +Subject: arm64/sysreg: Update PIE permission encodings + +From: Shiqi Liu + +[ 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 +Acked-by: Marc Zyngier +Reviewed-by: Catalin Marinas +Link: https://lore.kernel.org/r/20240421063328.29710-1-shiqiliu@hust.edu.cn +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..47ef0ee7238 --- /dev/null +++ b/queue-6.9/asoc-intel-sof_cs42l42-rename-bt-offload-quirk.patch @@ -0,0 +1,56 @@ +From 25de722027644cf7cbb33d6e7566bc924103718c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Mar 2024 17:10:44 -0500 +Subject: ASoC: Intel: sof_cs42l42: rename BT offload quirk + +From: Brent Lu + +[ 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 +Signed-off-by: Brent Lu +Signed-off-by: Pierre-Louis Bossart +Link: https://msgid.link/r/20240325221059.206042-7-pierre-louis.bossart@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..fbbd84efa00 --- /dev/null +++ b/queue-6.9/asoc-intel-sof_sdw-add-jd2-quirk-for-hp-omen-14.patch @@ -0,0 +1,42 @@ +From a2505346878cb09610ac8066f9d6c993cef41dbf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ Upstream commit 4fee07fbf47d2a5f1065d985459e5ce7bf7969f0 ] + +The default JD1 does not seem to work, use JD2 instead. + +Signed-off-by: Pierre-Louis Bossart +Link: https://lore.kernel.org/r/20240411220347.131267-4-pierre-louis.bossart@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..0a7dac09869 --- /dev/null +++ b/queue-6.9/asoc-intel-sof_sdw-add-quirk-for-dell-sku-0c0f.patch @@ -0,0 +1,46 @@ +From c78d7dd9481a1555cebc1e442cd5c9dc6a50d918 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Apr 2024 17:03:39 -0500 +Subject: ASoC: Intel: sof_sdw: add quirk for Dell SKU 0C0F + +From: Pierre-Louis Bossart + +[ 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 +Reviewed-by: Bard Liao +Link: https://lore.kernel.org/r/20240411220347.131267-5-pierre-louis.bossart@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..b6b55afb118 --- /dev/null +++ b/queue-6.9/avoid-hw_desc-array-overrun-in-dw-axi-dmac.patch @@ -0,0 +1,77 @@ +From 35ee34be96196e99a8593152fc02bbfa16fbfa90 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Mar 2024 10:49:24 +0000 +Subject: Avoid hw_desc array overrun in dw-axi-dmac + +From: Joao Pinto + +[ 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 +Link: https://lore.kernel.org/r/1711536564-12919-1-git-send-email-jpinto@synopsys.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..dd8fc442bd1 --- /dev/null +++ b/queue-6.9/batman-adv-bypass-empty-buckets-in-batadv_purge_orig.patch @@ -0,0 +1,110 @@ +From f2444ffdf5a83bb406276a7195832c407aef6baa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 30 Mar 2024 15:54:38 +0000 +Subject: batman-adv: bypass empty buckets in batadv_purge_orig_ref() + +From: Eric Dumazet + +[ 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): [] __local_bh_enable_ip+0x224/0x44c kernel/softirq.c:386 + hardirqs last disabled at (6182794): [] __el1_irq arch/arm64/kernel/entry-common.c:533 [inline] + hardirqs last disabled at (6182794): [] el1_interrupt+0x24/0x68 arch/arm64/kernel/entry-common.c:551 + softirqs last enabled at (6182792): [] spin_unlock_bh include/linux/spinlock.h:396 [inline] + softirqs last enabled at (6182792): [] batadv_purge_orig_ref+0x114c/0x1228 net/batman-adv/originator.c:1287 + softirqs last disabled at (6182790): [] spin_lock_bh include/linux/spinlock.h:356 [inline] + softirqs last disabled at (6182790): [] 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 +Signed-off-by: Sven Eckelmann +Signed-off-by: Simon Wunderlich +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..8b74fe37181 --- /dev/null +++ b/queue-6.9/block-ioctl-prefer-different-overflow-check.patch @@ -0,0 +1,88 @@ +From 8b7633082325017cf15beb69b64fd80013e253a9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 May 2024 03:53:49 +0000 +Subject: block/ioctl: prefer different overflow check + +From: Justin Stitt + +[ 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] +[ 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 +Reviewed-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20240507-b4-sio-block-ioctl-v3-1-ba0c2b32275e@google.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..80dde787d05 --- /dev/null +++ b/queue-6.9/bluetooth-ath3k-fix-multiple-issues-reported-by-chec.patch @@ -0,0 +1,190 @@ +From ec4615daa60c2d782ea403da8b5e87464c57e43f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 6 Apr 2024 00:42:24 +0300 +Subject: Bluetooth: ath3k: Fix multiple issues reported by checkpatch.pl + +From: Uri Arev + +[ 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 +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + 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 + #include + #include +@@ -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 index 00000000000..18d703f91fd --- /dev/null +++ b/queue-6.9/bpf-avoid-kfree_rcu-under-lock-in-bpf_lpm_trie.patch @@ -0,0 +1,102 @@ +From 4cf47ae2ac977f2150800aa5dabd7bfaf2093d4b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Mar 2024 10:14:39 -0700 +Subject: bpf: Avoid kfree_rcu() under lock in bpf_lpm_trie. + +From: Alexei Starovoitov + +[ 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 +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20240329171439.37813-1-alexei.starovoitov@gmail.com +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..fdc7d340282 --- /dev/null +++ b/queue-6.9/bpf-avoid-uninitialized-warnings-in-verifier_global_.patch @@ -0,0 +1,69 @@ +From ea4f0bc17ae646ce580b331db8736d05149d9bff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 May 2024 20:47:56 +0200 +Subject: bpf: avoid uninitialized warnings in verifier_global_subprogs.c + +From: Jose E. Marchesi + +[ 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 +Cc: david.faust@oracle.com +Cc: cupertino.miranda@oracle.com +Cc: Yonghong Song +Cc: Eduard Zingerman +Acked-by: Yonghong Song +Link: https://lore.kernel.org/r/20240507184756.1772-1-jose.marchesi@oracle.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + .../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 index 00000000000..d4c3343f3a4 --- /dev/null +++ b/queue-6.9/cgroup-cpuset-make-cpuset-hotplug-processing-synchro.patch @@ -0,0 +1,462 @@ +From 4b7d38a52a42bec3bdacdff0de92db3090ca492b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Apr 2024 09:47:48 -0400 +Subject: cgroup/cpuset: Make cpuset hotplug processing synchronous + +From: Waiman Long + +[ 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 +Tested-by: Valentin Schneider +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..a8b5011f454 --- /dev/null +++ b/queue-6.9/clocksource-make-watchdog-and-suspend-timing-multipl.patch @@ -0,0 +1,143 @@ +From 9dcfa1b9a635e6f58ff76a81653f7ef64df382cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Mar 2024 08:40:23 +0200 +Subject: clocksource: Make watchdog and suspend-timing multiplication overflow + safe + +From: Adrian Hunter + +[ 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 +Signed-off-by: Adrian Hunter +Signed-off-by: Thomas Gleixner +Link: https://lore.kernel.org/r/20240325064023.2997-20-adrian.hunter@intel.com +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..e380189a4c6 --- /dev/null +++ b/queue-6.9/cpufreq-amd-pstate-fix-memory-leak-on-cpu-epp-exit.patch @@ -0,0 +1,43 @@ +From 06bc74f02509d5d5afe93e4dba7da825c982039e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 May 2024 14:30:42 +0800 +Subject: cpufreq: amd-pstate: fix memory leak on CPU EPP exit + +From: Peng Ma + +[ 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 +Acked-by: Mario Limonciello +Reviewed-by: Perry Yuan +[ rjw: Subject and changelog edits ] +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..39743d983d0 --- /dev/null +++ b/queue-6.9/crypto-hisilicon-qm-add-the-err-memory-release-proce.patch @@ -0,0 +1,46 @@ +From b15c02b8b7d37cdc71a50ada9c2f925fd36059a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..e8a64fd4740 --- /dev/null +++ b/queue-6.9/crypto-hisilicon-sec-fix-memory-leak-for-sec-resourc.patch @@ -0,0 +1,42 @@ +From c3a03d6f647b960c8c34d53d3382335b9376bde1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 7 Apr 2024 15:59:58 +0800 +Subject: crypto: hisilicon/sec - Fix memory leak for sec resource release + +From: Chenghai Huang + +[ 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 +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..3bba8d24494 --- /dev/null +++ b/queue-6.9/cxl-add-post-reset-warning-if-reset-results-in-loss-.patch @@ -0,0 +1,130 @@ +From c22893bb2a4154b6fa83ce584c6fae79dee7afbf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20240502165851.1948523-6-dave.jiang@intel.com +Signed-off-by: Dave Jiang +Signed-off-by: Bjorn Helgaas +Reviewed-by: Jonathan Cameron +Reviewed-by: Dan Williams +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..538af043a19 --- /dev/null +++ b/queue-6.9/devlink-use-kvzalloc-to-allocate-devlink-instance-re.patch @@ -0,0 +1,86 @@ +From c4415ce313c2ddf2a8ea8a84211e0d7e084fca0a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Mar 2024 16:21:28 +0800 +Subject: devlink: use kvzalloc() to allocate devlink instance resources + +From: Jian Wen + +[ 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 +Link: https://lore.kernel.org/r/20240327082128.942818-1-wenjian1@xiaomi.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..747de8ad7ba --- /dev/null +++ b/queue-6.9/drm-amd-display-exit-idle-optimizations-before-hdcp-.patch @@ -0,0 +1,88 @@ +From 5ba8662aea142c261e8d93287f9c7be18adae5da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 12 Feb 2024 16:51:59 -0500 +Subject: drm/amd/display: Exit idle optimizations before HDCP execution + +From: Nicholas Kazlauskas + +[ 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 +Cc: Alex Deucher +Reviewed-by: Charlene Liu +Acked-by: Alex Hung +Signed-off-by: Nicholas Kazlauskas +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..75b2346c091 --- /dev/null +++ b/queue-6.9/drm-amd-display-workaround-register-access-in-idle-r.patch @@ -0,0 +1,84 @@ +From 583d21803548c89b0a0d74caa69b38a644a24dd2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Feb 2024 16:52:40 -0500 +Subject: drm/amd/display: Workaround register access in idle race with cursor + +From: Nicholas Kazlauskas + +[ 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 +Acked-by: Wayne Lin +Signed-off-by: Nicholas Kazlauskas +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..a909f00d533 --- /dev/null +++ b/queue-6.9/drm-lima-add-mask-irq-callback-to-gp-and-pp.patch @@ -0,0 +1,145 @@ +From 11fe8f45ad1a51d7c946df515f65e28fdb0014f0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 5 Apr 2024 17:29:49 +0200 +Subject: drm/lima: add mask irq callback to gp and pp + +From: Erico Nunes + +[ 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 +Signed-off-by: Qiang Yu +Link: https://patchwork.freedesktop.org/patch/msgid/20240405152951.1531555-2-nunes.erico@gmail.com +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..39a75435657 --- /dev/null +++ b/queue-6.9/drm-lima-include-pp-bcast-irq-in-timeout-handler-che.patch @@ -0,0 +1,40 @@ +From a1d9bfe2adc180678aacd1c7a985590101c63f67 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 5 Apr 2024 17:29:50 +0200 +Subject: drm/lima: include pp bcast irq in timeout handler check + +From: Erico Nunes + +[ 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 +Signed-off-by: Qiang Yu +Link: https://patchwork.freedesktop.org/patch/msgid/20240405152951.1531555-3-nunes.erico@gmail.com +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..986fc85d41a --- /dev/null +++ b/queue-6.9/drm-lima-mask-irqs-in-timeout-path-before-hard-reset.patch @@ -0,0 +1,63 @@ +From b4ad08ed3d1a679f5cf8b27e0743e3fa7ef3a1cc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 5 Apr 2024 17:29:51 +0200 +Subject: drm/lima: mask irqs in timeout path before hard reset + +From: Erico Nunes + +[ 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 +Reviewed-by: Qiang Yu +Signed-off-by: Qiang Yu +Link: https://patchwork.freedesktop.org/patch/msgid/20240405152951.1531555-4-nunes.erico@gmail.com +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..5a1d36b4bcf --- /dev/null +++ b/queue-6.9/drop_monitor-replace-spin_lock-by-raw_spin_lock.patch @@ -0,0 +1,155 @@ +From 0bf1bac942a8f6eff7e2192d87461cbb7ca66d38 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Apr 2024 11:13:46 -0300 +Subject: drop_monitor: replace spin_lock by raw_spin_lock + +From: Wander Lairson Costa + +[ 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): [] _raw_spin_unlock_irqrestore+0x63/0x80 +hardirqs last disabled at (139909): [] trace_drop_common.constprop.0+0x26d/0x290 +softirqs last enabled at (139892): [] __local_bh_enable_ip+0x103/0x170 +softirqs last disabled at (139898): [] rcu_cpu_kthread+0x93/0x1f0 +Preemption disabled at: +[] 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: + + 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 +Reported-by: Hu Chunyu +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..911351362dd --- /dev/null +++ b/queue-6.9/ext4-do-not-create-ea-inode-under-buffer-lock.patch @@ -0,0 +1,242 @@ +From beae47de49acaf691da5d3fc2804c82e66bbb411 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Mar 2024 17:26:50 +0100 +Subject: ext4: do not create EA inode under buffer lock + +From: Jan Kara + +[ 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 +Link: https://lore.kernel.org/r/20240321162657.27420-2-jack@suse.cz +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..044310f016f --- /dev/null +++ b/queue-6.9/ext4-fix-uninitialized-ratelimit_state-lock-access-i.patch @@ -0,0 +1,139 @@ +From 88701995e373ff9b570b229a1fc7d16b8e1ef943 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Jan 2024 21:37:30 +0800 +Subject: ext4: fix uninitialized ratelimit_state->lock access in + __ext4_fill_super() + +From: Baokun Li + +[ 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 +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20240102133730.1098120-1-libaokun1@huawei.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..50cc457e9d9 --- /dev/null +++ b/queue-6.9/f2fs-don-t-set-ro-when-shutting-down-f2fs.patch @@ -0,0 +1,61 @@ +From 9a5d04de8af3870b424beb070dfe275c65c553f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 (謝明燈)" +Reviewed-by: Daeho Jeong +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..d7e444830f6 --- /dev/null +++ b/queue-6.9/f2fs-fix-to-detect-inconsistent-nat-entry-during-tru.patch @@ -0,0 +1,71 @@ +From deeb3102f02310f6d207ee0fd505976bc9479386 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Mar 2024 22:59:55 +0800 +Subject: f2fs: fix to detect inconsistent nat entry during truncation + +From: Chao Yu + +[ 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 +Closes: https://lore.kernel.org/linux-f2fs-devel/085b27fd2b364a3c8c3a9ca77363e246@omp.ru +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..89fedd6bb56 --- /dev/null +++ b/queue-6.9/f2fs-remove-clear-sb_inlinecrypt-flag-in-default_opt.patch @@ -0,0 +1,49 @@ +From be70614d87628a3d26a2c9d05842bba1b19657a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Mar 2024 14:10:43 +0800 +Subject: f2fs: remove clear SB_INLINECRYPT flag in default_options + +From: Yunlei He + +[ 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 +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..a50c2ab1003 --- /dev/null +++ b/queue-6.9/fs-writeback-bail-out-if-there-is-no-more-inodes-for.patch @@ -0,0 +1,63 @@ +From 390625218b45316aed191f37c64be43b406377f0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20240228091958.288260-3-shikemeng@huaweicloud.com +Reviewed-by: Jan Kara +[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 +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..83aed1fc095 --- /dev/null +++ b/queue-6.9/hid-add-quirk-for-logitech-casa-touchpad.patch @@ -0,0 +1,56 @@ +From 09574bae016081cf3b951f155a385ff003aae726 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Apr 2024 18:08:05 +0000 +Subject: HID: Add quirk for Logitech Casa touchpad + +From: Sean O'Brien + +[ 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 +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..cad7b8b7033 --- /dev/null +++ b/queue-6.9/hid-asus-fix-more-n-key-report-descriptors-if-n-key-.patch @@ -0,0 +1,101 @@ +From ed1bc62a63bf7669628486883e1d5adc0a76539a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..8d2efe3c5de --- /dev/null +++ b/queue-6.9/i2c-lpi2c-avoid-calling-clk_get_rate-during-transfer.patch @@ -0,0 +1,75 @@ +From 865235dcddaa1b2049681a69a8015e5a9629b46b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Uwe Kleine-König +Reviewed-by: Andi Shyti +Signed-off-by: Andi Shyti +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..4b601595b28 --- /dev/null +++ b/queue-6.9/io_uring-sqpoll-work-around-a-potential-audit-memory.patch @@ -0,0 +1,66 @@ +From 568b5fba320c91d86c0a06bf4c523b5bd71bf942 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Mar 2024 07:38:38 -0600 +Subject: io_uring/sqpoll: work around a potential audit memory leak + +From: Jens Axboe + +[ 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 +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..57866b1b1e7 --- /dev/null +++ b/queue-6.9/iommu-arm-smmu-v3-free-msis-in-case-of-enomem.patch @@ -0,0 +1,40 @@ +From 4ce693f5b91a678f3cfb7eb03204db902b0b752d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Apr 2024 12:37:59 +0700 +Subject: iommu/arm-smmu-v3: Free MSIs in case of ENOMEM + +From: Aleksandr Aprelkov + +[ 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 +Link: https://lore.kernel.org/r/20240403053759.643164-1-aaprelkov@usergate.com +[will: Tweak commit message, remove warning message] +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..843d544e016 --- /dev/null +++ b/queue-6.9/kprobe-ftrace-bail-out-if-ftrace-was-killed.patch @@ -0,0 +1,226 @@ +From 6837850d5a6bfea744116f96cdc7efe4251144f5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 May 2024 09:29:56 -0700 +Subject: kprobe/ftrace: bail out if ftrace was killed + +From: Stephen Brennan + +[ 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 +Acked-by: Masami Hiramatsu (Google) +Acked-by: Guo Ren +Reviewed-by: Steven Rostedt (Google) +Signed-off-by: Masami Hiramatsu (Google) +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..a64dad039db --- /dev/null +++ b/queue-6.9/kselftest-arm64-add-a-null-pointer-check.patch @@ -0,0 +1,48 @@ +From 9c204d4a99f1ab6037549da063accbe784d9c974 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Apr 2024 16:21:02 +0800 +Subject: kselftest: arm64: Add a null pointer check + +From: Kunwu Chan + +[ 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 +Reviewed-by: Muhammad Usama Anjum +Link: https://lore.kernel.org/r/20240423082102.2018886-1-chentao@kylinos.cn +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + 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 + #include + #include ++#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 index 00000000000..aaf9a7e47a8 --- /dev/null +++ b/queue-6.9/media-intel-ipu6-fix-build-with-acpi.patch @@ -0,0 +1,263 @@ +From 7b50c58577a70319ec9e3470446e74670c215574 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Sakari Ailus +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + 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 + #include + ++#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 index 00000000000..b212c9bc448 --- /dev/null +++ b/queue-6.9/media-mtk-vcodec-potential-null-pointer-deference-in.patch @@ -0,0 +1,36 @@ +From 54a7099c1a776c742678a925b91bacb7f7723c14 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Jan 2024 02:35:06 +0000 +Subject: media: mtk-vcodec: potential null pointer deference in SCP + +From: Fullway Wang + +[ 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 +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + .../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 index 00000000000..e27e7a9896e --- /dev/null +++ b/queue-6.9/mips-octeon-add-pcie-link-status-check.patch @@ -0,0 +1,55 @@ +From 7264b262bc2e36cd302e94fff26cc43ebeb3e8c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Mar 2024 23:22:00 +0800 +Subject: MIPS: Octeon: Add PCIe link status check + +From: Songyang Li + +[ 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 +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..edbfb3ee3ae --- /dev/null +++ b/queue-6.9/net-dsa-realtek-do-not-assert-reset-on-remove.patch @@ -0,0 +1,55 @@ +From 5dba3bf5592ab87e26d5a8d3a17fcd8a5b1fcfbd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Linus Walleij +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..d1a3480d9fd --- /dev/null +++ b/queue-6.9/net-dsa-realtek-keep-default-led-state-in-rtl8366rb.patch @@ -0,0 +1,193 @@ +From 89df554405ea9235ac421c284eb9d337b80fdff6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Linus Walleij +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..2c79554922b --- /dev/null +++ b/queue-6.9/net-ena-add-validation-for-completion-descriptors-co.patch @@ -0,0 +1,139 @@ +From c3c21d4d1582b4e05afb311eb65a207fc0ad0036 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 May 2024 13:46:35 +0000 +Subject: net: ena: Add validation for completion descriptors consistency + +From: David Arinzon + +[ 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 +Signed-off-by: David Arinzon +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/20240512134637.25299-4-darinzon@amazon.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..a34487d4b5f --- /dev/null +++ b/queue-6.9/net-sched-fix-false-lockdep-warning-on-qdisc-root-lo.patch @@ -0,0 +1,192 @@ +From 6d9d6ba46a520909b541a58e38bac96959ae1716 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Apr 2024 15:50:11 +0200 +Subject: net/sched: fix false lockdep warning on qdisc root lock + +From: Davide Caratti + +[ 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: + + 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 + + +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 +CC: Xiumei Mu +Reported-by: Christoph Paasch +Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/451 +Signed-off-by: Davide Caratti +Link: https://lore.kernel.org/r/7dc06d6158f72053cf877a82e2a7a5bd23692faa.1713448007.git.dcaratti@redhat.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..e2e9916a60d --- /dev/null +++ b/queue-6.9/net-sfp-add-quirk-for-ats-sfp-ge-t-1000base-tx-modul.patch @@ -0,0 +1,45 @@ +From 4fb9531c6226aab7b27ebc29db59404ffda28ca0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Daniel Golle +[ rebased on top of net-next ] +Signed-off-by: Marek Behún +Link: https://lore.kernel.org/r/20240423090025.29231-1-kabel@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..540f1e393a8 --- /dev/null +++ b/queue-6.9/net-sfp-enhance-quirk-for-fibrestore-2.5g-copper-sfp.patch @@ -0,0 +1,87 @@ +From 4249b1207e83a4e6c502424c616edf36d8786f3e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Jiri Pirko +Link: https://lore.kernel.org/r/20240423085039.26957-2-kabel@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..0b271fed32d --- /dev/null +++ b/queue-6.9/netpoll-fix-race-condition-in-netpoll_owner_active.patch @@ -0,0 +1,52 @@ +From 012fdd51663039743b7f249e659915221150919e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Apr 2024 03:04:33 -0700 +Subject: netpoll: Fix race condition in netpoll_owner_active + +From: Breno Leitao + +[ 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) + + 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:?) + + 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 +Link: https://lore.kernel.org/r/20240429100437.3487432-1-leitao@debian.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..d1c66ed9c73 --- /dev/null +++ b/queue-6.9/opp-fix-required_opp_tables-for-multiple-genpds-usin.patch @@ -0,0 +1,140 @@ +From 082bfb0917ea0d0d962442767ef6ef7f1da5dfa1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 9 Apr 2024 15:53:58 +0530 +Subject: OPP: Fix required_opp_tables for multiple genpds using same table + +From: Viresh Kumar + +[ 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 +Reported-by: Vladimir Lypak +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218682 +Co-developed-by: Vladimir Lypak +Signed-off-by: Viresh Kumar +Reviewed-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..15e089b9e20 --- /dev/null +++ b/queue-6.9/padata-disable-bh-when-taking-works-lock-on-mt-path.patch @@ -0,0 +1,62 @@ +From 244ea3a2bc70e57915195bb3947503f0eca4a3e2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Apr 2024 17:36:18 +0800 +Subject: padata: Disable BH when taking works lock on MT path + +From: Herbert Xu + +[ 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 +Acked-by: Daniel Jordan +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..5d63d924ea3 --- /dev/null +++ b/queue-6.9/pci-do-not-wait-for-disconnected-devices-when-resumi.patch @@ -0,0 +1,93 @@ +From f173be21e0a998da319361a4ae8338efde810f95 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Tested-by: Mika Westerberg +Signed-off-by: Ilpo Järvinen +Signed-off-by: Bjorn Helgaas +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..33e9e7d6b23 --- /dev/null +++ b/queue-6.9/pci-pm-avoid-d3cold-for-hp-pavilion-17-pc-1972-pcie-.patch @@ -0,0 +1,71 @@ +From 583d4fcc031bf7cd4de430acf8287cdbb8bff244 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3229 +Signed-off-by: Mario Limonciello +Signed-off-by: Bjorn Helgaas +Tested-by: Eric Heintzmann +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..0c422e96bfb --- /dev/null +++ b/queue-6.9/platform-chrome-cros_usbpd_logger-provide-id-table-f.patch @@ -0,0 +1,64 @@ +From 681203ef3664967131594b65c9157ba649da38f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20240329075630.2069474-7-tzungbi@kernel.org +Signed-off-by: Tzung-Bi Shih +Signed-off-by: Sasha Levin +--- + 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 + #include ++#include + #include + #include + #include +@@ -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 index 00000000000..c46ff2a3614 --- /dev/null +++ b/queue-6.9/platform-chrome-cros_usbpd_notify-provide-id-table-f.patch @@ -0,0 +1,65 @@ +From 273920d9730c1a157a4f607eb3927b329cc10171 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Acked-by: Prashant Malani +Reviewed-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20240329075630.2069474-8-tzungbi@kernel.org +Signed-off-by: Tzung-Bi Shih +Signed-off-by: Sasha Levin +--- + 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 ++#include + #include + #include + #include +@@ -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 "); +-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 index 00000000000..2a60380e8f6 --- /dev/null +++ b/queue-6.9/platform-x86-p2sb-don-t-init-until-unassigned-resour.patch @@ -0,0 +1,86 @@ +From 788a77e7341398be0876236a94d8a31250b96700 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Acked-by: Andy Shevchenko +Tested-by: Klara Modin +Reviewed-by: Shin'ichiro Kawasaki +Link: https://lore.kernel.org/r/20240509164905.41016-1-bcfradella@proton.me +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..4415d2fac3b --- /dev/null +++ b/queue-6.9/platform-x86-toshiba_acpi-add-quirk-for-buttons-on-z.patch @@ -0,0 +1,138 @@ +From cbdf5f119f5608a462c0c92a9339a207eb9ad602 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jan 2024 12:16:41 +0100 +Subject: platform/x86: toshiba_acpi: Add quirk for buttons on Z830 + +From: Arvid Norlander + +[ 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 +Tested-by: Hans de Goede +Reviewed-by: Hans de Goede +Link: https://lore.kernel.org/r/20240131111641.4418-3-W_Armin@gmx.de +Signed-off-by: Hans de Goede +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..39e0b57a88e --- /dev/null +++ b/queue-6.9/platform-x86-x86-android-tablets-add-lenovo-yoga-tab.patch @@ -0,0 +1,306 @@ +From 15afefa8b3f5ef3aaaf091af8341fbf08b1e02c8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20240406125058.13624-2-hdegoede@redhat.com +Signed-off-by: Sasha Levin +--- + .../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 + #include + #include ++#include + #include + #include + #include +@@ -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 index 00000000000..1907e105b4c --- /dev/null +++ b/queue-6.9/platform-x86-x86-android-tablets-unregister-devices-.patch @@ -0,0 +1,99 @@ +From 4a415794d62b90669c77e2e915cae7cce2071b26 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 6 Apr 2024 14:50:56 +0200 +Subject: platform/x86: x86-android-tablets: Unregister devices in reverse + order + +From: Hans de Goede + +[ 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: + + 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 +Link: https://lore.kernel.org/r/20240406125058.13624-1-hdegoede@redhat.com +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..4ee0593400a --- /dev/null +++ b/queue-6.9/power-supply-cros_usbpd-provide-id-table-for-avoidin.patch @@ -0,0 +1,66 @@ +From 4d09b275011ab3d9ed5408329560c80a3a04306e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Prashant Malani +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Tzung-Bi Shih +Link: https://lore.kernel.org/r/20240401030052.2887845-4-tzungbi@kernel.org +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + 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 + #include + #include + #include +@@ -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 index 00000000000..717ef126960 --- /dev/null +++ b/queue-6.9/powerpc-io-avoid-clang-null-pointer-arithmetic-warni.patch @@ -0,0 +1,85 @@ +From 68cfde474f56adb47ca0097db37bec109def570c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 May 2024 17:56:18 +1000 +Subject: powerpc/io: Avoid clang null pointer arithmetic warnings + +From: Michael Ellerman + +[ 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 +Closes: https://lore.kernel.org/all/CA+G9fYtEh8zmq8k8wE-8RZwW-Qr927RLTn+KqGnq1F=ptaaNsA@mail.gmail.com +Signed-off-by: Michael Ellerman +Link: https://msgid.link/20240503075619.394467-1-mpe@ellerman.id.au +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..5af4b670993 --- /dev/null +++ b/queue-6.9/powerpc-pseries-enforce-hcall-result-buffer-validity.patch @@ -0,0 +1,82 @@ +From b38cf46addff8bae06a403719aa11a99a3bfd8ca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 8 Apr 2024 09:08:31 -0500 +Subject: powerpc/pseries: Enforce hcall result buffer validity and size + +From: Nathan Lynch + +[ 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 +Signed-off-by: Michael Ellerman +Link: https://msgid.link/20240408-pseries-hvcall-retbuf-v1-1-ebc73d7253cf@linux.ibm.com +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..83531bf1f5c --- /dev/null +++ b/queue-6.9/rcutorture-fix-invalid-context-warning-when-enable-s.patch @@ -0,0 +1,120 @@ +From 4623bbc44daefc097da652a971f2f453fa4e61ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Mar 2024 15:52:19 +0800 +Subject: rcutorture: Fix invalid context warning when enable srcu barrier + testing + +From: Zqiang + +[ 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): [] do_idle+0x362/0x500 +[ 163.911018][ C1] hardirqs last disabled at (30964): [] sysvec_call_function_single+0xf/0xd0 +[ 163.911025][ C1] softirqs last enabled at (0): [] copy_process+0x16ff/0x6580 +[ 163.911033][ C1] softirqs last disabled at (0): [<0000000000000000>] 0x0 +[ 163.911038][ C1] Preemption disabled at: +[ 163.911039][ C1] [] 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] +[ 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] +[ 163.911304][ C1] +[ 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] + +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 +Signed-off-by: Paul E. McKenney +Signed-off-by: Uladzislau Rezki (Sony) +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..3a32a3d4165 --- /dev/null +++ b/queue-6.9/rcutorture-fix-rcu_torture_one_read-pipe_count-overf.patch @@ -0,0 +1,39 @@ +From c6c7aa682fba9570b5709d3325d7d7059614ce5c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Mar 2024 19:21:47 -0800 +Subject: rcutorture: Fix rcu_torture_one_read() pipe_count overflow comment + +From: Paul E. McKenney + +[ 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 +Closes: https://lore.kernel.org/lkml/CAHk-=wi7rJ-eGq+xaxVfzFEgbL9tdf6Kc8Z89rCpfcQOKm74Tw@mail.gmail.com/ +Signed-off-by: Paul E. McKenney +Signed-off-by: Uladzislau Rezki (Sony) +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..69fb19112e4 --- /dev/null +++ b/queue-6.9/rcutorture-make-stall-tasks-directly-exit-when-rcuto.patch @@ -0,0 +1,103 @@ +From bfdac0c6a8cb06b40047fcf6c3f5fa4360b93efa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Mar 2024 16:28:50 +0800 +Subject: rcutorture: Make stall-tasks directly exit when rcutorture tests end + +From: Zqiang + +[ 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] +[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 +Signed-off-by: Paul E. McKenney +Signed-off-by: Uladzislau Rezki (Sony) +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..c5066645fcb --- /dev/null +++ b/queue-6.9/scsi-qedi-fix-crash-while-reading-debugfs-attribute.patch @@ -0,0 +1,95 @@ +From d5f84b1883c070d96be55cfd7d0ae8e294faa7e4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 15 Apr 2024 12:51:55 +0530 +Subject: scsi: qedi: Fix crash while reading debugfs attribute + +From: Manish Rangankar + +[ 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: + + ? __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 +Reviewed-by: John Meneghini +Signed-off-by: Manish Rangankar +Link: https://lore.kernel.org/r/20240415072155.30840-1-mrangankar@marvell.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..8db3d505458 --- /dev/null +++ b/queue-6.9/selftests-bpf-fix-flaky-test-btf_map_in_map-lookup_u.patch @@ -0,0 +1,87 @@ +From 8f9d7a670c37799c02afae3b08bcfbaf304a7a31 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Mar 2024 23:13:53 -0700 +Subject: selftests/bpf: Fix flaky test btf_map_in_map/lookup_update + +From: Yonghong Song + +[ 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 +Signed-off-by: Daniel Borkmann +Link: https://lore.kernel.org/bpf/20240322061353.632136-1-yonghong.song@linux.dev +Signed-off-by: Sasha Levin +--- + .../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 index 00000000000..7a0df25ac74 --- /dev/null +++ b/queue-6.9/selftests-bpf-prevent-client-connect-before-server-b.patch @@ -0,0 +1,82 @@ +From fcdead2be0213e0f6cc0a36d5fad0e84a4c372aa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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) + +[ 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) +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20240314105911.213411-1-alessandro.carminati@gmail.com +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..4114cf2dca1 --- /dev/null +++ b/queue-6.9/selftests-net-fix-timestamp-not-arriving-in-cmsg_tim.patch @@ -0,0 +1,87 @@ +From 5b150f5c3c0720deb7ead7ce2d524ddc47985ac1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 May 2024 17:57:04 -0700 +Subject: selftests: net: fix timestamp not arriving in cmsg_time.sh + +From: Jakub Kicinski + +[ 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 +Link: https://lore.kernel.org/r/20240510005705.43069-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..478f7b1abc1 --- /dev/null +++ b/queue-6.9/serial-exar-adding-missing-cti-and-exar-pci-ids.patch @@ -0,0 +1,77 @@ +From 83bc5789898b3af50cf860c526ca669585477d23 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Apr 2024 08:55:28 -0400 +Subject: serial: exar: adding missing CTI and Exar PCI ids + +From: Parker Newman + +[ Upstream commit b86ae40ffcf5a16b9569b1016da4a08c4f352ca2 ] + +- Added Connect Tech and Exar IDs not already in pci_ids.h + +Signed-off-by: Parker Newman +Link: https://lore.kernel.org/r/7c3d8e795a864dd9b0a00353b722060dc27c4e09.1713270624.git.pnewman@connecttech.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..0b20c99bf1a --- /dev/null +++ b/queue-6.9/serial-imx-introduce-timeout-when-waiting-on-transmi.patch @@ -0,0 +1,59 @@ +From 947102742d5ab0c72a647568ecb2487cc46067a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Apr 2024 14:19:23 +0200 +Subject: serial: imx: Introduce timeout when waiting on transmitter empty + +From: Esben Haabendal + +[ 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 +Acked-by: Marc Kleine-Budde +Link: https://lore.kernel.org/r/919647898c337a46604edcabaf13d42d80c0915d.1712837613.git.esben@geanix.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + #include + #include ++#include + #include + + #include +@@ -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 index 00000000000..630f26ad86a --- /dev/null +++ b/queue-6.9/series @@ -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 index 00000000000..cfa6a476851 --- /dev/null +++ b/queue-6.9/ssb-fix-potential-null-pointer-dereference-in-ssb_de.patch @@ -0,0 +1,49 @@ +From c2160c392def5c5cdb01841dc330f992598bcbaf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Mar 2024 15:30:28 +0300 +Subject: ssb: Fix potential NULL pointer dereference in ssb_device_uevent() + +From: Rand Deeb + +[ 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 +Signed-off-by: Kalle Valo +Link: https://msgid.link/20240306123028.164155-1-rand.sec96@gmail.com +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..2239ed178db --- /dev/null +++ b/queue-6.9/tty-add-the-option-to-have-a-tty-reject-a-new-ldisc.patch @@ -0,0 +1,111 @@ +From 1905ff16da0c10f232742a229e378e53d7083cbe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Cc: Jiri Slaby +Cc: Andrew Morton +Cc: Daniel Starke +Reported-by: syzbot +Closes: https://syzkaller.appspot.com/bug?extid=dbac96d8e73b61aa559c +Signed-off-by: Linus Torvalds +Link: https://lore.kernel.org/r/20240423163339.59780-1-torvalds@linux-foundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..babd415263b --- /dev/null +++ b/queue-6.9/ubsan-avoid-i386-ubsan-handler-crashes-with-clang.patch @@ -0,0 +1,80 @@ +From 17194c5969bda0b0b334ae20df8c7710fd3ad36d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Apr 2024 15:40:29 -0700 +Subject: ubsan: Avoid i386 UBSAN handler crashes with Clang + +From: Kees Cook + +[ 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 +Closes: https://github.com/KSPP/linux/issues/350 +Link: https://lore.kernel.org/r/20240424224026.it.216-kees@kernel.org +Acked-by: Nathan Chancellor +Acked-by: Justin Stitt +Signed-off-by: Kees Cook +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..389f9783271 --- /dev/null +++ b/queue-6.9/udf-udftime-prevent-overflow-in-udf_disk_stamp_to_ti.patch @@ -0,0 +1,54 @@ +From 0a98a71e1e66e92ac3c930a5d36a749867a22f20 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Mar 2024 16:27:55 +0300 +Subject: udf: udftime: prevent overflow in udf_disk_stamp_to_time() + +From: Roman Smirnov + +[ 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 +Signed-off-by: Roman Smirnov +Reviewed-by: Sergey Shtylyov +Signed-off-by: Jan Kara +Message-Id: <20240327132755.13945-1-r.smirnov@omp.ru> +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..f15d7c7b29a --- /dev/null +++ b/queue-6.9/usb-dwc3-pci-don-t-set-linux-phy_charger_detect-prop.patch @@ -0,0 +1,68 @@ +From e00d6d5cd833d18574930d535667f34244f9d258 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Acked-by: Thinh Nguyen +Link: https://lore.kernel.org/r/20240406140127.17885-1-hdegoede@redhat.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + */ + ++#include + #include + #include + #include +@@ -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 index 00000000000..acefd0dd614 --- /dev/null +++ b/queue-6.9/usb-gadget-function-remove-usage-of-the-deprecated-i.patch @@ -0,0 +1,98 @@ +From 213cbeabc2056ee8ef4798caba01b4b9fec71340 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/7cd361e2b377a5373968fa7deee4169229992a1e.1713107386.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..f8f26c2dab2 --- /dev/null +++ b/queue-6.9/usb-gadget-uvc-configfs-ensure-guid-to-be-valid-befo.patch @@ -0,0 +1,64 @@ +From 7b1d0ee53618005259d505ba1d8f666ffe1234f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Feb 2024 23:14:47 +0100 +Subject: usb: gadget: uvc: configfs: ensure guid to be valid before set + +From: Michael Grzeschik + +[ 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 +Link: https://lore.kernel.org/r/20240221-uvc-gadget-configfs-guid-v1-1-f0678ca62ebb@pengutronix.de +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 ++#include + #include + + /* ----------------------------------------------------------------------------- +@@ -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 index 00000000000..a67db083147 --- /dev/null +++ b/queue-6.9/usb-misc-uss720-check-for-incompatible-versions-of-t.patch @@ -0,0 +1,75 @@ +From b39e8dce16e950551db35de2296f90d3ebeebab5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Mar 2024 09:07:11 -0600 +Subject: usb: misc: uss720: check for incompatible versions of the Belkin + F5U002 + +From: Alex Henrie + +[ 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 +Link: https://lore.kernel.org/r/20240326150723.99939-5-alexhenrie24@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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, ®, 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, ®, 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 index 00000000000..62aaab43724 --- /dev/null +++ b/queue-6.9/usb-typec-qcom-pmic-typec-split-hpd-bridge-alloc-and.patch @@ -0,0 +1,80 @@ +From a1605d35e4a95d2ce25c99139f92c57bf87d6f1d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Apr 2024 05:16:57 +0300 +Subject: usb: typec: qcom-pmic-typec: split HPD bridge alloc and registration + +From: Dmitry Baryshkov + +[ 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 +Acked-by: Bryan O'Donoghue +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Heikki Krogerus +Reviewed-by: Johan Hovold +Link: https://lore.kernel.org/r/20240424-qc-pmic-typec-hpd-split-v4-1-f7e10d147443@linaro.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..ce9b3344dd0 --- /dev/null +++ b/queue-6.9/usb-typec-ucsi_glink-drop-special-handling-for-cci_b.patch @@ -0,0 +1,56 @@ +From 85054777b9ceb3cd5cd567d4e7b7c1b1a4dab59a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 8 Apr 2024 04:04:17 +0300 +Subject: usb: typec: ucsi_glink: drop special handling for CCI_BUSY + +From: Dmitry Baryshkov + +[ 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 +Reviewed-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20240408-qcom-ucsi-fixes-bis-v1-3-716c145ca4b1@linaro.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..bad98975ff6 --- /dev/null +++ b/queue-6.9/usb-typec-ucsi_glink-rework-quirks-implementation.patch @@ -0,0 +1,58 @@ +From e3e2c683b74937d9bd3a6bcf027f37d2533d9064 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Mar 2024 08:15:40 +0200 +Subject: usb: typec: ucsi_glink: rework quirks implementation + +From: Dmitry Baryshkov + +[ 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 +Reviewed-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20240329-qcom-ucsi-fixes-v2-8-0f5d37ed04db@linaro.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..d5d79383d99 --- /dev/null +++ b/queue-6.9/vfio-pci-collect-hot-reset-devices-to-local-buffer.patch @@ -0,0 +1,337 @@ +From 64a22d39cbba420eb7270af67262123d33e6357c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 May 2024 08:31:36 -0600 +Subject: vfio/pci: Collect hot-reset devices to local buffer + +From: Alex Williamson + +[ 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: + + 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 + + +Reviewed-by: Jason Gunthorpe +Link: https://lore.kernel.org/r/20240503143138.3562116-1-alex.williamson@redhat.com +Signed-off-by: Alex Williamson +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..ee3bd1edf29 --- /dev/null +++ b/queue-6.9/wifi-ath12k-fix-kernel-crash-during-resume.patch @@ -0,0 +1,225 @@ +From 4029b63c1099eedddd45c26bca7062b880f27605 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Apr 2024 15:11:47 +0300 +Subject: wifi: ath12k: fix kernel crash during resume + +From: Baochen Qiang + +[ 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 +Signed-off-by: Kalle Valo +Link: https://msgid.link/20240419034034.2842-1-quic_bqiang@quicinc.com +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..512b968d236 --- /dev/null +++ b/queue-6.9/wifi-ath12k-fix-the-problem-that-down-grade-phy-mode.patch @@ -0,0 +1,91 @@ +From 702f6f3666120bb8385f924b3a0bd4dde97ac88d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Acked-by: Jeff Johnson +Acked-by: Jeff Johnson +Signed-off-by: Kalle Valo +Link: https://msgid.link/20240425083837.5340-1-quic_lingbok@quicinc.com +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..15e8ff0b2d4 --- /dev/null +++ b/queue-6.9/wifi-ath9k-work-around-memset-overflow-warning.patch @@ -0,0 +1,72 @@ +From 4d48e5e3c9b14d3513d24db4968708a64ed92e85 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Acked-by: Toke Høiland-Jørgensen +Reviewed-by: Kees Cook +Signed-off-by: Kalle Valo +Link: https://msgid.link/20240328135509.3755090-3-arnd@kernel.org +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..1b55ce72f2e --- /dev/null +++ b/queue-6.9/wifi-mt76-mt7921s-fix-potential-hung-tasks-during-ch.patch @@ -0,0 +1,106 @@ +From 0552457a14fd4678df3c03ccc4f4ff5d618e5bd3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Mar 2024 17:46:32 +0800 +Subject: wifi: mt76: mt7921s: fix potential hung tasks during chip recovery + +From: Leon Yen + +[ 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 +Signed-off-by: Ming Yen Hsieh +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..b72d725a9c3 --- /dev/null +++ b/queue-6.9/wifi-rtw89-8852c-add-quirk-to-set-pci-ber-for-certai.patch @@ -0,0 +1,257 @@ +From 41096a15400f8b8aa5ca2aa130d941e4371b5808 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://msgid.link/20240329015251.22762-4-pkshih@realtek.com +Signed-off-by: Sasha Levin +--- + 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 + #include ++#include + #include + #include + #include +@@ -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 index 00000000000..acd2199cea1 --- /dev/null +++ b/queue-6.9/xhci-remove-xhci_trust_tx_length-quirk.patch @@ -0,0 +1,189 @@ +From c901e085aac4c4b3b7dca2d7e450ff77701f0299 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Apr 2024 17:02:36 +0300 +Subject: xhci: remove XHCI_TRUST_TX_LENGTH quirk + +From: Mathias Nyman + +[ 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 +Signed-off-by: Niklas Neronin +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20240429140245.3955523-10-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 +